c++ - CMake 依赖管理
问题描述
我正在寻找有关正确 CMake 依赖项管理的一些见解。我遇到过ExternalProject
,FetchContent
两者都不能完全满足我的需求。让我详细解释一下:
我的项目具有以下结构:
main_project/
├── CMakeLists.txt
├── external/
│ ├── submodule1/
│ ├── submodule2/
│ ├── submodule3/
│ .
│ .
│ .
每个submoduleN
都是一个 git 子模块,其中包含一个完整的 CMake 项目和自己的安装目标。我可以完全控制这些子模块(我编写它们)。我想使用安装目标,因为它们为子模块提供了外部接口(具有适当的命名空间等)。我不想使用内部构建目标。我想用来find_package
解决依赖关系。
其次,我不想使用一些下载机制来获取和部署依赖项。我想为此使用 git 子模块,因为
- 我可以在主项目中冻结子模块版本(依赖版本管理)。
- 我可以轻松签出任何其他版本以进行调试(无需编辑文件,只需使用 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
)。
问题:
- 我不能使用
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
解决方案
快速更新: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)
推荐阅读
- filemaker - FileMaker 关于用户数据目录等的最佳实践?
- javascript - 为 javascript 设置 12 小时时间
- mysql - 如何选择出现在两个表中的实体的总和
- javascript - 弹出警报后立即消失
- c# - 用逗号打印偶数,除了 C# 中的最后一个不工作
- android - 如何在不按返回按钮和关闭按钮的情况下将数据从第二个活动传递到第一个(弹出窗口)?
- gitlab - 发布到组的 gitlab pypi 包注册表
- python - 如何将带有 pip 文件的文件夹配置为本地 pip 存储库
- elixir - 如何更新与 Ecto 的多对多关联
- user-interface - Extjs 布局项目的顺序混乱