如何使用FetchContent将模块化boost构建正确地集成到我的CMake项目中?

jhkqcmku  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(154)

CMake FetchContent是一种管理构建依赖关系的好方法,它将依赖关系集成到构建中,并从源代码以及您自己的源代码构建它。
我也想用Boost来做。令我感到鼓舞的是,CMake对Boost的支持正在稳步提高。
当然,由于Boost是一个大型包,并且很少在项目中使用所有Boost库,因此将整个Boost源代码拉到自己的构建中是相当浪费的。考虑到Boost项目的模块化,使用git子模块,只获取实际使用的库的源代码会更加智能和高效,FetchContent通过其GIT_SUBMODULES选项支持这一点。
然而,这似乎并不能满足Boost库之间的依赖关系。我是否需要手动处理此问题,或者是否有更智能的解决方案?
此外,在这种情况下如何控制安装?许多Boost库都是只包含头文件的,我不希望在安装中包含头文件,因为我只在构建中使用它们。有没有办法告诉CMake我不想从我用FetchContent获取的内容中安装任何东西?
我读过克雷格Scott的书,当然也读过CMake文档,但关于这类问题的信息并不多。
但也许我在尝试一些我不该做的事。有没有其他人尝试过,可以告诉我如何正确地做?

1hdlvixo

1hdlvixo1#

我已经尝试了git子模块,ExternalProject,FetchContent和其他方法来获取依赖项(包括boost)。我现在使用vcpkg,我很满意。我没有用过柯南或斯派克,但我的印象,他们是伟大的太。因此,我建议使用包管理器。
要在manifest模式下使用vcpkg获得boost,请执行以下操作:

  • 将vcpkg添加为存储库的子模块并引导它(参见https://vcpkg.io/en/getting-started)。
  • 将包含依赖项的vcpkg.json文件添加到项目的顶层。
  • 通过设置VCPKG_CHAINLOAD_TOOLCHAIN_FILE,确保CMAKE_TOOLCHAIN_FILE设置为vcpkg工具链文件,并且您的工具链文件是链加载的(如果有)。

vcpkg.json文件可能看起来像这样:

{
  "name": "sample",
  "builtin-baseline":"030c53833b977f1580b2a4817bb22edbdde606d4",
  "version": "13.0.0",
  "dependencies": [
    "benchmark",
    "boost-asio",
    "boost-container",
    "boost-date-time",
    "boost-filesystem",
    "boost-histogram",
    "boost-thread"       
  ]
}

字符串
CMakePresets.json可能看起来像这样(如果你没有使用CMakePresets.json文件,你将需要调整你用来控制工具链文件的任何东西):

{
    "version": 3,
    "configurePresets": [
        {
            "name": "sample-defaults",
            "hidden": true,
            "binaryDir": "${sourceParentDir}/build/${sourceDirName}-${presetName}",
            "cacheVariables": {
                "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
                "VCPKG_CHAINLOAD_TOOLCHAIN_FILE": "${sourceDir}/scripts/clang17.cmake"
            }
        },
        ...


然后你只需要在你的CMakeLists.txt中输入find_package()

cmake_minimum_required(VERSION 3.21)

project(
    Sample-ThirdParty
    LANGUAGES CXX
    VERSION 2023.0.0
)

find_package(Boost REQUIRED COMPONENTS container filesystem thread)
...


无可否认,以下内容(来自@sehe提供的链接)似乎效果不错:

cmake_minimum_required(VERSION 3.21)
project(boost_test)
include(FetchContent)
set(BOOST_ENABLE_CMAKE ON)
FetchContent_Declare(build_boost
     GIT_REPOSITORY https://github.com/boostorg/boost.git
     GIT_TAG boost-1.82.0
)
FetchContent_GetProperties(build_boost)
if(NOT build_boost_POPULATED)
     FetchContent_Populate(build_boost)
     add_subdirectory(
         ${build_boost_SOURCE_DIR}
         ${build_boost_BINARY_DIR}
         EXCLUDE_FROM_ALL
     )
endif()
add_executable(boost_test boost_test.cpp)
target_link_libraries(boost_test PRIVATE Boost::format)


但是,我不认为我会回到使用FetchContent。现在我们已经为我们的项目设置了vcpkg,这意味着我们可以尝试新的依赖关系。我喜欢在一个位置记录依赖关系。它还使CMakeLists.txt文件尽可能简单。
我意识到我现在有一个额外的依赖项,那就是vcpkg。然而,我的观点是,vcpkg的维护者提供的价值比我管理vcpkg的成本更大。他们提供的一些东西:

  • 对静态链接等设置的统一控制。
  • 良好的项目默认值(例如NLopt默认为其他几种语言构建绑定,但这些都是禁用的)。
  • 可传递依赖关系。
  • 测试库之间的兼容性。

相关问题