Makefile:声明所有目标PHONY

时间:2017-06-12 06:36:51

标签: makefile phony-target

考虑一个包含多个目标的长makefile,所有目标都是PHONY(意味着目标名称不代表现有文件)。

我可以做任何一件事:

.PHONY: a
a:
    do someting a

.PHONY: b
b:
    do someting b

.PHONY: c
c:
    do someting c

或者:

.PHONY: a b c
a:
    do someting a

b:
    do someting b

c:
    do someting c

第一个选项很麻烦,第二个选项很容易出错,因为将来我添加一个目标并忘记将其声明为PHONY

是否有标准方法可以将makefile中的所有目标声明为PHONY

2 个答案:

答案 0 :(得分:3)

如果真的所有目标都是 PHONY ,这有点毫无意义。 make用于“执行更新输出所需的操作”,如果必要的答案是什么?总是相同的,简单的脚本会以较少的开销做同样的工作。

话虽这么说,我可以想象一下所有目标打算在命令行给出的情况应该是 PHONY - 让我们假设您想构建一些类似的文档这样:

all: doc1.pdf doc2.pdf doc3.pdf doc4.pdf doc5.pdf

manuals: doc3.pdf doc4.pdf

faqs: doc1.pdf

designdocs: doc2.pdf

apidocs: doc5.pdf

developerdocs: doc2.pdf doc5.pdf

userdocs: doc1.pdf doc3.pdf doc4.pdf

%.pdf: %.md
     $(somedocgenerator) -o $@ $<

然后你可以执行以下操作:

.PHONY: all $(MAKECMDGOALS)

这将动态地在命令行 PHONY 中给出任何目标。请注意,您必须在此处包含默认目标,因为只需输入make即可在不明确指定的情况下调用它。

我不推荐这种方法,因为它有两个缺点:

  • 对于make的不同风格,它的可移植性较差。
  • 如果某人决定make此处make doc3.pdf之类的特定输出文件,则会出现行为异常
  • 如果您决定让某个 PHONY 目标依赖于另一个 PHONY ,那么它也会行为不端。

因此,最好采用一条方法来声明所有 PHONY 目标。如果您的Makefile非常庞大,可以将其拆分为多个文件并使用include - 并在每个文件中添加一条.PHONY:行。

答案 1 :(得分:0)

One way to do it:

.PHONY: $(shell sed -n -e '/^$$/ { n ; /^[^ .\#][^ ]*:/ { s/:.*$$// ; p ; } ; }' $(MAKEFILE_LIST))

即使对于提到为依赖项的目标也能完美工作。