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
to use them in my project. But it take much time to compile these libs, and I can not manage cmake
variables in my projects, and install()
command make my package contains many things that I don't need.
So what is correct way to use third-party libraries in my project. I can not tell the client to install these libraries as dependencies of my project.
Add a subdirectory to the build. Adds a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.
Since CLion relies on CMake build system, you can do this with CMake commands. To add libraries to your project, use find_package (if you use separate libraries, for example, installed in the system) and target_link_libraries CMake commands.
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:
(1) library Foo
is not using CMake
(2) and maintainer of Foo
do not want (or are not ready) to transition to CMake.
(3) and the current build system is not working well, or the library is difficult to build with a wider range of compiler, or does not support cross-compilation
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With