Makefile vpath不拾取新生成的对象

Makefile vpath不拾取新生成的对象,makefile,gnu-make,vpath,automatic-variable,Makefile,Gnu Make,Vpath,Automatic Variable,我有这个Makefile(和GNU Make): 很明显,由于symbol.o和symbol\u test.o都不存在,因此需要构建它们。 并且它们正确地放置在子目录/objs 但是,“链接”时,vpath不会拾取.objs子目录中新创建的.o-文件 这不是很奇怪吗?再次运行make,可以得到: Linking target: symbol_tests.so, prerequisites: .objs/symbol_tests.o .objs/symbol.o 在我看来,为了触发对subdir

我有这个Makefile(和GNU Make):

很明显,由于
symbol.o
symbol\u test.o
都不存在,因此需要构建它们。 并且它们正确地放置在子目录
/objs

但是,“链接”时,
vpath
不会拾取
.objs
子目录中新创建的
.o
-文件

这不是很奇怪吗?再次运行
make
,可以得到:

Linking target: symbol_tests.so, prerequisites: .objs/symbol_tests.o .objs/symbol.o
在我看来,为了触发对subdir中
.o
的搜索,当调用
make
时,它们必须存在。这种做法违背了
vpath
的目的,不是吗

或者我的
Makefile
或对
vpath
的理解有问题吗


注意:在vpath指令中使用$(OBJDIR)不起作用。为什么?

这看起来对GNU Make和我尝试过的任何其他Make都不起作用

我认为
vpath
$(vpath)
[对于BSD Make
.PATH:
]只对原始源(即调用Make之前存在的文件,而不是任何中间目标)有效

具体请参见GNU Autoconf手册中的以下警告:

在显式规则中使用$<是不可移植的。必须在规则中显式命名先决条件文件。如果要通过VPATH搜索找到先决条件,必须手动编写整个代码

请参阅Gnu Autoconf手册一节中的更多注意事项

当然,您可以通过递归调用
make
来愚弄它,但这似乎是浪费,特别是如果您为许多目标执行此操作

BSD Make管理对象目录的创建,方法是自动将当前工作目录更改为对象目录,然后通过
${.CURDIR}
变量(第一次调用
Make
的位置)显式查找源

不幸的是,GNU Make仅在处理
-C
选项后设置其
$(CURDIR)
。它似乎是首选的GNU Make方式(尤其是与其他GNU自动工具结合使用)是为生成过程使用单独的生成目录。即,创建一个单独的空生成目录,并通过运行其中的
configure
脚本开始,其中包含指向生成目录的相对路径:

mkdir build
cd build
../configure
这将在build目录中创建所有必要的
makefile
,然后您也可以在build目录中运行Make:

gmake
当然,这是确保在源目录中不会创建任何目标(中间或其他)的最安全的方法


您也可以避免<代码> vPATA/COD>并直接将对象目录添加到每个对象的目标名称中,如格雷戈所提到的:

,您不能使用VPATH来定位对象文件。您可以考虑阅读:我来自<代码> $(Objdir)。前面的每一个预选词都觉得有点混乱,但至少它是明确的。我会考虑移到<代码> Objdir,但是可能会忘记有一个单独的<代码> Objdir,我无论如何都不在这个项目中做多拱形编译。或者使用一些<代码> PATSUST<<代码>魔法。
mkdir build
cd build
../configure
gmake