【发布时间】:2018-07-08 15:49:14
【问题描述】:
假设我有一个使用 cmake 的 C++ 单元测试项目,如下所示:
$ 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每个子文件夹中的文件 +add_subdirectory()在顶级CmakeLists.txt中; -
some-random-name.cmake在每个子文件夹中 +include()在顶级CmakeLists.txt中; - 忽略我的想法,即每个子文件夹都是独立的,并将所有相关的构建信息放在顶级
CMakeLists.txt中,其他 cmake 文件仅作为帮助程序(宏、函数等);
第一个选项最方便,但它表明每个子文件夹实际上是一个独立的项目,可以单独编译。
第二个选项似乎清楚地表明这里只有一个 cmake 项目。但是随后在子文件夹中的每个some-random-name.cmake 中,我必须使用源文件的完整路径,这违背了我希望它们中的每一个都是独立的。如果只有一层嵌套(例如前两个示例子文件夹),那没关系,但对于some/deeply/nested/path/SomeFeature-unit-test,这不是很好。我还必须为输出文件的名称加上前缀。
第三个选项似乎是一种快速创建具有意大利面条长度的CMakeLists.txt 文件的简单方法,所以我可能更喜欢其他东西。
我想知道在“现代”cmake 项目中哪种是“首选”方式。我可以为多目录项目找到的所有教程都涉及以下情况:一个文件夹中有一个独立库,独立应用程序在另一个文件夹中使用该库,以及在另一个目录中使用相同库的独立测试。查看使用 cmake 的项目,我发现没有一致性,所以这没有多大帮助。
(我是cmake菜鸟,想把比较大的项目转成cmake使用)
【问题讨论】:
-
I would like know which is the "preferred" way in a "modern" cmake project.- 没有单一的“首选”方式。选择一个对你来说似乎方便的,并实施它。顺便说一句,add_subdirectory本身的方式并不意味着子项目是独立的。 -
@Tsyvarev - 作为一个完整的 cmake 菜鸟,我更愿意将我的选择基于某种常识而不是我自己的偏好(; 你说我的理解
CMakeLists.txt意味着文件夹是独立是错误的?但是如果一个特定的存储库将包含一些 cmake 项目,你怎么知道你应该使用哪个CMakeLists.txt来构建一些东西而不阅读文档? -
“但是,如果一个特定的存储库包含几个 cmake 项目,你怎么知道应该使用哪个 CMakeLists.txt 来构建一些东西而不阅读文档呢?” - 没门。 On 可能猜测顶级
CMakeLists.txt将是需要的。但可能需要CMakeLists.txt在 some other 项目中;例如在给定项目提供插件的情况下。
标签: cmake