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

如何使用单个Makefile构建存放于子文件夹中的多个C应用程序

你遇到的首次编译链接失败的核心原因是:wildcard函数在Makefile的解析阶段就会执行,此时编译生成.o文件的步骤还没运行,所以第一次执行时拿到的结果为空,第二次运行时.o已经生成在磁盘上,才能正常匹配到文件。
另外你最初写的$(OBJ): $(SRC)规则也存在逻辑问题:所有.o文件会依赖全部.c文件,只要修改任意一个.c,所有.o都会重新编译,不符合增量编译的需求。

不需要为每个子文件夹单独编写Makefile,修正后的单顶层Makefile即可正常运行,完整代码如下:

EXAMPLES := hello_world example1 example2
# 自动扫描所有.c文件
SRC := $(wildcard */*.c)
OBJ := $(SRC:.c=.o)
# 生成每个例子的最终输出路径:格式为 目录名/目录名
OUT := $(foreach e,$(EXAMPLES),$(e)/$(e))

CC := gcc
# 可自行补充链接参数,比如LDFLAGS += -lm
LDFLAGS ?= 

# 最终目标:编译所有示例
all: $(OUT)

# 通用编译规则:单个.c生成对应.o,支持增量编译
%.o: %.c
	$(CC) -c $< -o $@

# 通用链接规则:筛选对应目录下的所有.o链接生成最终二进制
%/%: $(OBJ)
	$(CC) $(filter $(dir $@)%.o,$^) -o $@ $(LDFLAGS)

# 清理规则
clean:
	rm -f $(OUT) $(OBJ)

# 声明伪目标,避免和目录下的同名文件冲突
.PHONY: all clean

修正点说明

  • 用通用模式规则%.o: %.c替代原来的全量依赖规则,实现增量编译:单个.c文件修改只会触发对应.o的重编译
  • 保留你之前验证过的filter筛选逻辑,该逻辑在规则执行阶段才会展开,此时所有.o已经编译完成,不会出现空值问题,能正确筛选出对应目录下的所有.o文件用于链接
  • 新增.PHONY伪目标声明,避免当目录下存在名为all、clean的文件时,make执行异常

内容的提问来源于stack exchange,提问作者DegH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:06:04