Boost logo

Boost-Build :

Subject: [Boost-build] Generating CMake package files using Boost.Build
From: Stephen Kelly (hello_at_[hidden])
Date: 2015-11-17 16:49:56


Hello,

For CMake users, the most convenient way to consume a library is if the
library provides 'package configuration files' which contain imported
targets. Those files are somewhat similar in concept to pkg-config files in
that they specify flags that consumers should use, but the files use the
cmake language and are designed to be consumed only by cmake.

CMake has commands to allow CMake-based buildsystems to easily
export/generate and install such files. As the files are just plain text,
non-CMake buildsystems, can also generate the files so that downstreams
which use CMake get the convenience, without upstream having to depend on
CMake. This is the case with Qt 5, which uses qmake to build, and to
generate CMake files. It is also the case with the LLVM Makefiles
buildsystem which generates CMake package configuration files.

It could be done for Boost.Build too. This has been raised on the Boost
mailing list several times:

* http://boost.2283326.n4.nabble.com/boost-config-context-log-1-58-address-model-and-architecture-detection-td4674125i20.html#a4674266

* http://boost.2283326.n4.nabble.com/Status-of-the-CMake-ification-tp4681599p4681607.html

* http://boost.2283326.n4.nabble.com/boost-config-context-log-1-58-address-model-and-architecture-detection-td4674125i40.html#a4674780

Let's talk about whether it is plausible and what it would mean for users.

The task is for Boost.Build to generate files following a naming convention
of

 Boost<LibName>Config.cmake'

and install them to

 <install-prefix>/share/cmake

Generating files which work for a build of Boost (before or without
installing) would also not be a problem.

Such a 'config file' would be generated for each static library built by the
build of boost, and one extra config file to represent header-only files
shipped with Boost.

[Aside: Let's not let this discussion become about modularization. Let's
create a solution that can be deployed with Boost as it is organized today]

The generated config file would contain cmake code such as

 add_library(boost::log STATIC IMPORTED)
 set_property(TARGET boost::log
   PROPERTY LOCATION @THE_LOCATION@)
 set_property(TARGET boost::log
   PROPERTY INTERFACE_LINK_LIBRARIES @THE_DEPS@)

where @THE_LOCATION@ and @THE_DEPS@ are determined by Boost.Build and
written into the generated file.

With that as a starting point, we can also generate usage requirements such
as include directories, defines and compile flags which the user must use
when linking against the boost library (as a result of how the boost library
is built). We can also generate 'compatibility requirements' so that
attempting to use libraries which have conflicting usage requirements
results in an error at cmake time instead of link time.

The user then writes something like

 cmake_minimum_required(VERSION 3.0)
 project(MyProject)

 # CMake finds the BoostLogConfig.cmake file
 find_package(BoostLog REQUIRED)
 find_package(BoostSystem REQUIRED)

 add_executable(myexe main.cpp)
 target_link_libraries(myexe
   boost::log
   boost::system
 )

It is also possible to generate an 'umbrella' config package so that the
user can instead use

 find_package(Boost REQUIRED COMPONENTS Log System)

I think a possible TODO list of where to go from here could be

* Create a branch to work on where prototyping can be done
* Generate and install basic config files
* Add features for transitive dependencies and usage requirements
* Find out how packaging and boost releasing system needs to handle the
presence of the new files
* Find out whether to enable the generated files for all libraries in boost
which create binaries to link to, or somehow make it configurable/opt in.
* Rebase/merge the branch

What do you think?

Thanks,

Steve.


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk