我正在尝试简化 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:
的拼写错误,使用后缀而不是答案/评论中建议的前缀,并进一步测试:
正如我最初怀疑的那样,.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
答案 0 :(得分:2)
您需要检查 How Patterns Match 上可以找到此文本的部分:
<块引用>当目标模式不包含斜杠时(通常包含 不),文件名中的目录名从文件名中删除 在与目标前缀和后缀进行比较之前。
(以及有关其工作原理的更多详细信息)。
答案 1 :(得分:1)
根据文档和@MadScientist 的回答,这是 how patterns match。但解决方法很简单:用后缀规则替换你的前缀规则,这样目录重整不会妨碍。
示例:
$ cat Makefile
.PHONY: %-clean
%-clean:
$(info $*)
.PHONY: foo
foo: /as/d-clean
@:
.PHONY: bar
bar: ./as/d-clean
@:
输出:
$ make foo
/as/d
$ make bar
as/d
顺便说一句。请注意,.PHONY:
需要目标名称,它不会自动应用于后面的目标。