情况
我有一个 Makefile,它依赖于具有自己的 Makefile 的子项目中的一些内容。在子项目中,目标具有我希望我的主项目不必知道的依赖关系。因此,我尝试使用子项目的 Makefile 在必要时从中构建我需要的任何内容。这是我在构建之前在示例项目中的内容:
$ find . -type f | xargs head
==> ./subproject/Makefile <==
binary: source.txt
echo subproject source: > $@
date >> $@
cat $< >> $@
clean:
rm binary
==> ./subproject/source.txt <==
this is the subproject source code
==> ./Makefile <==
binary: source.txt subproject/binary
echo main source: > $@
date >> $@
cat $^ >> $@
subproject/%:
$(MAKE) -C $(@D) $(@F)
clean:
rm binary
$(MAKE) -C subproject clean
==> ./source.txt <==
this is the main source code
这就是我构建后得到的:
$ make
make -C subproject binary
make[1]: Entering directory '~/make-example/subproject'
echo subproject source: > binary
date >> binary
cat source.txt >> binary
make[1]: Leaving directory '~/make-example/subproject'
echo main source: > binary
date >> binary
cat source.txt subproject/binary >> binary
$ find . -type f | xargs head
==> ./subproject/Makefile <==
binary: source.txt
echo subproject source: > $@
date >> $@
cat $< >> $@
clean:
rm binary
==> ./subproject/binary <==
subproject source:
Di 10. Okt 14:01:03 CEST 2023
this is the subproject source code
==> ./subproject/source.txt <==
this is the subproject source code
==> ./Makefile <==
binary: source.txt subproject/binary
echo main source: > $@
date >> $@
cat $^ >> $@
subproject/%:
$(MAKE) -C $(@D) $(@F)
clean:
rm binary
$(MAKE) -C subproject clean
==> ./binary <==
main source:
Di 10. Okt 14:01:03 CEST 2023
this is the main source code
subproject source:
Di 10. Okt 14:01:03 CEST 2023
this is the subproject source code
==> ./source.txt <==
this is the main source code
alex@elephant:~/make-example$
问题
当我更改subproject/source.txt
并make
在父项目中运行时,它仍然不会重新编译。
我几乎可以像这样解决这个问题:
subproject/%: always
$(MAKE) -C $(@D) $(@F)
always:
当make在子项目中运行时,subproject/binary
不会被重新编译。但是,binary
在父项目中仍然会重新编译,因为它的先决条件之一已运行,即使先决文件上的日期是旧的。
问题
所以我认为答案可能是我不应该这样做。我真的希望父项目和子项目彼此了解得尽可能少。
有没有办法让父项目检查日期subproject/binary
并使用它来确定是否重建binary
,即使subproject/binary
公式已运行?
我希望能够键入make
并构建它,然后在主项目中再次更改subproject/source.txt
和键入,然后重新编译,然后重新编译结果,然后紧接着,不更改任何内容,然后再次键入,不重新编译任何内容make
subproject/binary
binary
make
你写:
make 不是这样工作的。仅仅因为配方被调用并不意味着 make 总是假设目标已被修改;make 将检查先决条件的修改时间并进行比较,即使先决条件的配方被调用也是如此。
因此,如果您看到
binary
总是重建,那么这里发生了其他事情:也许子 make 的编写方式总是修改二进制文件。您可能想使用make --trace
或make -d
了解 make 决定重建的原因binary
。例子:
现在:
正如预期的那样,但现在如果我们实际上不改变先决条件:
我们可以看到先决条件更新规则已运行,但由于它实际上没有改变
prereq
,所以 make 没有重建binary
。