使用的cmake中的项目的第三方库的正确方法使用的cmake中的项目的第三方库的正确方法(Corre

2019-05-12 09:11发布

我正在使用一些第三方库项目。 我可以克隆,并把它们放到我的项目作为一个git submodule ,并使用add_subdirectory在我的项目中使用它们。 但它需要很多时间来编译这些库,我不能管理cmake在我的项目变量和install()命令让我的包中,我并不需要很多东西。

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

Answer 1:

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

  • 配置文件包
  • 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:

    • (一)库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)和当前的构建系统都不尽如人意,或文库是很难建立与一个更宽范围的编译器中,或者不支持交叉编译
    • 操作 :创建一个项目(最好在GitHub上)命名为foo-cmake-buildsystem ,将允许建立由要么库

      • 配置与路径的项目,以现有的源代码树
      • 具有项目下载源代码给你
      • 这是例如用于CPython的实现。 有一个名为项目python-cmake-buildsystem GitHub上可用
  • 案例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的,畅达锻,巧克力味,...)有这样的包是不可能的*(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

结论

还有更多的细节,但我希望这将让你更好地了解什么是可能的。



文章来源: Correct way to use third-party libraries in cmake project