Makefile如何自动将.o依赖转为.c目标?未定义.o目标为何仍可构建?
嘿,这两个问题本质上都和 Make 自带的**隐式规则(Implicit Rules)**有关——这是 Make 为了减少我们重复编写规则而预设的一套默认逻辑,我来给你详细拆解:
1. Makefile如何自动将.o依赖转换为.c目标?
Make 天生就知道「.o 目标文件是从对应的 .c 源文件编译来的」,它内置了一套默认的编译规则,大致等价于你手动写了:
%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
这里的关键细节:
%.o: %.c是模式规则,能匹配任意.o文件和对应的同名.c文件$@是自动变量,代表当前规则的目标文件(也就是那个待生成的.o)$<代表规则的第一个依赖文件(对应的.c源文件)$(CC)是 Make 默认的编译器变量(默认值为cc),$(CFLAGS)和$(CPPFLAGS)是默认的编译参数变量
当你在 Makefile 里只声明了某个目标依赖 .o 文件,但没定义 .o 对应的编译规则时,Make 就会自动调用这套隐式规则,找到对应的 .c 文件并完成编译。
这是隐式规则的延伸,还涉及到 Make 对「链式依赖」的自动推导能力:
当 Make 需要生成 olmenu-proto1_yacc.o 但找不到对应的自定义规则时,它会按步骤自动推导:
- 先尝试查找对应的
olmenu-proto1_yacc.c文件——如果这个文件存在,直接用上面的.c转.o隐式规则编译它; - 如果
olmenu-proto1_yacc.c也不存在,Make 会继续往上找能生成这个.c文件的规则,而它刚好内置了 Yacc 文件的隐式规则,大致等价于:
%.c: %.y $(YACC) $(YFLAGS) -o $@ $<
也就是说,如果你有 olmenu-proto1_yacc.y 文件,Make 会自动调用 Yacc 工具把 .y 文件编译成 .c,再把 .c 编译成 .o,最后把所有 .o 文件链接成 olmenu-proto1 目标。
如果你想确认 Make 到底用了哪些隐式规则,可以在终端执行 make -p 命令,它会列出所有 Make 内置的默认规则和变量。
内容的提问来源于stack exchange,提问作者jack chan
相关产品推荐
相关产品推荐

