-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
Introduction
All CMakeLists.txt need a deep refactoring about the dependencies management.
Quick Survey
Prebuilt vs Sources
There is two main way to consume a dependency,
-
Using some prebuilt binary
-
Integrating the dependency source to your project and compile them along the way.
- show stopper: CMake targets which are NOT
IMPORTEDmust form a closure on the install export set. (seeadd_subdirectory()limitation below)
- show stopper: CMake targets which are NOT
How to retrieve dependency Source ?
- using git submodules
- using CMake (>= 3.11.4) FetchContent module
- using the famous ExternalProjectAdd "submodule hack" (see gtest doc)
How to retrieve Prebuilt
- Using the canonical way aka
find_package()and it's the user responsibility to provide them... - using ExternalProject_add ("regular") to build them.
cons: do at build time not access to project stuff e.g. config.cmake... - using ExternalProject_add "prebuilt hack" to compile/install deps in staging area then continue as regular
find_package()
see: https://github.com/Mizux/cmake-abseil/tree/install
Three shades of ExternalProject usage
AFAIK there is three way to use CMake ExternalProject module.
- "regular"
ExternalProject_Add(foo_project
PREFIX "${CMAKE_BINARY_DIR}/dependencies/foo"
GIT_REPOSITORY ...
GIT_TAG "..."
CMAKE_ARGS
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}-
"submodule hack" like gtest doc
see https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
(ed notice the configure/build/install command set to empty string -> only the "download/update step is performed") like a git submodule (aka Strategy 2) -
"prebuilt hack" like "submobule hack" BUT build/install it in a staging area and add this staging to CMAKE_PREFIX_PATH
example: https://github.com/Mizux/cmake-abseil/tree/install
Roadmap
- Rework CMakeLists.txt in few Dependencies
- https://github.com/abseil/abseil-cpp (most on abseil-cpp HEAD)
- Split Cbc to follow new coin-or github layout (bye bye svn archive !)
- Move old Mizux/Cbc to Mizux/coinor-cbc and archive it.
- Add CMake support for each libraries (bye bye autotools)
- https://github.com/Mizux/CoinUtils
- https://github.com/Mizux/Osi
- https://github.com/Mizux/Clp
- https://github.com/Mizux/Cgl
- https://github.com/Mizux/Cbc
- Rework Dependencies management (
install/find_package()overadd_subdirectory())- see below for explanation why
add_subdirectory()doesn't work...
- see below for explanation why
Misc
Related PR
- PR Feature/better find package #1019
find_package()everywhere, Tricks: you may have hiddenadd_subdirectory()inside FindFoo.cmake- nice trick since it will make the super build seen as a regular project
- you can control what you want by CMAKE_PREFIX_PATH (i.e. find your custom FindFoo.cmake or the one in the system (good for distro maintainer))
Related issues
- Missing install rule in abseil-cpp see: Step 6: Allow Abseil to be installed and used with find_package() abseil/abseil-cpp#111
- CMake build support future #732 CMake build support future
- CMake: install target not working: fails: file INSTALL cannot find absl-config.cmake #1025 CMake install rule not working
- Building or-tools 7.0 from Cmake error #1159 OR-Tools CMake error
- cbc.CMakeLists.txt should point to a version in or-tools releases #1169 OR-Tools Cbc sha1
- Dependencies issues when building or-tools 7.0 from Cmake error #1167 cbc -> coinor-cbc
- configure script has issue when pwd contains spaces coin-or/CoinUtils#87 : Autotools does not support space in path and thus coin-or libraries too
Reference
- Don't package your libraries, write packagable libraries! by Robert Schumacher
youtube: https://youtu.be/sBP17HQAQjk
add_subdirectory() limitation
If you see this kind error
CMake Error: install(EXPORT "MyLibTargets" ...) includes target "MyLib" which requires target "deps" that is not in the export set.
Bravo ! you just figure out the limitation of add_subdirectory() vs regular cmake install dependencies ;)
add_subdirectory() add dependency targets not as IMPORTED targets so your export set must contains them (think of a graph closure of all target not imported) which you can't do unless hacking dependency source to modify the export set name...
note: bear in mind that until CMake 3.13, you can't add target to your super project export set.
The install(TARGETS) command learned to install targets created outside the current directory.
src: https://cmake.org/cmake/help/v3.13/release/3.13.html#commands
note: simpler example here: https://github.com/Mizux/cmake-abseil
Coin-OR integration
long story: coin-Cbc was on svn and I created the repo Mizux/cbc based on their "mono-repo" svn archive, then I added a CMake-based build.
Now, coin-OR use a one repo per library approach, you can see on github they have split coin-or in several repo, so I moved it to mizux/coinor-cbc in order to fork coinor/Cbc to add (again) a CMake-Based build.
Here the list of my fork:
- https://github.com/Mizux/CoinUtils
- https://github.com/Mizux/Osi
- https://github.com/Mizux/Clp
- https://github.com/Mizux/Cgl
- https://github.com/Mizux/Cbc
Hope to soon send PR to coin-or maintainer, CMake patches/improvement are welcome !
warning: until I would consider my CMake integration "Stable/good enough" I'll heavily use rebase/fixup on my branch to keep an atomic final CMake single patch, which mean don't rely on SHA1 until release (i.e. PR is sent to coin-or)...