Makefile隐式规则:编译子目录源码并在根目录生成目标文件失败问题
问题分析
你的Makefile核心问题是:旧版本的GNU Make不支持模式规则中的%通配符匹配包含路径的目标。你写的%.o: src/%.c规则只能匹配当前目录下的main.o,无法匹配sub/file.o这种带路径的目标——因为旧版Make里的%只能匹配单个文件名,不能包含目录分隔符/。
当Make处理sub/file.o这个依赖时,找不到对应的构建规则,就会默认认为该目标已经存在(或者不需要构建),直接跳到链接步骤,自然就会报找不到sub/file.o的错误。
解决方案
有两种可靠的修复方式,都能满足你在根目录生成对应路径目标文件的需求:
方案一:使用静态模式规则
静态模式规则可以明确为每个带路径的目标匹配对应的源文件,不受Make版本限制:
all: tool # GENERATED PART START OBJS := main.o sub/file.o main.o: src/main.c src/sub/file.h sub/file.o: src/sub/file.c src/sub/file.h # GENERATED PART END # 静态模式规则:为每个目标匹配src下对应的.c文件 $(OBJS): %.o: src/%.c mkdir -p $(dir $@) gcc -c -o $@ $< tool: $(OBJS) gcc -I src -o $@ $^ .PHONY: all
方案二:使用vpath指定源文件搜索路径
通过vpath告诉Make到src目录下查找.c文件,这样普通模式规则就能匹配带路径的目标:
all: tool # GENERATED PART START main.o: src/main.c src/sub/file.h sub/file.o: src/sub/file.c src/sub/file.h # GENERATED PART END # 指定.c文件在src目录搜索 vpath %.c src %.o: %.c mkdir -p $(dir $@) gcc -c -o $@ $< tool: main.o sub/file.o gcc -I src -o $@ $^ .PHONY: all
验证效果
执行make后,会正确生成main.o、sub/file.o和tool,完全符合你的预期项目结构。
内容的提问来源于stack exchange,提问作者Schlumpf
相关产品推荐
相关产品推荐

