Make无法识别间接依赖关系的更改

时间:2018-03-14 14:10:01

标签: makefile dependencies dependency-graph

考虑这个简单的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.txtfile1.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动态生成的。

当我多个依赖关系时,如何确保检查修改一直在树上

2 个答案:

答案 0 :(得分:1)

您的makefile完全既不生成也不更新 file1.txt(例如:file1.txt在运行make时必须存在。它包含 no recipe ,用于从file1.txt生成file2.txt。它只有空规则(即:没有配方的规则):

file1.txt: file2.txt

由于file1.txtoutput.txt的先决条件,因此这个空白规则只意味着file2.txt必须存在才能构建output.txt,它甚至不会更新file1.txt生成file2.txt时。

由于file1.txtoutput.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.txtfile1.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}} 更新,因此依赖关系链可以按预期工作。