GNU make 不执行命令

问题描述 投票:0回答:1

我有两个不同的操作系统环境:CentOS6 和 CentOS7。

CentOS6 GNU make版本是3.81

CentOS7 GNU make版本为3.82

我的Makefile如下

%o : %c   
    $(CC) -c $(CPFLAGS) -I. $(INCDIR) $< -o $@

3.81 效果很好。

但是3.82不会执行命令

$(CC) -c $(CPFLAGS) -I. $(INCDIR) $< -o $@

似乎只执行其默认命令

%o : %c 

我在终端上看到的内容,将像这样展开 ===> gcc c -o main.o main.c

经过一些测试,我确信这条线 $(CC) -c $(CPFLAGS) -I。 $(INCDIR) $< -o $@ will NEVER be executed.

Google搜索后,我用另一种语法格式重写

.c.o:

    $(CC) -c $(CPFLAGS) -I. $(INCDIR) $< -o $@

这有效! $(CC) -c $(CPFLAGS) -I。 $(INCDIR) $< -o $@ will execute!!!

我阅读了 3.82 发行说明,但没有得到任何有关此问题的线索。

你能帮我解释一下原因吗?

我不认为这是由不同的 GNU make 版本引起的。

谢谢!!!

makefile gnu-make
1个回答
0
投票

当你说:

似乎只执行其默认命令

%o : %c

这是不正确的。从 C 源文件构建目标文件的默认规则不是

%o : %c
,而是
%.o : %.c
。这里的差异(添加的
.
)可能看起来很小,但这就是您看到的行为的原因。

由于默认规则是

%.o : %.c
,当您使用
%o : %c
定义自己的规则时,这是一个完全不同的规则:它不会替换现有规则,它是一个新规则除了现有规则之外.

所以现在有two模式规则可用于从 C 源文件构建目标文件。 make 如何决定使用哪一个? GNU Make 3.81 和 GNU Make 3.82 之间的选择算法发生了变化。

在 GNU Make 3.81 及更早版本中,始终选择“第一个定义的规则”(其中默认规则被认为是最后定义的)。这意味着您的规则%o: %c已被选择。

在 GNU Make 3.82 及更高版本中,始终选择“最佳匹配”。最佳匹配被定义为

stem

(与%匹配的部分)最短的规则(我们的选择是选择最具体的规则)。如果我们想从 foo.o 构建

foo.c
,那么在默认规则中,词干是
foo
,而在您的替代规则中,默认是
foo.
(对于与字符串
%o
词干匹配的模式
foo.o
) --匹配
%
的部分--是
foo.
).
由于内置规则的主干(
foo
为 3 个字符长)比模式规则的主干(

foo.

为 4 个字符长)短,因此内置规则

更具体
,所以它将被选择。
如果您希望 makefile 适用于所有版本,那么您应该使用 same 模式而不是不同的模式来 

replace

内置规则,而不是创建 extra 规则;将您的规则写为: %.o : %.c $(CC) -c $(CPFLAGS) -I. $(INCDIR) $< -o $@ 它适用于所有版本的 GNU Make。

您的规则无论如何都不是很好,因为省略 
.

意味着该规则将匹配任何以

o

结尾的目标文件(不仅仅是

.o
)以及任何以
c
结尾的先决条件(不仅仅是
 .c
)。
    

© www.soinside.com 2019 - 2024. All rights reserved.