vpath不拾取新生成的对象

问题描述 投票:0回答:1

我有这个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 $@

但是建筑物(没有任何子目录或对象存在)给我这个:

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.osymbol_test.o都不存在,因此不需要构建它们。并将它们正确放置在子目录./objs中。

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

这很奇怪吗?再次运行make会给出:

Linking target: symbol_tests.so, prerequisites: .objs/symbol_tests.o .objs/symbol.o

对我来说,为了触发对子目录中.o的搜索,当调用make时,它们必须存在。这种破坏了vpath的目的,不是吗?

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

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

makefile gnu-make vpath automatic-variable
1个回答
0
投票

看来这不适用于GNU Make或我尝试过的任何其他Make。

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

特别是从GNU Autoconf手册中看到以下警告:

在显式规则中使用$

请参见《 Gnu Autoconf手册》 12.14 VPATH and Make部分的更多警告。

当然,您可以通过对make进行递归调用来完成最后一个链接步骤,从而蒙蔽了它,但这似乎很浪费,特别是如果您对许多目标执行此操作。

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

不幸的是,GNU Make仅设置其$(CURDIR) 之后,它处理-C选项。似乎首选的GNU Make处理方式(尤其是与其他GNU Autotools结合使用)是为Make进程使用单独的构建目录。即创建一个单独的空构建目录,并从其中运行configure脚本开始,并带有构建目录的相对路径:

mkdir build
cd build
../configure

这会在构建目录中创建所有必需的Makefiles,然后您也可以在构建目录中运行Make:

gmake

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

您还可以避免使用vpath,而是直接将对象目录添加到每个对象目标名称中,如以下答案:https://stackoverflow.com/a/37469528/816536

© www.soinside.com 2019 - 2024. All rights reserved.