How to Build Boost with Cmake

Is it possible to build Boost with CMake?

We've struggled with this a fair bit too at my workplace. While I certainly can't claim to know the "best" way, I can offer the following thoughts on my experiences.

We initially just required devs to install boost separately and had CMake do its normal checks in the form of a find_package(Boost...) call. This was easy, but not automated, and caused problems for devs with older versions of boost already installed.

We then changed tack and added a copy of the boost sources which we cloned from one of the projects you mentioned above. I can't recall the specifics, but I think it was a precursor to the one currently being worked on in the Ryppl project. The main point was that it already had support for CMake; the boost libraries were actual CMake targets added via add_library calls, which made them easier to work with in the CMake code.

While this solved the previous problems by automating the use of boost in our project, it ultimately became a maintenance nightmare. The boost project we had cloned from changed radically and is now very dependent on Ryppl-specific CMake functions. We didn't want to add Ryppl as a dependency, so we changed tack again!

We looked at the projects you mentioned in your question, and likewise found none of them to be usable.

Our current setup makes use of CMake's ExternalProject module. This allows us to download and build boost to our build tree.

Advantages:

  • Low maintenance
  • Automated, so all devs use the same version built with the same flags
  • Keeps our own source tree free from third-party code
  • Multiple copies of boost can happily co-exist (so no chance of accidentally linking to a copy built with a different compiler/stdlib combination)

Disadvantages

  • Deleting your build tree means having to download and build boost from scratch. This could be ameliorated by e.g. downloading to a fixed location (say, system temp dir), so the download/unzip step could be skipped if an existing copy of the boost sources is found.
  • The boost libraries are not proper CMake targets (i.e. they haven't been added via add_library calls)

Here's a link to our CMake code. There are a few ways in which this needs improved, but it currently works reasonably well for us.

I hope that soon this answer becomes out of date and a decent, modularised, CMake-compatible solution becomes available.

Adding Boost to CMake project?

Following recipe should work

Download Boost binaries from official boost binaries location and install to say C:\Boost

Most times you do not need to build Boost on your own.

Your CMakeLists.txt should look like follows

cmake_minimum_required (VERSION 3.8)

project(boostAndCMake)

set(BOOST_ROOT "C:\Boost") # either set it here or from the command line
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED COMPONENTS system) # header only libraries must not be added here

add_executable(CMakeProject2 CMakeProject2.cpp CMakeProject2.h)
target_include_directories(CMakeProject2 PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(CMakeProject2 ${Boost_LIBRARIES})

Because we used REQUIRED on the find_package call, CMake will fail execution and skip the rest of the script if it cannot be found. So no need to check Boost_FOUND. You need to check it, when you omit REQUIRED.

Now from the command line call from the directory where your script resides:

cmake -H. -Bbuildit -G "Visual Studio 15 2017" -DBOOST_ROOT=C:\Boost 

This creates a build directory named buildit in the current directory, further creates a solution for Visual Studio 2017 inside the build directory and provides the setting for the variable BOOST_ROOT that is used in the find_package call to identify the Boost directory on your computer. To see what options are available on the find_package(Boost ...) call see FindBoost documentation in CMake.

Header Only Libraries

If your libraries are header only you need to omit them from the find_package(Boost ...) call. To see which libraries are not header only see this post.

Using newer Boost versions

If your CMake installation cannot find the requested version, e.g. 1.69.0, but supports the naming scheme of the more recent Boost version you can use it with set(Boost_ADDITIONAL_VERSIONS "1.69.0" "1.69"). Last change of the Boost naming scheme was from 1.65.1 to 1.66.

Include Boost build with clang CMake

I managed to link boost with this code thanks to drescherjm and vre.

This code is not universal, and depends on how you build boost. Variable after BOOST_ROOT may differ.

cmake_minimum_required (VERSION 3.19)

set(BOOST_ROOT "E:/boost_1_74_0/stage")
set(Boost_USE_STATIC_RUNTIME FALSE)
set(Boost_USE_STATIC_LIBS TRUE)
set(Boost_USE_MULTITHREADED TRUE)
set(THREAD_LIBRARY_DEBUG TRUE)
set(Boost_USE_DEBUG_RUNTIME FALSE)
set(Boost_COMPILER "-clang11")

find_package(Boost COMPONENTS system)

if(NOT Boost_FOUND)
message(FATAL_ERROR "Boost Not found")
endif()

include_directories (${Boost_INCLUDE_DIR})

add_executable (main "src/main/main.cpp")

target_include_directories(main PUBLIC ${Boost_INCLUDE_DIRS})

target_link_libraries(main ${Boost_LIBRARIES})

How to build boost libraries using cmake

I guess this is not possible unless you decide to make your own CMakeLists.txt.

I just went with b2 in my case as cmake was not a fixed requirement.

HelloWorld: downloading, building and linking Boost using CMake

I will attempt to give you some hints, to try to answer your questions.

1) With this snippet you should be able to have sources and built files in the right directories. I kept TMP_DIR "${Cmaketest_SOURCE_DIR}/temp" but in my project I don't use that line.

