makefile - 为什么 echo 在 % : foo. o 规则中起作用,但在 % : %. o 中不起作用?

标签 makefile

这是我当前的 makefile

.PHONY = all clean

all: foo
        @echo "Dependencies: $<"

%: %.o
        @echo "Checking.. $@, <- $<"
        gcc -lm foo.o -o foo
        @echo "\n"

%.o: %.c
        @echo "Creating object.. $@, <- $<"
        gcc -c foo.c
        @echo "\n"

clean:
        @echo "Cleaning up..."
        rm -rvf foo.o foo

当我运行 make 时,它​​不会打印出任何回显的字符串,但我仍然得到可执行文件。这是打印到终端的所有内容

gcc                             foo.c   -o foo
echo "Dependencies: foo"

当我用 %: foo.o 替换 %: %.0 规则时,所有内容都会正常打印到终端

Creating object.. foo.o, <- foo.c
gcc -c foo.c


Checking.. foo, <- foo.o
gcc -lm foo.o -o foo


Dependencies: foo
rm foo.o

在这两种情况下,我仍然得到可执行文件 foo 并且它正常工作,但为什么我在终端中得到 2 个不同的结果?

最佳答案

When I run make, it doesn't print out any echoed strings, but I still get the executable file.

由于您没有明确的构建规则 foo ,(GNU)make执行implicit rule search ,通过它尝试找到一系列一个或多个模式规则,无论是用户提供的还是内置的,通过它可以构建 foo 。尽管它可以选择应用您的规则来构建 foo.o来自foo.c然后你的规则构建 foo来自foo.o ,它有一个较短的链可用:构建 foo 的内置规则直接来自foo.c 。它选择后者,因为它更短。

When I replace %: %.0 rule with %: foo.o, everything is printed to the terminal normally

这是隐式规则搜索过程的一个怪癖。当您进行更改时,make将修订后的规则标识为“适用于”建筑 foo由于唯一的先决条件是具有明确的名称(这是手册中描述的算法中的第 5.3 项)。直接从%.c构建的内置规则也适用,但 makefile 中给出的规则具有优先权(在相同长度的规则链中)。事实是make必须单独弄清楚如何制作foo.o在这种情况下不考虑(这是奇怪的部分,但从文档中可以清楚地看出)。

当然,这种特殊的怪癖很少会被触发,因为修订后的规则几乎总是不合适的。它说无论要构建什么目标,都可以从 foo.o 构建它。 ,通过提供的配方,但该配方确实仅适用于构建 foo 。而不是%: foo.o ,那么,你真的应该做到 foo: foo.o :

.PHONY = all clean

all: foo
        @echo "Dependencies: $<"

foo: foo.o
        @echo "Checking.. $@, <- $<"
        gcc -o $@ $< -lm
        @echo "\n"

%.o: %.c
        @echo "Creating object.. $@, <- $<"
        gcc -c foo.c
        @echo "\n"

clean:
        @echo "Cleaning up..."
        rm -rvf foo.o foo

附加说明:

  • 链接库选项,例如 -lm应该出现在链接线的末尾。这些文件和目标文件在命令行上的相对顺序很重要。
  • 避免重复自己的话。规则的配方应该使用 automatic variables尽可能避免重复目标或先决条件名称。

关于makefile - 为什么 echo 在 % : foo. o 规则中起作用,但在 % : %. o 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57233519/

相关文章:

c - 如何将参数的值包含到 makefile 中的字符串中

c - Makefile:尽管给出了目标,但没有制定目标的规则?

linux - 为什么 "make all"似乎跳过了 "all:"规则?

c - 体系结构 x86_64 错误的 Makefile 重复符号?

linux - "Exec format error"运行由 g++ 创建的二进制文件

c - Makefile 不使用变量

emacs - 如何在 Emacs 中为 Ocaml 生成和设置注释?

Makefile 中找不到命令错误

ubuntu - 构建 apache thrift 时出错

c++ - 静态库中对 c++11 原子的 undefined reference