Skip to content

Cleanup CMake based build #1116

@Mizux

Description

@Mizux

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,

  1. Using some prebuilt binary

  2. Integrating the dependency source to your project and compile them along the way.

    • show stopper: CMake targets which are NOT IMPORTED must form a closure on the install export set. (see add_subdirectory() limitation below)

How to retrieve dependency Source ?

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.

  1. "regular"
ExternalProject_Add(foo_project
  PREFIX "${CMAKE_BINARY_DIR}/dependencies/foo"
  GIT_REPOSITORY ...
  GIT_TAG "..."
  CMAKE_ARGS
    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
  1. "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)

  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

Misc

Related PR

  • PR Feature/better find package #1019 find_package() everywhere, Tricks: you may have hidden add_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

Reference

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:

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)...

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions