c - Makefile 执行错误命令

标签 c makefile gnu-make

我正在为我的项目使用以下生成文件:

IDIR    =       -I/a/include
INSURE  =
CC      =       gcc
CEFLAGS =       -fverbose-asm -masm=intel
AFLAGS  =
LFLAGS  =
WFLAGS  =       -Wall -Wextra
LDIR    =       -L/a/lib.Linux
LIBS    =       -lpthread -lpopt
OLVL    =       -O3

b.exe: b.o c.o
    $(CC) $(DBG) -o $@ $^ $(WFLAGS) $(IDIR) $(LDIR) $(LIBS)

%.o: %.s
    $(CC) -c $(DBG) $< $(AFLAGS) $(WFLAGS)

%.s: %.c %.h
    $(CC) -S $(DBG) $< $(OLVL) $(CEFLAGS) $(IDIR) $(WFLAGS)

.PHONY: debug
debug:
    $(eval DBG=-g)

.PHONY: clean
clean:
    rm *.o
    rm *.s

基于此,我期望生成一个 assmebly 文件作为第一步。但是,当我运行它时,我得到了

$make b.exe 
gcc    -c -o b.o b.c

在我看来,make 正在跳过我制作 b.o 的规则,而是运行默认规则。我想知道为什么以及如何解决它?

我正在使用 GNU Make 3.80 和 gcc 3.4.6。

最佳答案

您在 makefile 中定义的规则 do 优先于内置规则,但“一步”规则(可以直接从现有输入产生输出)胜过“多步”规则链(通过中间文件从现有输入产生输出),即使多步链是用户定义的并且一步规则是内置的。

在您的例子中,您已经定义了一系列模式规则:

bar.c -> bar.s -> bar.o

但这比从 bar.c 创建 bar.o 的内置规则要长:

bar.c -> bar.o

事实上,GNU make 的实现是这样的,在检查所有单步模式规则之前,甚至不会考虑多步规则链。当然,由于在您的示例中有一个匹配的一步规则,GNU make 使用它并且从不费心查看多步链。

如您所见,您可以通过在命令行上使用 -r 禁用所有内置规则来解决此问题。您还可以为给您带来麻烦的特定内置规则添加覆盖到您的 makefile。从字面上看,它看起来像这样:

%.o: %.c

也就是重新定义内置规则,没有命令。

关于c - Makefile 执行错误命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25976998/

相关文章:

cmake - gnu 使 : use wildcard twice in rule dependency

c - C 库的实现是否依赖于操作系统?

c - "inline"什么时候失效? (在 C 中)

makefile - GNU 为目标文件的自动列表制作替换命令

makefile - 从传递给用户定义函数的参数中去除前导空格

shell - 如何在Makefile中设置子进程的环境变量

c++ - GNU Make 在看到其他同名文件时重新使用源文件

testing - 实现 `make check` 或 `make test`

c - 如何修复这个简单的 do/while 循环?

c - 线程试图同时访问同一个变量? C