ExternalProject_Add(Boost
TMP_DIR "${Cmaketest_SOURCE_DIR}/temp"
DOWNLOAD_DIR "${Cmaketest_SOURCE_DIR}/downloads"
URL "${Cmaketest_SOURCE_DIR}/downloads/boost_1_63_0.zip"
URL_HASH "SHA1=${Boost_Sha1}"
SOURCE_DIR ${Cmaketest_SOURCE_DIR}/downloads/boost_1_63_0
BUILD_IN_SOURCE 1
UPDATE_COMMAND ""
PATCH_COMMAND ""
CONFIGURE_COMMAND ${Boost_Bootstrap_Command} --without-icu --with_libraries=${Config_Libraries}
BUILD_COMMAND ${Boost_b2_Command}
--prefix="${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0"
--without-python
--address-model=64
--architecture=x64
--threading=multi
--link=static
--variant=release
--layout=tagged
--build-type=complete
-j${N}
INSTALL_COMMAND ${Boost_b2_Command} --prefix="${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0" --without-python
--address-model=64
--architecture=x64
--threading=multi
--link=static
--variant=release
--layout=tagged
--build-type=complete
-j${N} install
INSTALL_DIR "${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0"
)

set(BOOST_ROOT ${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0)
set(Boost_LIBRARY ${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0/lib)
set(Boost_INCLUDE_DIR ${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0/include)
include_directories(${Boost_INCLUDE_DIR})

To notice that you were not calling "install" so once built in that "strange" directory, the files were not moved to the specified prefix. Notice also the use of ${Cmaketest_SOURCE_DIR} instead of the previous.

Try to print both and see if there's a difference.

2) To address the warning you get in case Boost is not found, you should write:

find_package(Boost QUIET)  

3) To address this I guess you could not generate project files, i.e. instead of having

cmake build -G "Visual Studio 14 2015 Win64"  

just have cmake . or cmake .. depending whether you will do an in-source or an out-of-source build. I suggest doing out-of-source builds, but that's your choice.

4) FindBoost.cmake (FindBoost.cmake) gives you the possibility to pass an arbitrary path to a Boost directory. You could use that at configuration to hint CMake to look for Boost in the location you give, e.g. you would call cmake in the following way:

cmake -DBOOST_ROOT=/path_to_cmaketest_dir/depends/boost_1_63_0 ..  

and if your system might be picky you could specify all things:

cmake -DBOOST_ROOT=/path_to_cmaketest_dir/depends/boost_1_63_0 -DBOOST_LIBRARYDIR=/path_to_cmaketest_dir/depends/boost_1_63_0/lib DBOOST_INCLUDEDIR=/path_to_cmaketest_dir/depends/boost_1_63_0/include ..  

Notice that in the last two snippets I assumed configuration of an out-of-source build.

Also notice that if you already installed or have the Boost package downloaded, using ${Cmaketest_SOURCE_DIR} in the snipped of code in 1) should solve also 4) so when it will not find Boost it will try to download but it will not, since now cmake should be able to see the file (.zip).



Related Topics



Leave a reply



Submit