Makefile:为什么带有%的makefile不起作用?

爱德华

我的Makefile中的%无效。

我已经在ubuntu 16.04 x64上测试了makefile。

我的makefile代码是:版本1

CC=gcc
OBJ=main.o
TARGET:=main
.PHONY: clean
all : main
# ${OBJ}:%.o:%.c

%.i : %.c
        $(info Preprocess: build main.i)
        ${CC} -E -o $@ $<

%.s : %.i
        $(info Compile: build main.s)
        ${CC} -S -o $@ $<

%.o : %.s
        $(info Assemble: build main.o)
        ${CC} -c -o $@ $<

main : main.o
        $(info Link: build main.o)
        ${CC} -o $@ $^

clean:
        rm -f *.o *.out *.s *.i *.asm *.map ${OBJ} main

运行make,终端显示消息:

gcc    -c -o main.o main.c
Link: build main.o
gcc -o main main.o

因此,只有最后一条规则(main:main.o)运行。第一个步骤是自动派生的代码(gcc -c -o main.o main.c)。为什么其他规则没有执行?

然后修改第三条规则,添加静态模式:版本2

...
%.i : %.c
        $(info Preprocess: build main.i)
        ${CC} -E -o $@ $<

%.s : %.i
        $(info Compile: build main.s)
        ${CC} -S -o $@ $<

main.o : %.o : %.s
        $(info Assemble: build main.o)
        ${CC} -c -o $@ $<

%: %.o
        $(info Link: build main.o)
        ${CC} -o $@ $^

然后所有规则生效,显示消息:

Preprocess: build main.i
gcc -E -o main.i main.c
Compile: build main.s
gcc -S -o main.s main.i
Assemble: build main.o
gcc -c -o main.o main.s
Link: build main.o
gcc -o main main.o
rm main.i

(为什么运行“ rm main.i”?)

我再次修改makefile:版本3

%.o:%.c
        $(info build main.o)
        ${CC} -c -o $@ $<
main : main.o
        $(info Link: build main.o)
        ${CC} -o $@ $^

它可以正确运行。列印讯息:

build main.o
gcc -c -o main.o main.c
Link: build main.o
gcc -o main main.o

那么,为什么版本1无法正常工作?

亚历克斯

这是行不通的,因为make知道如何.o.c源代码构建目标文件(内置的隐式规则

您可以禁用隐式规则,如果您运行的版本1make -r应该可以正常运行。

.i文件被删除,因为它是一个中间文件,默认情况下,make删除所有中间文件,可以通过使用.PRECIOUS: some-file-name

%makefile中的规则称为stempattern规则(不是通配符,这是另一回事)

您可以运行make与参数--debug--debug=all进行详细的日志或更详细的日志

编辑

您还有两个选项可以禁用内置规则并使版本1正常运行:

  • 用空规则覆盖特定的内置规则,只需添加 %.o: %.c
  • 禁用所有内置规则,添加空后缀列表 .SUFFIXES:

如果您修改后缀列表,则唯一有效的预定义后缀规则将是由您指定的列表中的一个或两个后缀命名的规则

编辑

禁用我过去使用的内置规则的另一个选项:

MAKEFLAGS += --no-builtin-rules

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么带有头文件的makefile不起作用?

带有通配符的 Makefile 目标不起作用

为什么$(<file.txt)在makefile上不起作用?

为什么这个makefile文件不起作用?

为什么带有字符语句的 ifelse 不起作用?

为什么带有push的git别名不起作用?

为什么带有粘性div的网格不起作用?

为什么Bash-in-Makefile表达式不起作用?

Makefile:为什么命令替换在$(shell)函数中不起作用?

为什么.save在Mongoose中起作用但在带有upsert的.update中不起作用

为什么带有jmp指令的shellcode起作用,为什么标签在C包装器中不起作用?

g ++的openmp的makefile ----不起作用

Makefile中的路径不起作用

Makefile不起作用,@ if,@ else,@ then找不到

推送在makefile中不起作用

通用Makefile在FreeBSD上不起作用

Makefile通用规则不起作用

Makefile模式规则不起作用

-lm对我的Makefile不起作用

'notdir'在Makefile中不起作用

为什么这种带有动态输入值的表单验证不起作用?

悬停时,为什么带有CSS过渡的其他图像源不起作用?

为什么VStack在带有scrollview的GeometryReader中不起作用?

为什么带有多个可观察对象的RxSwift concat似乎不起作用?

为什么带有javascript的脚本标签在ionic项目中不起作用?

为什么这个带有 flatpickr 的 jQuery 不起作用?(动态添加/删除日期时间字段)

为什么带有 \[ 的正则表达式不起作用

发现:为什么带有egrep的正则表达式不起作用?

从列中删除带有冒号的单词-为什么不起作用?