【问题标题】:CMake Dependency ManagementCMake 依赖管理
【发布时间】:2021-09-09 12:27:03
【问题描述】:

我正在寻找有关正确 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 子模块,因为

  • 我可以在主项目中冻结子模块版本(依赖版本管理)。
  • 我可以轻松签出任何其他版本以进行调试(无需编辑文件,只需使用 git 并准备好完整的提交消息以供参考)。

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

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

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

问题:

  • 我不能使用ExternalProject_Add,因为它只在构建阶段可用。
  • 我不能使用FetchContent,因为它会忽略安装目标(甚至不构建它们)。
  • 我不能使用FetchContent,因为会有重复的目标名称(doc、main、tests 等)。

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

有什么想法吗?


编辑:

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

【问题讨论】:

  • FWIW,在这些情况下,我所做的是将带有 CMAKE_INSTALL_PREFIX 的依赖项构建到本地目录,并在构建根项目时将该目录添加到 CMAKE_PREFIX_PATH。这确实意味着构建是一个两阶段的过程,但它最终要干净得多。
  • 这是一个很棒的问题,它指出了 CMake 中的依赖管理故事中的一些严重问题。我对此有一些想法,我会尝试将它们组合成一个答案。
  • 您绝对需要阅读原始问题 #17735(参考问题 21687)

标签: c++ c git cmake dependency-management


【解决方案1】:

快速更新: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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 2011-03-13
    • 2013-06-15
    • 2011-11-24
    • 2010-09-13
    相关资源
    最近更新 更多