由于某些原因,make正在重新编译我之外的源文件 每次都是项目树。我通常不会有这样的文件,但我在测试这个Makefile时注意到了它,我想了解原因。它相对于项目树中的源文件行为正常。这是我的规则。首先,我有一个功能
src_to_obj = $(basename $(addprefix $(build_dir)/,$(1))).o
然后我通过在源列表上调用foreach并将上述函数应用于每个函数来填充program_objects列表。
$(bin_dir)/$(program_name): $(program_objects)
$(linker) $(link_flags) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) \
$^ $(OUTPUT_OPTION)
define build_template =
$$(call src_to_obj,$(1)) : $(1) $$(call dependency_file,$(1))
// make dependency and build directories
$$(compile) $$(OUTPUT_OPTION) $$<
// rename dependency
endef
$(foreach source,$(program_sources),\
$(eval $(call build_template,$(source))))
正如我所说,这适用于项目目录中的源文件。例如,Makefile位于〜/ Projects / foo中,大部分源代码位于〜/ Projects / foo / src中。但是,如果我从主目录中提取文件A.cc,那么每次运行make时都会重新编译该文件。
编辑: 按照Mad-Scientists的建议,我运行make -d并检查输出。这使问题变得清晰。基本上,如果我提供这个源文件〜/ bad.cc,那么规则如下:
build/~/bad.o : ~/bad.cc .deps/~/bad.d
...
但是,我的规则脚本是创建文件.deps / home / jim / bad.d。因此,每次我运行时,依赖文件都是&#34;不是那里&#34;并且必须重新制作目标文件。我使用完全相同的表达式来引用脚本中的文件名。但是我猜测shell正在将〜扩展到/ home / jim。所以我不得不在配方中逃避〜。感谢Mad Scientist指出make的-d选项。
我现在没有时间做一个简短的自包含正确的例子,但是如果我无法解决这个问题,我会想出一个并在以后发布。
编辑编辑: 所以我用下面的黑客解决了这个问题:
program_sources = $(shell echo $(program_sources))
这会预先扩展所有名称,以便它们在shell中永远不会有所不同。