vpath 没有拾取新建的对象
vpath not picking up newly built objects
我有这个 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.o
和 symbol_test.o
都不存在,因此需要构建它们。
并且它们正确地放置在子目录 ./objs
.
但是当 "linking" 时 vpath
不会在 .objs
子目录中获取新创建的 .o
文件。
这不奇怪吗? 运行 make
再次给出:
Linking target: symbol_tests.so, prerequisites: .objs/symbol_tests.o .objs/symbol.o
对我来说,为了触发在子目录中搜索 .o
,它们必须在调用 make
时存在。这种做法违背了 vpath
的目的,不是吗?
还是我的Makefile
或者理解的vpath
有问题?
注意:在 vpath 指令中包含 $(OBJDIR) 不起作用。为什么?
这看起来不适用于 GNU Make 或我尝试过的任何其他 Make。
我认为 vpath
和 $(VPATH)
[以及 BSD Make .PATH:
] 仅对原始源有效(即在调用 Make 之前存在的文件,对任何中间文件无效目标。
请特别注意 GNU Autoconf 手册中的以下警告:
Using $< in explicit rules is not portable. The prerequisite file must be named explicitly in the rule. If you want to find the prerequisite via a VPATH search, you have to code the whole thing manually.
在 Gnu Autoconf 手册部分查看更多注意事项 12.14 VPATH and Make。
您当然可以通过在对 make
的递归调用中执行最后的 link 步骤来愚弄它,但这似乎很浪费,尤其是当您对很多目标执行此操作时。
BSD Make 管理对象目录的创建,方法是自动将当前工作目录更改为对象目录,然后通过 ${.CURDIR}
变量显式查找源——首次调用 make
的位置。
不幸的是,GNU Make 仅在 处理 -C
选项后设置其 $(CURDIR)
。似乎首选的 GNU Make 处理方式(尤其是与其他 GNU Autotools 结合使用)是为 Make 进程使用单独的构建目录。 IE。创建一个单独的空构建目录,然后从 运行 在其中设置 configure
脚本开始,并使用构建目录的相对路径:
mkdir build
cd build
../configure
这会在构建目录中创建所有必需的 Makefiles
,然后您也可以 运行 在构建目录中创建 Make:
gmake
这当然是确保不会在源目录中创建目标(中间或其他)的最安全方法。
您也可以避免 vpath
并直接将对象目录添加到每个对象目标名称,如以下答案所示:
我有这个 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.o
和 symbol_test.o
都不存在,因此需要构建它们。
并且它们正确地放置在子目录 ./objs
.
但是当 "linking" 时 vpath
不会在 .objs
子目录中获取新创建的 .o
文件。
这不奇怪吗? 运行 make
再次给出:
Linking target: symbol_tests.so, prerequisites: .objs/symbol_tests.o .objs/symbol.o
对我来说,为了触发在子目录中搜索 .o
,它们必须在调用 make
时存在。这种做法违背了 vpath
的目的,不是吗?
还是我的Makefile
或者理解的vpath
有问题?
注意:在 vpath 指令中包含 $(OBJDIR) 不起作用。为什么?
这看起来不适用于 GNU Make 或我尝试过的任何其他 Make。
我认为 vpath
和 $(VPATH)
[以及 BSD Make .PATH:
] 仅对原始源有效(即在调用 Make 之前存在的文件,对任何中间文件无效目标。
请特别注意 GNU Autoconf 手册中的以下警告:
Using $< in explicit rules is not portable. The prerequisite file must be named explicitly in the rule. If you want to find the prerequisite via a VPATH search, you have to code the whole thing manually.
在 Gnu Autoconf 手册部分查看更多注意事项 12.14 VPATH and Make。
您当然可以通过在对 make
的递归调用中执行最后的 link 步骤来愚弄它,但这似乎很浪费,尤其是当您对很多目标执行此操作时。
BSD Make 管理对象目录的创建,方法是自动将当前工作目录更改为对象目录,然后通过 ${.CURDIR}
变量显式查找源——首次调用 make
的位置。
不幸的是,GNU Make 仅在 处理 -C
选项后设置其 $(CURDIR)
。似乎首选的 GNU Make 处理方式(尤其是与其他 GNU Autotools 结合使用)是为 Make 进程使用单独的构建目录。 IE。创建一个单独的空构建目录,然后从 运行 在其中设置 configure
脚本开始,并使用构建目录的相对路径:
mkdir build
cd build
../configure
这会在构建目录中创建所有必需的 Makefiles
,然后您也可以 运行 在构建目录中创建 Make:
gmake
这当然是确保不会在源目录中创建目标(中间或其他)的最安全方法。
您也可以避免 vpath
并直接将对象目录添加到每个对象目标名称,如以下答案所示: