cmake:add_subdirectory()vs include()

cmake: add_subdirectory() vs include()

假设我有一个使用cmake的C ++单元测试项目,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ tree
.
├── C-API-ConditionVariable-unit-test
│ ├── C-API-ConditionVariable-compile-link-test.c
│ ├── C-API-ConditionVariable-unit-test-0.cpp
│ └── C-API-ConditionVariable-unit-test-1.cpp
├── C-API-Mutex-unit-test
│ ├── C-API-Mutex-compile-link-test.c
│ ├── C-API-Mutex-unit-test-0.cpp
│ └── C-API-Mutex-unit-test-1.cpp
├── some
│ └── deeply
│   └── nested
│       └── path
│           └── SomeFeature-unit-test
│                 ├── SomeFeature-compile-link-test.c
│                 ├── SomeFeature-unit-test-0.cpp
│                 └── SomeFeature-unit-test-1.cpp
└── CMakeLists.txt

子文件夹中的每个源文件都会创建一个单独的可执行文件。我希望项目中的每个子文件夹都是一个非独立的模块-也就是说,每个子文件夹都是(或多或少)独立的,但不是一个可以单独编译的独立的cmake项目。我希望只能构建所有内容或一无所获。例如,我不想给人一种印象,即您只能从some/deeply/nested/path/SomeFeature-unit-test运行cmake来构建它。

我应该选择哪个选项?

  • 每个子文件夹中的CMakeLists.txt文件+顶级CMakeLists.txt中的add_subdirectory()
  • 每个子文件夹中的some-random-name.cmake +顶级CMakeLists.txt中的include();
  • 忽略我关于每个子文件夹都是独立的想法,并将所有相关的构建信息放置在顶级CMakeLists.txt中,其他cmake文件仅用作帮助程序(宏,函数等);
  • 第一个选项最方便,但是它建议每个子文件夹实际上是一个独立的项目,可以单独编译。

    第二种选择似乎清楚地表明这里只有一个cmake项目。但是,然后在子文件夹的每个some-random-name.cmake中,我必须使用完整路径来获取文件,这与我希望每个文件都独立的想法背道而驰。如果只有一个嵌套级别(例如前两个示例子文件夹),就可以了,但是对于some/deeply/nested/path/SomeFeature-unit-test来说就不太好了。我还必须在输出文件的名称前加上前缀。

    第三种选择似乎是一种快速创建长度为意大利面条的CMakeLists.txt文件的简便方法,因此我可能希望使用其他方法。

    我想知道在"现代" cmake项目中哪种是"首选"方式。在一个目录中有一个独立的库,在另一个文件夹中有一个使用该库的独立应用程序,而在另一个目录中有一个同一个库的独立测试,我可以找到的多目录项目的所有教程都涉及这种情况。使用cmake查看项目时,我看不到一致性,所以这没有太大帮助。

    (我是一个cmake菜鸟,试图将一个相对较大的项目转换为使用cmake)


    最常用的规则是"每个目标一个CMakeLists.txt"。所以您的选择号1。

    为此,如果"子文件夹中的每个源文件都创建了一个单独的可执行文件",则您的项目结构可能必须适应。

    CMakeLists.txt是您的起点,并且包含project()命令。

    请务必注意

    • CMake将在其生成的构建环境中镜像您的add_subdirectory()CMakeLists.txt目录结构
    • CMake将在每次add_subdirectory()调用时创建一个新的变量作用域(与使用include()命令的最大区别)

    您应该避免的是必须使用../some_other_dir/some_other_source.cpp之类的东西引用其他子目录中的源文件。它表明您的CMake结构没有根据上面引用的经验法则进行设置。

    文档摘录

  • CMake:add_subdirectory()命令

    Add a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.txt and code files are located.

  • CLion:CMakeLists文件

    When a project has the complex structure and includes one or more subdirectories (project root and subdirectories), you can create subdirectory CMakeList.txt files. Subdirectory CMakeLists.txt files describe the build, contents, and target rules for a subdirectory.

  • C ++ Now 2017:Daniel Pfeifer"有效的CMake:最佳实践的随机选择

    Directories that contain a CMakeLists.txt are the entry point for the build system generator. Subdirectories may be added with add_subdirectory() and must contain a CMakeLists.txt too.

  • 参考文献

    • 拥抱现代CMake
    • CMake教程
    • 带子目录的CMake
    • 具有多个可执行文件的CMake共享库
    • 重命名`CMakeLists.txt`