CMake 依赖管理

CMake Dependency Management

我正在寻找有关正确 CMake 依赖管理的一些见解。我遇到过 ExternalProjectFetchContent,但两者都不能完全满足我的需求。让我详细解释一下:

我的项目结构如下:

main_project/
├── CMakeLists.txt
├── external/
│   ├── submodule1/
│   ├── submodule2/
│   ├── submodule3/
│   .
│   .
│   .

每个 submoduleN 都是一个 git 子模块,其中包含一个完整的 CMake 项目,带有自己的 安装目标 。我可以完全控制那些子模块(我编写它们)。我想使用 install targets 因为它们为子模块提供外部接口(具有适当的命名空间等)。我do not want to use the internal build targets。我想使用 find_package 来解决依赖关系。

其次,我不想使用某些下载机制来获取和部署依赖项。我想为此使用 git 个子模块,因为

假设每个 submoduleN 都有自己相似的子结构,并且它们可能在内部相互依赖。如果他们碰巧有一个共享的依赖关系,我希望他们使用一个单一的、通用的版本。主项目中的层次结构优先于版本选择。例如,类似于 FetchContent 的 populate 习语:

FetchContent_GetProperties(mylib)
if(NOT mylib_POPULATED)
  FetchContent_Populate(mylib)
  # do build, install and other stuff
endif()

我希望安装目标在配置步骤中可用(即 find_package),并且我希望在我编辑它们时重建它们(即在一个 submoduleN 中应用一些调试更改)。

问题:

我知道 Hunter++,它几乎解决了我的问题,除了 git 子模块和非下载部分。我用 ExternalProject 做了一个部分工作的例子,但我发现它很乱而且没有解决常见的版本问题:
https://github.com/image357/cmake_tutorial_external

有什么想法吗?


编辑:

我刚刚在 CMake 上发现了一个类似的提案:
https://gitlab.kitware.com/cmake/cmake/-/issues/21687

快速更新:好像Hunter has a git submodule mode: https://hunter.readthedocs.io/en/latest/user-guides/hunter-user/git-submodule.html

因此它实际上非常适合我的用例。

有这个在你的CMakeLists.txt

include(your/local/path/to/HunterGate.cmake)
HunterGate(
        URL "https://github.com/cpp-pm/hunter/archive/v0.23.320.tar.gz"
        SHA1 "9b4e732afd22f40482c11ad6342f7d336634226f"
        LOCAL
)

hunter_add_package(mysubmodule_lib)
find_package(mysubmodule_lib CONFIG REQUIRED)

在你的项目 cmake/Hunter/config.cmake 中有这个:

hunter_config(mysubmodule_lib GIT_SUBMODULE your/path/to/mysubmodule_lib VERSION 1.2.3)