不评估带有百分号的 Makefile 规则

Ser*_*gey 5 linux makefile

我正在尝试将 Linux 内核的 kconfig util 移植到我的产品

编译时出现下一个错误:

make[6]: *** No rule to make target `zconf.tab.c', needed by `zconf.tab.o'.  Stop.
Run Code Online (Sandbox Code Playgroud)

我在 Makefile.lib 中找到了该文件的下一条规则

$(obj)/%: $(src)/%_shipped
    $(call cmd,shipped)
Run Code Online (Sandbox Code Playgroud)

它对我来说看起来不错,它只适用于内核,但不适用于我的产品。

然后我在前一条规则之后添加了另一条规则。

$(obj)/%c: $(src)/%c_shipped
    $(call cmd,shipped)
Run Code Online (Sandbox Code Playgroud)

现在效果很好。

有人可以解释一下原来的规则有什么问题吗?

就我而言obj=.,和src=.(两者=点)。当前目录包含适当的*_shipped文件。

Ulf*_*zer 4

我的猜测是,这$(obj)/%: $(src)/%_shipped符合匹配任何内容的模式规则。(该手册没有提到如何处理目录组件的目标和先决条件,但这是有意义的。)

请注意手册中的以下内容:

非终结符任意匹配规则不能应用于指示特定数据类型的文件名。如果某些不匹配的隐式规则目标与其匹配,则文件名指示特定类型的数据。

由于已经存在用于创建.c文件的内置隐式规则(例如使用解析器生成器),因此永远不会考虑匹配任何规则。

内核 makefile 不会发生错误的原因是它们使用 运行make-r这消除了内置的隐式规则。这是通过设置变量在顶级 makefile 中完成的MAKEFLAGS

# Do not use make's built-in rules and variables
# (this increases performance and avoids hard-to-debug behaviour);
MAKEFLAGS += -rR
Run Code Online (Sandbox Code Playgroud)

作为一个简单的实验,我创建了一个文件test.c_foo和以下 makefile:

MAKEFLAGS += -r

%: %_foo
   @echo building
Run Code Online (Sandbox Code Playgroud)

make test.c没有第一行给出

make: *** 没有规则可以创建目标“test.c”。停止。

在第一行中,它打印“building”。