我试图找到一种方法来使用CMake构建一个大型模块化C ++项目。
项目结构如下:
--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文件?
非常感谢你。
答案 0 :(得分:1)
有许多关于如何为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
中,您执行所有项目级初始化,I.E。 find_package
,设置包含路径等。然后,您只需在结尾处添加以下内容:
add_subdirectory(folder_1)
add_subdirectory(folder_2)
...
这告诉CMake应该查看这些文件夹中的其他内容。现在在src/folder_1/CMakeLists.txt
,我们执行add_executable
和add_library
的任何组合的实际工作,您需要正确构建source_1.cc
和test_source_1.cc
,同样在{{{} 1}} src/folder_2/CMakeLists.txt
等等。
另一件好事是,您在树上设置的任何CMake变量都会向下传播source_2.cc
。因此,例如,在add_subdirectory
中,您可以检查某种“构建单元测试”标志并在那里设置CMake变量,然后您在其他CMakeLists.txt文件中所要做的就是检查变量。如果您有一个项目,CMake根据检查路径名称的环境变量等为您动态生成头文件,这也是非常有用的。
答案 1 :(得分:1)
如果项目结构管理良好,您可以编写自定义宏或cmake函数来定义模块及其依赖项。
OpenCV project中的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)
答案 2 :(得分:0)
在将要进行构建的每个文件夹中,您都需要一个CMakeLists.txt。
project()用于设置整个项目的名称。
add_subdirectory()用于命令配置以处理该目录中的CMakeLists.txt。
add_executable()用于从包含的源创建可执行文件。
add_library()用于创建可以作为依赖项添加到可执行文件或库的静态或动态库。
使用构建脚本(.bat,.cmd或.sh)将使您可以自动化某些cmake流程,例如设置源外配置或构建。
您应该在cmake网站https://cmake.org/cmake/help/latest/
上查找这些命令的文档。