考虑一个包含多个目标的长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
?
答案 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 目标。如果您的Makefile
非常庞大,可以将其拆分为多个文件并使用include
- 并在每个文件中添加一条.PHONY:
行。
答案 1 :(得分:0)
.PHONY: $(shell sed -n -e '/^$$/ { n ; /^[^ .\#][^ ]*:/ { s/:.*$$// ; p ; } ; }' $(MAKEFILE_LIST))
即使对于提到为依赖项的目标也能完美工作。