我有这个Makefile (以及GNU Make):
vpath %.o .objs
OBJDIR=.objs
all: symbol_tests.so
symbol_tests.so: symbol_tests.o symbol.o # simulate linking
@echo Linking target: $@, prerequisites: $^
%.o: %.c | $(OBJDIR)/
gcc -o $(OBJDIR)/$@ -c $<
$(OBJDIR)/:
-mkdir $@但是,构建(没有任何子this或存在的对象)给了我以下内容:
mkdir .objs/
gcc -o .objs/symbol_tests.o -c symbol_tests.c
gcc -o .objs/symbol.o -c symbol.c
Linking target: symbol_tests.so, prerequisites: symbol_tests.o symbol.o显然,由于symbol.o和symbol_test.o都不存在,因此需要构建它们。它们被正确地放置在子./objs中。
但是,当“链接”时,vpath不会在.objs子the中获取新创建的.o-files。
这不是很奇怪吗?再次运行make会给出:
Linking target: symbol_tests.so, prerequisites: .objs/symbol_tests.o .objs/symbol.o在我看来,为了触发子for中对.o的搜索,在调用make时,它们必须存在。这种情况违背了vpath的目的,不是吗?
或者我的Makefile或对vpath的理解有什么问题吗?
注意:在vpath指令中包含$(OBJDIR)不起作用。为什么?
发布于 2020-03-13 22:35:37
这看起来不适用于GNU Make,也不适合我尝试过的任何其他Make。
我认为vpath和$(VPATH)以及BSD make.PATH:实际上只对原始源有效(即调用Make之前存在的文件,而不是任何中间目标)。
特别是请参阅GNU Autoconf手册中的以下警告:
在显式规则中使用$<是不可移植的。先决条件文件必须在规则中显式命名。如果您想通过VPATH搜索找到先决条件,则必须手动编写整个代码。
请参阅Gnu Autoconf手册部分12.14 VPATH和Make中的更多注意事项。
当然,您可以在对make的递归调用中执行最后的链接步骤来欺骗它,但这似乎是浪费的,特别是当您对许多目标执行链接步骤时。
BSD通过自动将当前工作目录更改为对象目录来管理对象目录的创建,然后通过${.CURDIR}变量显式地查找源--第一次调用make的位置。
遗憾的是,GNU只在处理$(CURDIR)选项之后才设置它的-C。似乎首选的GNU做事情的方式(特别是与其他GNU Autotools一起)是使用一个单独的构建目录来处理Make进程。例如,创建一个单独的空构建目录,首先在其中运行configure脚本,并提供到构建目录的相对路径:
mkdir build
cd build
../configure这将在build目录中创建所有必需的Makefiles,然后您也可以在build目录中运行Make:
gmake当然,这是确保在源目录中创建目标(中间目标或其他目标)的最安全的方法。
您还可以避免使用vpath,并直接将对象目录添加到每个对象目标名称中,如下面的答案:https://stackoverflow.com/a/37469528/816536
https://stackoverflow.com/questions/60676940
复制相似问题