首页 > 解决方案 > CMake 依赖管理

问题描述

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

我的项目具有以下结构:

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

每个submoduleN都是一个 git 子模块,其中包含一个完整的 CMake 项目和自己的安装目标。我可以完全控制这些子模块(我编写它们)。我想使用安装目标,因为它们为子模块提供了外部接口(具有适当的命名空间等)。我不想使用内部构建目标。我想用来find_package解决依赖关系。

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

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

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

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

问题:

我知道Hunter++,它几乎解决了我的问题,除了 gitsubmodule 和 no-download 部分。我用 做了一个部分工作的例子ExternalProject,但我觉得它很乱,它不能解决常见的版本问题:
https ://github.com/image357/cmake_tutorial_external

有任何想法吗?


编辑:

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

标签: c++cgitcmakedependency-management

解决方案


快速更新:Hunter好像有 git 子模块模式: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)

推荐阅读