模块化c++项目构建与CMake

Modular C++ Project Build with CMake

本文关键字:CMake 构建 项目 c++ 模块化      更新时间:2023-10-16

我正试图找到一种方法来建立一个大的模块化c++项目与CMake。

项目结构如下:

--project_root
  --src
    --folder_1
      --source_1.h
      --source_1.cc
      --test_source_1.cc // file containing a main with unit tests
    --folder_2
      --source_2.h
      --source_2.cc
      --test_source_2.cc // file containing a main with unit tests
    --folder_3
      ...

等等

每个文件夹代表一个项目模块,每个模块可能依赖于其他模块,因此例如source_1.h可能包括source_2.h。每个模块文件夹也可以包含一个测试文件,这样整个项目将有多个可执行文件。

如何用CMake构建整个项目?我应该如何写我的CMakeLists.txt文件?

非常感谢。

关于如何为c++构建CMake项目的例子有很多,其中许多都是在他的评论中建议的教程@user2485710中引用的,所以我不打算在这里深入讨论,但我至少会给你一个很好的起点,基于你想要布局文件夹结构的方式。

CMake的好处是,它基本上可以使用add_subdirectory命令做一个像样的树。这让我们可以很容易地划分CMake代码,只做任何特定目录级别所需的事情。换句话说,每个CMakeLists.txt文件应该只做正确设置目录树当前深度所需的最少的工作。在你的例子中,你的CMake树可能看起来像这样:

--project_root
  --src
    --CMakeLists.txt
    --folder_1
      --CMakeLists.txt
      --source_1.h
      --source_1.cc
      --test_source_1.cc // file containing a main with unit tests
    --folder_2
      --CMakeLists.txt
      --source_2.h
      --source_2.cc
      --test_source_2.cc // file containing a main with unit tests
    ...

src/CMakeLists.txt中,您执行所有项目级初始化,即find_package,设置包含路径等。然后只需在末尾添加以下内容:

add_subdirectory(folder_1)
add_subdirectory(folder_2)
...

这告诉CMake它应该在这些文件夹中寻找额外的东西要做。现在在src/folder_1/CMakeLists.txt中,我们做add_executableadd_library的任何组合的实际工作,你需要正确构建source_1.cctest_source_1.cc,同样在src/folder_2/CMakeLists.txt中为source_2.cc,等等。

另一个好处是,您在树的上层设置的任何CMake变量都会通过add_subdirectory向下传播。所以,例如,在src/CMakeLists.txt你可以检查某种类型的"构建单元测试"标志,并设置CMake变量在那里,然后所有你要做的是在其他CMakeLists.txt文件检查该变量。如果你有一个项目,其中CMake基于检查环境变量的路径名等为你动态生成头文件,这也可以超级有用。

如果项目结构规范良好,可以编写自定义宏或cmake函数来定义模块及其依赖关系。

在OpenCV项目的cmake脚本是一个很好的参考:

/libs/opencv-2.4.8/sources/
|+cmake/
|+doc/
|~modules/
| |+core/
| | |+doc/
| | |+include/
| | |+perf/
| | |+src/
| | |+test/
| | `-CMakeLists.txt
| |~imgproc/
| | |+doc/
| | |+include/
| | |+perf/
| | |+src/
| | |+test/
| | `-CMakeLists.txt
| |+ml/
| |+...
| |-CMakeLists.txt
|-CMakeLists.txt
根/模块/imgproc/CMakeLists.txt

set(the_description "Image Processing")
ocv_define_module(imgproc opencv_core)

您将需要在每个文件夹中生成CMakeLists.txt。

project()用于设置整个项目的名称。

add_subdirectory()用于命令配置处理该目录下的CMakeLists.txt。

add_executable()用于从包含的源代码创建可执行文件。

add_library()用于创建静态或动态库,该库可以作为依赖项添加到可执行文件或库中。

使用构建脚本(.bat, .cmd或.sh)将允许您自动执行一些cmake过程,例如设置源外配置或构建。

您应该在cmake网站上查找这些命令的文档,https://cmake.org/cmake/help/latest/