I\'m working on project that use some third-party libraries. I can clone and put them into my project as a git submodule
and use add_subdirectory
t
Answering this question requires to cover few aspects, you will find below two sections:
If you are looking into integrating libraries that are not built within the scope of your project, the first step is to make sure the libraries all provide a config-file package.
A config-file package usually include files like FooConfig.cmake
, FooConfigVersion.cmake
and FooTargets.cmake
.
Generally speaking, if the library Foo
is already using CMake and already provide a config-file package, configuring your project with -DFoo_DIR:PATH=/path/to/build-or-install-dir/
allow you to call find_package(Foo REQUIRED)
from your own project. This will import CMake targets that you can link against your own libraries or executables.
Now if the library Foo
is not already using CMake, there are options:
Case 1:
Foo
is already using CMakeCase 2:
Foo
is not using CMakeFoo
are willing to transition to CMake (or at least have the CMakeLists.txt
along side their current build system)Case 3:
Foo
is not using CMakeFoo
do not want to transition to CMakeCase 4:
Foo
is not using CMakeFoo
do not want (or are not ready) to transition to CMake. action: create a project (ideally on GitHub) named foo-cmake-buildsystem
that will allow to build the library by either
python-cmake-buildsystem
available on GitHubCase 5:
Foo
do not want to transition, or maintaining an alternative build system is not possible, or library is already available on the systemFindFoo.cmake
that would create imported targets.
FindOpenSSL.cmake
, FindGit.cmake
, ... To learn more about config-file package, see https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html
If the library Foo
is:
* (1) not available on the system:
* or can't be installed using package manager
* or working with the community maintaining packages (debian, conda-forge, chocolatey, ...) to have such package is not possible
* (2) or need to be compiled specially for your project
Then, the ExternalProject
CMake module will allow you to download, configure, build ... these projects from within your own project.
There are few approaches to make this happen.
Here is one that has been working well: You could setup a 2-level build system that we call: SuperBuild
.
To support the SuperBuild
approach, your CMakeLists.txt could have the following structure:
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)
[...]
Then, in the file SuperBuild.cmake
you would roughly have these two calls:
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 ""
)
This means that you usual build tree will now be found in the subdirectory AwesomeProject-build
.
Note that Foo-build
and AwesomeProject-build
are two independent build tree, the link between them
is the config-file package discussed above.
This is made possible by configuring AwesomeProject
sub project with -Foo_DIR:PATH=${CMAKE_BINARY_DIR}/Foo-build
and the calling find_package(Foo REQUIRED)
.
If you use tools like VisualStudio you can open the solution file found in any of these sub-directory.
To learn more about external project: https://cmake.org/cmake/help/latest/module/ExternalProject.html
There are many more details, but I hope this will allow you to get a better understanding of what is possible.