考虑这个简单的makefile:
all: output.txt
# The actual build command won't be this simple.
# It'll more be like "some-compiler file1.txt",
# which includes file2.txt automatically.
output.txt: file1.txt
cat file1.txt file2.txt > output.txt
file2.txt:
echo "heyo" > file2.txt
file1.txt: file2.txt
首次运行时,Make会认识到file2.txt
是file1.txt
的依赖关系,因此需要构建output.txt
来构建它。因此,它运行echo "heyo" > file2.txt
然后cat file1.txt file2.txt > output.txt
。
但是,在后续运行中,如果更改了file2.txt
,则Make不会重建!如果更改了file1.txt
,则会更改file2.txt
。它只是给出了可怕的make: Nothing to be done for 'all'.
消息。
我见过人们建议的一个hacky解决方案是执行以下操作:
all: output.txt
output.txt: file1.txt file2.txt
cat file1.txt file2.txt > output.txt
但是,在我的情况下这是不可能的,因为我的辅助依赖项(像file1.txt: file2.txt
这样的行)是使用include
动态生成的。
当我多个依赖关系时,如何确保检查修改一直在树上?
答案 0 :(得分:1)
您的makefile完全既不生成也不更新 file1.txt
(例如:file1.txt
在运行make
时必须存在。它包含 no recipe ,用于从file1.txt
生成file2.txt
。它只有空规则(即:没有配方的规则):
file1.txt: file2.txt
由于file1.txt
是output.txt
的先决条件,因此这个空白规则只意味着file2.txt
必须存在才能构建output.txt
,它甚至不会更新file1.txt
生成file2.txt
时。
由于file1.txt
是output.txt
的唯一先决条件而file1.txt
永远不会由make
更新,因此一旦生成output.txt
,它始终保持最新状态-date(提供的file1.txt
未在外部更新)。
file2.txt
被更改永远不会导致重建output.txt
,因为:
output.txt
。file1.txt
(这是output.txt
的唯一先决条件)。 根据您当前的output.txt
规则:
output.txt: file1.txt
cat file1.txt file2.txt > output.txt
如果您希望每次output.txt
更改时都构建file2.txt
,那么每次file1.txt
更改时都需要file2.txt
构建file1.txt
。这可以通过其配方实际更新file2.txt
并且具有file1.txt: file2.txt
touch $@
作为先决条件的规则来实现,例如:
clusterb
答案 1 :(得分:1)
我认为这里的问题是你的makefile略微太简单。
让a -> b
表示a depends on b
。从你的makefile中得到......
output.txt -> file1.txt -> file2.txt
当make
尝试更新output.txt
时,它会发现output.txt
取决于file1.txt
。然后,它注意到file1.txt
取决于file2.txt
。在那时,依赖链停止。如果make看到file2.txt
比file1.txt
更新,它将运行与file1.txt: file2.txt
拒绝关联的命令。但是,在这种情况下,没有任何命令 - 只是依赖本身。事情进展顺利,但这确实意味着即使file2.txt
更新file1.txt
也不会。因此,当make向上移动依赖链时......
output.txt: file1.txt
它看到output.txt
仍比file1.txt
更新,因此无需运行与该依赖关联的任何命令。
如果添加touch
命令...
file1.txt: file2.txt
touch $@
然后{/ 1}} 将更新,因此依赖关系链可以按预期工作。