具有PHONY依赖性的真实目标

时间:2013-09-06 21:19:51

标签: makefile dependencies

尝试找到一种优雅的方法来解决一些复杂的依赖关系。我的Makefile中有以下内容:

.PHONY: FOO
FOO: foo
foo:
    build foo

.PHONY: BAR
BAR: bar
bar: FOO
    build bar

这里的想法是我想用虚假目标(FOO BAR)抽象真实文件(foo,bar)。当然,在我真正的Makefile中,它更复杂,这就是为什么抽象很重要。但是,这里的问题是让假目标FOO成为bar的依赖,然后Make总是尝试重建bar,即使foo和bar都是最新的。这显然是因为它总是将FOO视为过时。但这种行为并不正确。

所以看来我只有3个选项:     1)使bar直接依赖于foo。在我真正的Makefile中,它更复杂,并且尝试将实际文件指定为依赖项是非常不受欢迎的。     2)除了所有的声音之外还使用变量。这使得整个Makefile更加复杂。     3)从bar中删除foo / Foo作为依赖项,并在bar中添加FOO的递归make作为规则的一部分。这是非常糟糕的形式。

是否有一些我不了解的更优雅的解决方案?

感谢。

2 个答案:

答案 0 :(得分:2)

GNU make对这种情况的回答是order-only dependencies。它允许您提供目标的排序,而不会过时"过时"关系也是如此。从您的问题来看,这似乎是您正在寻找的。

所以上面的makefile片段看起来像这样:

.PHONY: FOO
FOO: foo
foo:
    build foo

.PHONY: BAR
BAR: bar
bar: | FOO
    build bar

这将允许foo始终在bar之前构建,但不会强制要求在foo更新时,必须构建该bar。只有在调用make BAR并且foo的文件不存在时才会构建foo。

答案 1 :(得分:1)

正如您所说,变量就是您所需要的,并且实际上可以帮助您实现可读性。它们允许我们使条形文件正确依赖于foo文件,而不是用户友好的.PHONY目标:

foo.file = horrendously/long/path/to/the/real/foo.file
bar.file = horrendously/long/path/to/the/real/bar.file

.PHONY: FOO
FOO: $(foo.file)
$(foo.file):
        touch $@

.PHONY: BAR
BAR: $(bar.file)
$(bar.file): $(foo.file)
        touch $@

我们走了:

$ make BAR 
touch horrendously/long/path/to/the/real/foo.file
touch horrendously/long/path/to/the/real/bar.file

$ make BAR
make: Nothing to be done for `BAR'.