首页 > 解决方案 > 普通 Makefile C++ 项目和单元测试

问题描述

我目前正在从事一个大型 C++ 项目,该项目恰好有大量的单元测试。随着时间的推移,构建时间开始变得相当长,所以我决定重新组织我的构建策略。我目前正在使用普通的 makefile,并且我没有计划切换到 Cmake 之类的东西。

整体组织如下:项目由多个模块组成,模块由多个类组成。这些模块被编译成静态库,然后这些库链接到项目的应用程序和单元测试。就makefile我而言,构建模块和应用程序没有问题。

最大的挑战在于单元测试:你看,最初,我让测试直接依赖于那些静态库,这意味着对任何模块的任何更改都会导致所有单元测试被重新构建。一开始这不是问题,但很明显,鉴于目前的项目规模,这是不可行的。

经过反复试验,我最终使测试依赖于单个目标文件,这意味着每当模块更改(以及因此其目标文件)时,只有依赖于它的测试才会重新编译。当然,必须重新链接测试可执行文件(因为它依赖于静态库),但这只是构建整个测试套件所需时间的一小部分。

在大多数情况下,此解决方案有效,但它增加了为每个测试手动列出依赖项的负担。下面是如何构建测试的示例:

1 : ...
2 :  # Add test dependencies here (.cc files only)
3 :  MODULES = LexicalAnalyzer SyntacticAnalyzer IntermediateRepresentation
4 :  MODULES_DEPS = $(addsuffix .o, $(addprefix $(BUILD_TEMP)/,$(MODULES)))
5 :
6 :  .PHONY: all
7 :
8 :  all: $(OBJ_FILES) $(MODULES_DEPS)
9 :
10:  -include $(DEP_FILES)
11:  $(BUILD_TEMP)/%.o: $(CURDIR)/%.cc $(MODULES_DEPS)
12:     $(CC) $(INCLUDE) $(CPPFLAGS) -MMD -MT"$@" -c $< -o $@
13: ...

重要的是要注意套件中的每个测试文件都有自己的makefile(并且存储在自己的目录中)。第 3 行列出了测试的依赖项,其中LexicalAnalyzerSyntacticAnalyzerIntermediateRepresentation项目模块。第 4 行将模块依赖项列表转换为该依赖项的目标文件的完整路径。

这种方法似乎可以满足我的需求,但我不禁觉得它很容易出错并且过于依赖文件名。你会如何组织这样一个项目?还有另一种方法可以只使用 plainmakefile吗?我不确定我可以完全解释我所拥有的,但希望这已经足够了......

谢谢!

标签: c++unit-testingmakefileproject-organization

解决方案


推荐阅读