.PHONY 模式规则:匹配模式与前导斜杠

时间:2021-06-08 08:53:57

标签: makefile gnu-make

我正在尝试简化 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

2 个答案:

答案 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: 需要目标名称,它不会自动应用于后面的目标。