gpt4 book ai didi

cmake - 在cmake项目中使用第三方库的正确方法

转载 作者:行者123 更新时间:2023-12-01 17:52:27 26 4
gpt4 key购买 nike

我正在研究使用某些第三方库的项目。我可以克隆它们并将它们作为git submodule放入我的项目中,并使用add_subdirectory在我的项目中使用它们。但是编译这些库需要花费很多时间,而且我无法在项目中管理cmake变量,而install()命令使我的程序包包含了许多我不需要的东西。

那么在我的项目中使用第三方库的正确方法是什么。我不能告诉客户端将这些库安装为我项目的依赖项。

最佳答案

回答这个问题需要涵盖几个方面,您将发现以下两个部分:

  • 配置文件包
  • ExternalProject CMake模块

  • 配置文件包
    如果要集成不在项目范围内的库,则第一步是确保所有库都提供配置文件包。
    配置文件包通常包括 FooConfig.cmakeFooConfigVersion.cmakeFooTargets.cmake之类的文件。
    一般来说,如果库 Foo已在使用CMake并已提供配置文件包,则使用 -DFoo_DIR:PATH=/path/to/build-or-install-dir/配置项目可让您从自己的项目中调用 find_package(Foo REQUIRED)。这将导入CMake目标,您可以将其链接到自己的库或可执行文件。
    现在,如果库 Foo尚未使用CMake,则有以下选项:
  • 情况1:
  • (a)库Foo已在使用CMake
  • (b),但不这样做不提供配置文件包
  • 操作:我建议改进其构建系统

  • 情况2:
  • (1)库Foo,而不是使用CMake
  • (2)和Foo的维护者愿意过渡到CMake(或至少将CMakeLists.txt与他们当前的构建系统一起使用)
  • 操作:我建议改进其构建系统

  • 情况3:
  • (1)库Foo,而不是使用CMake
  • (2)和Foo的维护者不希望过渡到CMake
  • (3),但维护者愿意从其当前的构建系统
  • 生成配置文件包
  • 操作:我建议帮助他们。例如,这是对Qt5所做的事情,现在它提供了一个配置文件包。

  • 案例4:
  • (1)库Foo,而不是使用CMake的
  • (2)和Foo的维护者不希望(或尚未准备好)过渡到CMake。
  • (3)和当前的构建系统运行不正常,或者难以使用更广泛的编译器来构建该库,或者不支持交叉编译
  • 操作:创建一个名为foo-cmake-buildsystem的项目(最好在GitHub上),该项目将允许通过以下任一方式构建库
  • 使用现有源树的路径配置项目
  • 让项目为您下载源代码
  • 例如,这是为CPython完成的。 GitHub上有一个名为python-cmake-buildsystem的项目


  • 案例5:
  • (1)出于任何原因,Foo的维护者不希望过渡,或者无法维护备用构建系统,或者系统
  • 上已经存在库
  • 操作:您可以创建一个FindFoo.cmake来创建导入的目标。
  • 这样的文件可能特定于您的项目,或者可以直接贡献给CMake
  • 例如,FindOpenSSL.cmakeFindGit.cmake,...



  • 要了解有关配置文件包的更多信息,请参见 https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html
    ExternalProject CMake模块
    如果库 Foo是:
  • (1)在系统上不可用:
  • 或无法使用软件包管理器
  • 安装
    或无法与社区维护软件包(debian,conda-forge,chocolatey等)一起使用此类软件包

  • (2)或需要为您的项目专门编译

  • 然后, ExternalProject CMake模块将允许您从自己的项目中下载,配置,构建...这些项目。
    很少有办法做到这一点。
    这是一个运行良好的系统:您可以设置一个称为我们的2级构建系统: SuperBuild
    为了支持 SuperBuild方法,您的CMakeLists.txt可以具有以下结构:
    project(AwesomeProject)

    [...]

    option(Awesome_ENABLE_EXTRA "Enable more awesome stuff" OFF)

    option(AwesomeProject_SUPERBUILD "Build ${PROJECT_NAME} and the projects it depends on." ON)

    [...]

    if(AwesomeProject_SUPERBUILD)
    include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake")
    return()
    endif()

    find_package(Foo REQUIRED)

    add_library(AwesomeLib ....)
    target_library_libraries(AwesomeLib PUBLIC Foo)

    [...]
    然后,在文件 SuperBuild.cmake中,您将大致执行以下两个调用:
    ExternalProject_Add(Foo
    GIT_REPOSITORY "git://github.com/Foo/Foo"
    GIT_TAG "123456"
    SOURCE_DIR ${CMAKE_BINARY_DIR}/Foo
    BINARY_DIR ${CMAKE_BINARY_DIR}/Foo-build
    CMAKE_CACHE_ARGS
    -DFOO_ENABLE_BAR:BOOL=1
    INSTALL_COMMAND ""
    )


    ExternalProject_Add(AwesomeProject
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
    BINARY_DIR ${CMAKE_BINARY_DIR}/AwesomeProject-build
    DOWNLOAD_COMMAND ""
    UPDATE_COMMAND ""
    CMAKE_CACHE_ARGS
    -Foo_DIR:PATH=${CMAKE_BINARY_DIR}/Foo-build
    -DAwesome_ENABLE_EXTRA:BOOL=${Awesome_ENABLE_EXTRA}
    INSTALL_COMMAND ""
    )
    这意味着您现在可以在子目录 AwesomeProject-build中找到您常用的构建树。
    注意 Foo-buildAwesomeProject-build是两个独立的构建树,它们之间的链接
    是上面讨论的配置文件包。
    这可以通过使用 AwesomeProject配置 -Foo_DIR:PATH=${CMAKE_BINARY_DIR}/Foo-build子项目来实现
    和调用 find_package(Foo REQUIRED)
    如果使用VisualStudio之类的工具,则可以打开在任何这些子目录中找到的解决方案文件。
    要了解有关外部项目的更多信息: https://cmake.org/cmake/help/latest/module/ExternalProject.html
    结论
    还有更多细节,但是我希望这将使您更好地了解可能的情况。

    关于cmake - 在cmake项目中使用第三方库的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51564251/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com