【发布时间】:2021-06-08 08:53:57
【问题描述】:
我正在尝试简化 Makefile。在那,我试图有一个删除文件的模式规则:
.PHONY:
rm-%:
rm $*
其中 % 将包含文件的名称(通常是带有前导斜杠的绝对路径)。
然后我只是声明 rm-/some/file 是 make uninstall 的依赖项,并期望 make 匹配此模式规则。
但是,它咬了我。我做了一些测试并意识到问题在于前导斜杠与该模式规则不匹配:
~/src/test$ cat Makefile
.PHONY:
a-/%:
$(info /$*)
.PHONY:
b-%:
$(info $*)
.PHONY:
foo: a-/as/d
@:
.PHONY:
bar: b-/as/d
@:
~/src/test$ make foo
/as/d
~/src/test$ make bar
make: *** No rule to make target 'b-/as/d', needed by 'bar'. Stop.
~/src/test$
为什么我需要在模式规则中指定前导斜杠(而不是其他斜杠)?
GNU make 文档是这样说的:
'%' 匹配任何非空子字符串,而其他字符匹配 只有他们自己
https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html#Pattern-Intro
编辑:修正一些关于 .PHONY: 的拼写错误,使用答案/cmets 中建议的后缀而不是前缀,并进一步测试:
正如我最初所怀疑的那样,.PHONY: 正在做一些奇怪的事情:
~/src/test/$ tree a b c d
a
└── a
b
└── b
c
└── c
d
└── d
0 directories, 4 files
~/src/test$ cat Makefile
%-rmdir:
rmdir $(@D)
%-rm:
rm $*
.PHONY: ./a/.-rmdir
./a/.-rmdir: ./a/a-rm
.PHONY: ./b/-rmdir
./b/-rmdir: ./b/b-rm
./c/.-rmdir: ./c/c-rm
./d/-rmdir: ./d/d-rm
.PHONY: foo
foo: ./a/.-rmdir ./b/-rmdir ./c/.-rmdir ./d/-rmdir
$(info foo)
~/src/test$ make foo
rm a/a
rm b/b
rm c/c
rmdir c
rm d/d
rmdir d
foo
【问题讨论】:
-
请注意,我不知道您在
.PHONY pattern rule的问题标题中是什么意思,但是您没有在此处声明 anything.PHONY,因为它的先决条件列表是空的。但是,无论如何,虚假与您的问题无关。 -
@MadScientist D'oh,这是一个错字。无论如何,我只是添加了该信息以防它触发一些不同的行为,但我想它不会。
-
@MadScientist,你能回顾一下我添加的测试吗?看起来 .PHONY: 正在做某事...
-
询问时请清楚说明您显示的结果有什么问题(您期望的不同)。您需要花费大量时间来解决您试图自行解决的问题。但是,是的,正如其他问题所提到的,
.PHONY目标永远没有资格通过隐式规则进行查找。这是声明目标.PHONY: 以提高性能的主要原因之一。如果您只关心在不提高性能的情况下确保重建,您可以使用FORCE技巧。 -
我关于“不做任何事情”的原始评论仅涉及您最初的问题/makefile,其中
.PHONY目标没有先决条件。那是无操作的。