CMake 项目模块化布局
Contents
在 C\C++ 项目中,通常会有不止一个可执行程序,或者需要将一些调用封装成动态或静态库,来实现项目的模块化,本文就讲解一种支持这种项目布局的方法。
CMake 支持子目录构建(add_subdirectory 指令),本文介绍的布局方法就是基于这个功能来实现。
项目
项目根目录编写一个 CMakeLists.txt,主要描述项目名称,也可以将一些项目级别的配置写入,来影响所有项目构建目标。比如编译的警告级别设置,如果要在项目级别上统一,可以写入,如果要针对不同构建目标来设置,可以留到构建目标 CMakeLists.txt 文件中写入。
项目的各个构建目标作为子目录存放在项目根目录下,每个子目录均包含相应的构建 CMakeLists.txt 文件。使用 add_subdirectory 指令将构建目标子目录添加到项目 CMakeLists.txt 中,构建目标间可以相互引用,只要在添加子目录到项目 CMakeLists.txt 时保持依赖顺序即可。
项目 CMakeLists.txt 示例:
|
|
项目 TestApps 中包含4个构建目标目录,2 个库 staticlib 和 sharelib,依赖库的 1 个应用程序 testapp,以及配置文件类目标 config。4 个目标的输出文件均统一到了构建目录下,按类型分类,这样便于构建结果的归档处理。
通常将构建目标子目录名与目标名一致,这样便于项目管理。
目标
每个构建目标对应在项目根目录下的各个子目录,每个子目录中都有一个 CMakeLists.txt 文件,记录着对应的构建配置。这些构建配置均会继承项目 CMakeLists.txt 文件中的配置。
以下针对示例项目,讲解各个子目录的 CMakeLists.txt ,用以理解如何进行具体的项目布局。
目标 staticlib(静态库编译示例):
|
|
add_library 指令添加一个库目标,参数 STATIC 表示编译成静态库,该目标链接时需要链接数学库。
目标 sharelib(动态库编译示例):
|
|
与目标 staticlib 差不多,只是add_library 参数 SHARED 表示编译成动态库。
目标 testapp(执行程序编译示例):
|
|
add_executable 指令添加一个可执行目标,其依赖于静态库 staticlib 和动态库 sharelib。
目标 config(配置文件示例):
|
|
config 目标是一个特殊目标,其不构建库或可执行程序,而是执行一个文件拷贝工作,在此示例中,将 config 目录下的文件(除 CMakeLists.txt 和 README.md)都拷贝到可执行输出目录中。这个用法一般用于拷贝程序的默认配置文件。这样做的好处在于可以将默认配置文件纳入版本管理,也方便打包程序以及测试部署,既能将代码与输出分离,又能实现自动化整合。
结语
CMake 是一个很便利的跨平台构建工具,使用模块化布局方法可以更契合多人共享开发模式,促进项目复用代码,方便上下游库协同管理。如果与 Git 的 submodule 配合,就更能体现出模块化。