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

如何使用Makefile在子目录生成C语言项目的.o目标文件

修改方案

你只需要对原有Makefile做以下几处调整即可实现需求:

  • 开头声明目标文件存储目录变量,同时把重复的编译、链接参数抽成公共变量,降低维护成本
  • 所有.o目标和引用路径前统一加上目录前缀
  • 编译命令末尾增加-o $@参数,明确指定目标文件输出到指定目录
  • 增加目录自动创建逻辑,避免首次编译因目录不存在报错
  • 链接、清理阶段的路径同步修改

完整修改后Makefile

# 自定义目标文件存储路径,可按需调整
OBJDIR = ./objects
# 公共编译参数
CFLAGS = -fstack-protector-all -std=c99 -g
# 公共链接库
LDLIBS = -lm

# 最终生成的可执行文件目标
progr : $(OBJDIR)/main.o $(OBJDIR)/manipulate_strings.o $(OBJDIR)/environment_set.o $(OBJDIR)/variables.o $(OBJDIR)/segments_private.o $(OBJDIR)/rectangle_private.o $(OBJDIR)/circle_private.o $(OBJDIR)/tree.o $(OBJDIR)/dynamic_list.o $(OBJDIR)/visibility.o $(OBJDIR)/query.o
	gcc $(CFLAGS) $^ -o $@ $(LDLIBS)
	# 编译完成后如果不需要保留目标文件可保留这行,无需清理则删除
	rm -rf $(OBJDIR)/*.o

# 各级源文件对应的.o生成规则
$(OBJDIR)/main.o : main.c manipulate_strings.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/manipulate_strings.o : manipulate_strings.c manipulate_strings.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/environment_set.o : environment_set.c environment_set.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/variables.o : private/variables.c private/variables.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@ $(LDLIBS)

$(OBJDIR)/segments_private.o : private/segments_private.c private/segments_private.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@ $(LDLIBS)

$(OBJDIR)/rectangle_private.o : private/rectangle_private.c private/rectangle_private.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/circle_private.o : private/circle_private.c private/circle_private.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/tree.o : data_struct/tree.c data_struct/tree.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/dynamic_list.o : data_struct/dynamic_list.c data_struct/dynamic_list.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/visibility.o : visibility.c visibility.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@

$(OBJDIR)/query.o : query.c query.h
	@mkdir -p $(OBJDIR)
	gcc $(CFLAGS) -c $< -o $@ $(LDLIBS)

# 可选:手动清理目标
clean:
	rm -rf $(OBJDIR) progr

可选简化优化

如果不想重复写每个.o的编译规则,可以添加模式规则统一处理,之后只需要维护每个.o的头文件依赖即可:

# 匹配根目录的.c文件生成.o
$(OBJDIR)/%.o : %.c
	@mkdir -p $(@D)
	gcc $(CFLAGS) -c $< -o $@

# 匹配private目录的.c文件生成.o
$(OBJDIR)/%.o : private/%.c
	@mkdir -p $(@D)
	gcc $(CFLAGS) -c $< -o $@

# 匹配data_struct目录的.c文件生成.o
$(OBJDIR)/%.o : data_struct/%.c
	@mkdir -p $(@D)
	gcc $(CFLAGS) -c $< -o $@

说明

  • 原有Makefile存在一处笔误:progr的依赖列表中写的是segment_private.o,实际对应源文件是segments_private.c,上述代码已经修正该问题
  • mkdir -p命令不会在目录已存在时报错,适合编译前自动创建目录
  • $<代表第一个依赖文件,$@代表当前目标文件,属于Makefile内置自动变量,可简化代码编写

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 12:45:07