无法将标志传递给 Makefile 来编译我的代码
Cannot pass flags to Makefile to compile my code
我有一个项目,基本上是从以下形式的命令行编译的:
g++ -o stack_raster stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
我做了一个Makefile,内容是这样的:
CXX =g++
LDDFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
但是我得到了一个 collect2: error: ld returned 1 exit status。
我尝试的 Makefile 的第二个变体是:
CXX = g++
CPPFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rem -f stack_raster
但我仍然收到以下消息(即使编译标志显示为我的程序成功编译所应有的样子)。
collect2: error: ld returned 1 exit status
<builtin>: recipe for target `stack_raster` failed
make: *** [stack_raster] Error 1
有没有人可以帮助我参考或提示我的问题,我该如何解决?
查看答案:
您必须在 Makefile 中指定要创建的文件,在本例中 stack_raster.exe 和 objective 文件,在本例中 stack_raster.cpp 并指定您通常为编译传递的命令行参数。所以 Makefile 应该是这样的:
CXX=g++
stack_raster.exe: stack_raster.cpp
g++ -o stack_raster.exe stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
all: clean stack_raster.exe
clean:
rm -f stack_raster.exe
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
首先,您应该查看 make
执行的实际 link 命令。它应该在来自 collect2
的错误消息之前回显到 make
的输出。了解命令有什么问题是确定如何修复 makefile 的第一步。
在第一种情况下,命令可能类似于
g++ stack_raster.cpp -o stack_raster
第二个大概是这样的
g++ -lgdal -lboost_system -lboost_filesystem stack_raster.cpp -o stack_raster
如果将 LDDFLAGS
的拼写更正为 LDFLAGS
。
,后者可能也与第一个 makefile 中得到的非常相似。
您会注意到库标志在该命令中的位置与它们在手动命令中的位置不同,我假设您知道 linker 命令中对象和库标志的顺序行对于 Unix 风格的 link 程序很重要,例如 GNU(g++
驱动程序将使用的)。
您当然可以通过编写明确的规则来解决此问题,正如您在自己的回答中所描述的那样,但是您的 make
的内置规则也可以完成这项任务。如果您使用的是 GNU make
,那么它们肯定是。为此,了解内置规则的实际内容很有用,了解这些规则所依赖的变量的含义也很重要。
具体来说,
LDFLAGS
提供调用 linker 时要传递的选项,并且 通常,它们出现在命令行 before 对象正在 linked。因此,此变量通常不适合指定库(但它适用于其他 link 特定选项,例如 -L
将目录添加到库搜索路径)。
CPPFLAGS
提供用于调整 C 预处理器行为的选项(包括编译 C++ 时)。这些通常根本不会出现在 link(仅)由 make
执行的命令中,但它们会(较早地)出现在从 C 或 C++ 源代码编译目标文件的命令中,以及构建规则中直接来自 C 或 C++ 源的可执行文件。
这些都不是你想要的,但如果你使用 GNU make,那么 its documentation for the former 明确告诉你应该做什么(使用 make
实现):
Extra flags to give to compilers when they are supposed to invoke the
linker, ‘ld
’, such as -L
. Libraries (-lfoo
) should be added to the
LDLIBS
variable instead.
(强调)
在 GNU make
中,也许还有一些其他的,LDLIBS
变量正好满足您需要的目的:将库指定为 link。这些将出现在内置规则的 link 命令行的末尾,正如您可以从 GNU make
的 catalog of implicit rules 或从 [=84= 获得的列表中确认的那样] make -p
在不包含 makefile 的目录中。
因此,使用 GNU make
,您可以从内置规则中获得您似乎想要的构建,方法是:
CXX = g++
LDLIBS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
最后,我注意到默认情况下在构建之前进行清理,正如您的示例和我的示例所做的那样,在很大程度上违背了使用 make
而不是简单脚本的目的。 make
的部分要点是做最少的必要工作,如果您的目标可执行文件存在并且相对于其源代码没有过时,那么没有理由强制重建它。
我有一个项目,基本上是从以下形式的命令行编译的:
g++ -o stack_raster stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
我做了一个Makefile,内容是这样的:
CXX =g++
LDDFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
但是我得到了一个 collect2: error: ld returned 1 exit status。 我尝试的 Makefile 的第二个变体是:
CXX = g++
CPPFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rem -f stack_raster
但我仍然收到以下消息(即使编译标志显示为我的程序成功编译所应有的样子)。
collect2: error: ld returned 1 exit status
<builtin>: recipe for target `stack_raster` failed
make: *** [stack_raster] Error 1
有没有人可以帮助我参考或提示我的问题,我该如何解决?
查看答案:
您必须在 Makefile 中指定要创建的文件,在本例中 stack_raster.exe 和 objective 文件,在本例中 stack_raster.cpp 并指定您通常为编译传递的命令行参数。所以 Makefile 应该是这样的:
CXX=g++
stack_raster.exe: stack_raster.cpp
g++ -o stack_raster.exe stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
all: clean stack_raster.exe
clean:
rm -f stack_raster.exe
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
首先,您应该查看 make
执行的实际 link 命令。它应该在来自 collect2
的错误消息之前回显到 make
的输出。了解命令有什么问题是确定如何修复 makefile 的第一步。
在第一种情况下,命令可能类似于
g++ stack_raster.cpp -o stack_raster
第二个大概是这样的
g++ -lgdal -lboost_system -lboost_filesystem stack_raster.cpp -o stack_raster
如果将 LDDFLAGS
的拼写更正为 LDFLAGS
。
您会注意到库标志在该命令中的位置与它们在手动命令中的位置不同,我假设您知道 linker 命令中对象和库标志的顺序行对于 Unix 风格的 link 程序很重要,例如 GNU(g++
驱动程序将使用的)。
您当然可以通过编写明确的规则来解决此问题,正如您在自己的回答中所描述的那样,但是您的 make
的内置规则也可以完成这项任务。如果您使用的是 GNU make
,那么它们肯定是。为此,了解内置规则的实际内容很有用,了解这些规则所依赖的变量的含义也很重要。
具体来说,
LDFLAGS
提供调用 linker 时要传递的选项,并且 通常,它们出现在命令行 before 对象正在 linked。因此,此变量通常不适合指定库(但它适用于其他 link 特定选项,例如-L
将目录添加到库搜索路径)。CPPFLAGS
提供用于调整 C 预处理器行为的选项(包括编译 C++ 时)。这些通常根本不会出现在 link(仅)由make
执行的命令中,但它们会(较早地)出现在从 C 或 C++ 源代码编译目标文件的命令中,以及构建规则中直接来自 C 或 C++ 源的可执行文件。
这些都不是你想要的,但如果你使用 GNU make,那么 its documentation for the former 明确告诉你应该做什么(使用 make
实现):
Extra flags to give to compilers when they are supposed to invoke the linker, ‘
ld
’, such as-L
. Libraries (-lfoo
) should be added to theLDLIBS
variable instead.
(强调)
在 GNU make
中,也许还有一些其他的,LDLIBS
变量正好满足您需要的目的:将库指定为 link。这些将出现在内置规则的 link 命令行的末尾,正如您可以从 GNU make
的 catalog of implicit rules 或从 [=84= 获得的列表中确认的那样] make -p
在不包含 makefile 的目录中。
因此,使用 GNU make
,您可以从内置规则中获得您似乎想要的构建,方法是:
CXX = g++
LDLIBS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
最后,我注意到默认情况下在构建之前进行清理,正如您的示例和我的示例所做的那样,在很大程度上违背了使用 make
而不是简单脚本的目的。 make
的部分要点是做最少的必要工作,如果您的目标可执行文件存在并且相对于其源代码没有过时,那么没有理由强制重建它。