我正在开发一个使用第三方库的项目。我可以将这些库克隆并作为git submodule
放入我的项目,并使用add_subdirectory
将其用于我的项目。但编译这些库需要很长时间,我无法在自己的项目中管理cmake
变量,install()
命令会使我的软件包包含许多我不需要的东西。
那么,在我的项目中正确使用第三方库的方法是什么呢?我无法要求客户安装这些库作为我的项目依赖项。
情况1:
Foo
已经使用了 CMake情况2:
Foo
没有使用 CMakeFoo
的维护者愿意转换到 CMake(或至少与他们当前的构建系统并存)情况3:
Foo
没有使用 CMakeFoo
的维护者不想转换到 CMake情况4:
(1) 库 Foo
没有使用 CMake
(2) Foo
的维护者不想(或尚未准备)转换到 CMake。
(3) 当前的构建系统不太好用,或者库在更广泛的编译器范围内很难构建,或者不支持交叉编译
行动:创建一个名为 foo-cmake-buildsystem
的项目(最好在 GitHub 上),允许通过以下方式之一构建库:
python-cmake-buildsystem
的项目情况5:
Foo
的维护者不想转换,或者无法维护替代构建系统,或者库已经可用于系统中FindFoo.cmake
,以创建导入目标。
FindOpenSSL.cmake
、FindGit.cmake
等都是如此要了解有关config-file包的更多信息,请参见https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html。
如果库Foo
:
那么,ExternalProject
CMake模块将允许您从自己的项目中下载、配置、构建...这些项目。
有几种方法可以实现这一点。
以下是一个工作良好的方法:您可以设置一个我们称之为SuperBuild
的2级构建系统。
为了支持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_link_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-build
和AwesomeProject-build
是两个独立的构建树,它们之间的链接是上述讨论的配置文件包。-Foo_DIR: PATH = $ {CMAKE_BINARY_DIR} / Foo-build
来配置AwesomeProject
子项目,并调用find_package(Foo REQUIRED)
,实现了这一点。