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

如何修改Makefile规则,修复多目录.c生成.o的unit_test构建错误

解决Makefile中unit_test目标的构建错误

问题场景

  • ./source_files/:存放make build2和make unit_test共用的*.c文件
  • ./source_files/unit_tests/:仅make unit_test使用的*.c文件

两个构建命令需求:

  1. make build2:正常工作,编译source_files/*.c生成build/*.o并打包为静态库
  2. make unit_test:需编译source_files/*.c和source_files/unit_tests/*.c生成build/*.o,最终生成可执行文件test_main.out,但执行该命令时报错

错误信息

make: *** No rule to make target 'build/test_main.o', needed by 'unit_test'.  Stop.

问题根源

当前模式规则存在路径错误:

$(BUILDDIR)/%.o: $(UNITSRCS)/%.c | $(BUILDDIR)

$(UNITSRCS)是所有单元测试源文件的完整路径列表(比如source_files/unit_tests/test_main.c),用它作为模式规则的依赖会导致通配符%无法匹配正确的路径,Make找不到生成build/test_main.o的规则。

修正后的完整Makefile

#Compiler flags
CC := gcc
INCLDIR := -I./includes
LIBS := -lcunit

#Directories and files
BUILDDIR := build

SRCDIR := source_files
SRCS := $(wildcard $(SRCDIR)/*.c)
OBJS := $(SRCS:$(SRCDIR)/%.c=$(BUILDDIR)/%.o)

UNITDIR := $(SRCDIR)/unit_tests
UNITSRCS := $(wildcard $(UNITDIR)/*.c)
UNITOBJS := $(UNITSRCS:$(UNITDIR)/%.c=$(BUILDDIR)/%.o)

STLIB := $(BUILDDIR)/libbinary_tree.a

$(BUILDDIR):
    mkdir $(BUILDDIR)

# 编译主源码目录下的.c文件到build目录
$(BUILDDIR)/%.o: $(SRCDIR)/%.c | $(BUILDDIR)
    $(CC) -c $< $(INCLDIR) -o $@

# 编译单元测试目录下的.c文件到build目录
$(BUILDDIR)/%.o: $(UNITDIR)/%.c | $(BUILDDIR)
    $(CC) -c $< $(INCLDIR) -o $@

.PHONY: unit_test
unit_test: $(OBJS) $(UNITOBJS)
    $(CC) $(OBJS) $(UNITOBJS) $(INCLDIR) $(LIBS) -o $(BUILDDIR)/test_main.out

.PHONY: build2
build2: $(OBJS)
    ar -rcs $(STLIB) $(OBJS)

.PHONY: clean
clean:
    rm -r $(BUILDDIR)

修正说明

把错误的$(UNITSRCS)/%.c改为$(UNITDIR)/%.c:

  • 模式规则中,%作为通配符需要对应源文件的相对路径,$(UNITDIR)是单元测试源文件的目录,这样Make能正确匹配source_files/unit_tests/xxx.c到build/xxx.o的生成关系
  • 两个模式规则分别处理不同目录的源文件,无需合并,只要路径匹配正确即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:25:24