如何修改Makefile规则,修复多目录.c生成.o的unit_test构建错误
解决Makefile中unit_test目标的构建错误
问题场景
./source_files/:存放make build2和make unit_test共用的*.c文件./source_files/unit_tests/:仅make unit_test使用的*.c文件
两个构建命令需求:
make build2:正常工作,编译source_files/*.c生成build/*.o并打包为静态库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
相关产品推荐
相关产品推荐

