.PHONY 模式规则:匹配带有前导斜线的模式

.PHONY pattern rule: match pattern with leading slash

我正在尝试简化 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 文档是这样说的:

the ‘%’ matches any nonempty substring, while other characters match only themselves

https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html#Pattern-Intro


编辑: 修复关于 .PHONY: 的一些拼写错误,使用后缀而不是 answers/comments 中建议的前缀,并进一步测试:

正如我最初怀疑的那样,.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

您需要检查 How Patterns Match 上的部分,您会在其中找到以下文本:

When the target pattern does not contain a slash (and it usually does not), directory names in the file names are removed from the file name before it is compared with the target prefix and suffix.

(以及有关其工作原理的更多详细信息)。

根据文档和@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: 需要目标名称,它不会自动应用于后面的目标。