Hi all,
the recent activity regarding adding CMake support to some remaining
libraries (many thanks go to Peter Dimov), encouraged me to try using
FetchContent to integrate Boost into client projects. I'm sure many
people are interested in such a possibility in order to reduce
dependencies on the build environment.
The brief result seems to be: It almost works. Enough to make it
interesting.
The reason for my message is to ask if this is supposed to work, i.e. if
I am trying something that should work, either now or in the near
future, or if it is a frivolous expectation on my part.
A toy project's CMakeLists.txt might look like this:
=============================================================
cmake_minimum_required(VERSION 3.21)
project(boost_test)
include(FetchContent)
set(BOOST_ENABLE_CMAKE ON)
FetchContent_Declare(build_boost
GIT_REPOSITORY https://github.com/boostorg/boost.git
GIT_TAG boost-1.77.0.beta1
)
FetchContent_GetProperties(build_boost)
if(NOT build_boost_POPULATED)
FetchContent_Populate(build_boost)
add_subdirectory(
${build_boost_SOURCE_DIR}
${build_boost_BINARY_DIR}
EXCLUDE_FROM_ALL
)
endif()
add_executable(boost_test boost_test.cpp)
target_link_libraries(boost_test PRIVATE Boost::format)
=============================================================
The corresponding source file would look like this:
=============================================================
#include
#include <iostream>
int main() {
std::cout << boost::format("Hello %1%!") % "everybody";
}
=============================================================
I used the CMake GUI version 3.21.0 on Windows 10 to configure the
project for Visual Studio 2019 Release 16.10.3 with a 64-bit build. It
produced lots of install-related errors in the generation phase, but
it nevertheless pruduced a solution that successfully built the project.
Now, there are of course a couple of issues, which I'd like to get your
opinion on:
1. Optimized source download
As listed, FetchContent pulls in the entire boost sources, regardless
whether they're needed or not. This takes a significant amount of time
and uses a lot of disk space for no benefit. Clearly, you would want to
fetch only the sources you need, but there doesn't seem to be a good way
to handle the dependencies between the various boost libraries.
You could use the GIT_SUBMODULES option of FetchContent, but you'd need
to list not only the libraries you directly use (Boost::format in my
example above), but you also need to list the dependencies of those,
which is tedious and brittle.
I imagine that this can be handled via a special tool that gets invoked
as a PATCH_COMMAND, which is able to scan through the submodules that
have been populated and populates all its dependencies. I haven't seen
such a tool anywhere, but maybe somebody has got a solution already?
2. Dealing with install
Obviously, when using Boost like this, I don't want it to add
installation items into the install of my own project, therefore I used
the option EXCLUDE_FROM_ALL of add_subdirectory(). That doesn't
eliminate all of the problems, as is evidenced by the myriad
install-related errors that CMake flags up. Do you have an idea how to
properly deal with that? I'm slightly out of my depth here.
If you want to check this on your system, the CMake errors may prevent
building. I have been able to build when generating a Visual Studio
solution, but not when I openend the folder in Visual Studio directly,
relying on Visual Studio's own CMake support.
Of couse, if you have other suggestions, please tell!
Cheers
Stefan Heinzmann