ima*_*age 9 c c++ git cmake dependency-management
我正在寻找有关正确 CMake 依赖管理的一些见解。我遇到过ExternalProject和FetchContent,两者都不能完全满足我的需求。我来详细解释一下:
我的项目具有以下结构:
\nmain_project/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 external/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 submodule1/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 submodule2/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 submodule3/\n\xe2\x94\x82 .\n\xe2\x94\x82 .\n\xe2\x94\x82 .\nRun Code Online (Sandbox Code Playgroud)\n每个submoduleN都是一个 git 子模块,其中包含一个完整的 CMake 项目及其自己的安装目标。我可以完全控制这些子模块(我编写它们)。我想使用安装目标,因为它们为子模块提供外部接口(具有适当的命名空间等)。我不想使用内部构建目标。我想用它find_package来解决依赖关系。
其次,我不想使用某些下载机制来获取和部署依赖项。我想为此使用 git 子模块,因为
\n假设每个submoduleN都有自己的、相似的子结构,并且它们可能在内部相互依赖。如果他们碰巧有共享依赖项,我希望他们使用单一的通用版本。主项目中的层次结构优先选择版本。例如,类似于FetchContent\ 的 populate 习语:
FetchContent_GetProperties(mylib)\nif(NOT mylib_POPULATED)\n FetchContent_Populate(mylib)\n # do build, install and other stuff\nendif()\nRun Code Online (Sandbox Code Playgroud)\n我希望安装目标可以在配置步骤(即find_package)中使用,并且如果我编辑它们(即在其中应用一些调试更改),我希望重建它们submoduleN。
问题:
\nExternalProject_Add因为它仅在构建阶段可用。FetchContent因为它忽略安装目标(甚至不构建它们)。FetchContent,因为会有重复的目标名称(doc、main、tests 等)。我知道Hunter++,它几乎解决了我的问题,除了 gitsubmodule 和无下载部分。我用 做了一个部分工作的示例ExternalProject,但我发现它非常混乱,并且它不能解决常见的版本问题:
\n https://github.com/image357/cmake_tutorial_external
有任何想法吗?
\n编辑:
\n我刚刚在 CMake 上发现了类似的提案:
\n 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)
Run Code Online (Sandbox Code Playgroud)
将其添加cmake/Hunter/config.cmake到您的项目中:
hunter_config(mysubmodule_lib GIT_SUBMODULE your/path/to/mysubmodule_lib VERSION 1.2.3)
Run Code Online (Sandbox Code Playgroud)