首页 > 解决方案 > 为什么 Make 更喜欢隐式规则而不是 Makefile 中列出的规则?

问题描述

我试图弄清楚为什么 Make 使用某个规则来编译我的代码。这是一个最小的例子:

运行时make我得到以下信息:

$ make
gcc -O2 -Wno-implicit-function-declaration    main1.c   -o main1
/usr/bin/ld: /tmp/ccBsxlMV.o: in function `main':
main1.c:(.text.startup+0x11): undefined reference to `add'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: main1] Error 1

我的意图是通过%: %.o $(obj_lib)表明每个目标都依赖于所有目标文件,以便目标.o文件将与add.o. 但是,我观察到的是 Make 正在使用隐式规则将.c文件编译为可执行文件,由于add.o没有被链接,因此失败。

为什么 Make 使用隐式规则而不是我定义的规则?如何使用我在那里指定的命令让 Make 编译我的目标?

标签: makefilegnu-make

解决方案


原因是 make 总是使用最短的隐式规则链。所以,如果 make 可以找到一个规则%.x -> %.y和另一个规则%.x -> %.z -> %.y,它总是会选择第一个。

Make 不会区别对待内置规则和用户定义规则,只是先搜索用户定义规则,然后再搜索内置规则。

在您的情况下,您有一个知道如何从具有相同名称的源文件创建二进制文件的内置规则,以及您定义的知道如何从目标文件创建二进制文件的规则和另一个构建来自源文件的目标文件。所以make选择了第一个。

您可以使用以下方法删除该内置规则:

%: %.c

正如你所做的(你不必删除%.o : %.c规则)。或者,您可以使用创建显式规则的静态模式规则:

all: $(targets)

$(targets): %: %.o $(obj_lib)
        ...

因为这是一种显式规则,所以不会使用隐式规则(如模式规则)。


推荐阅读