You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:39:51