164

I need to add Boost libraries into my CMakeLists.txt. How do you do it or how do you add it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
laksh
  • 2,209
  • 6
  • 21
  • 25
  • See official documentation [here](https://cmake.org/cmake/help/v3.0/module/FindBoost.html) –  Jan 15 '19 at 00:51

8 Answers8

194

Put this in your CMakeLists.txt file (change any options from OFF to ON if you want):

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
find_package(Boost 1.45.0 COMPONENTS *boost libraries here*) 

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS}) 
    add_executable(progname file1.cxx file2.cxx) 
    target_link_libraries(progname ${Boost_LIBRARIES})
endif()

Obviously you need to put the libraries you want where I put *boost libraries here*. For example, if you're using the filesystem and regex library you'd write:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)
xuhdev
  • 8,018
  • 2
  • 41
  • 69
LainIwakura
  • 2,871
  • 2
  • 19
  • 22
  • 4
    Note that you don't need to specify components for header only libraries, such as `lexical_cast`. Thus you only need the `find_package` and `include_directories` command. – miguel.martin May 13 '15 at 13:13
  • 1
    On Windows, it can also help to add this to your cmake file: ADD_DEFINITIONS( -DBOOST_ALL_NO_LIB ) otherwise you may run into http://stackoverflow.com/questions/28887680/linking-boost-library-with-boost-use-static-lib-off-on-windows – Stéphane Jul 22 '15 at 16:08
  • is it possible to set BOOST_USE_STATIC_LIBS to ON and Boost_USE_STATIC_RUNTIME OFF? & vice verse. – squid Aug 21 '15 at 07:00
  • 6
    What does `*boost libraries here*` mean? – IgorGanapolsky May 26 '16 at 18:23
  • 3
    You can also use `FIND_PACKAGE(Boost REQUIRED COMPONENTS system)` if you don't know the exact version of boost to use – smac89 Aug 17 '17 at 06:39
  • You can also hard code ${Boost_LIBRARIES} (e.g. Boost::fiber) – Guillaume Aug 11 '21 at 15:21
  • @squid I just had this problem.. CMake was linking in the "dynamic" lib, I wanted the static libboost. Found the solution [here](https://stackoverflow.com/questions/3176035/link-the-static-versions-of-the-boost-libraries-using-cmake), I needed to `set(Boost_USE_STATIC_LIBS ON)` – yano Oct 29 '22 at 19:44
91

You can use find_package to search for available boost libraries. It defers searching for Boost to FindBoost.cmake, which is default installed with CMake.

Upon finding Boost, the find_package() call will have filled many variables (check the reference for FindBoost.cmake). Among these are BOOST_INCLUDE_DIRS, Boost_LIBRARIES and Boost_XXX_LIBRARY variabels, with XXX replaced with specific Boost libraries. You can use these to specify include_directories and target_link_libraries.

For example, suppose you would need boost::program_options and boost::regex, you would do something like:

find_package( Boost REQUIRED COMPONENTS program_options regex )
include_directories( ${Boost_INCLUDE_DIRS} )
add_executable( run main.cpp ) # Example application based on main.cpp

# Alternatively you could use ${Boost_LIBRARIES} here.
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )

Some general tips:

  • When searching, FindBoost checks the environment variable $ENV{BOOST_ROOT}. You can set this variable before calling find_package if necessary.
  • When you have multiple build-versions of boost (multi-threaded, static, shared, etc.) you can specify you desired configuration before calling find_package. Do this by setting some of the following variables to On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED, Boost_USE_STATIC_RUNTIME
  • When searching for Boost on Windows, take care with the auto-linking. Read the "NOTE for Visual Studio Users" in the reference.
    • My advice is to disable auto-linking and use cmake's dependency handling: add_definitions( -DBOOST_ALL_NO_LIB )
    • In some cases, you may need to explicitly specify that a dynamic Boost is used: add_definitions( -DBOOST_ALL_DYN_LINK )
starball
  • 20,030
  • 7
  • 43
  • 238
André
  • 18,348
  • 6
  • 60
  • 74
29

Adapting @LainIwakura's answer for modern CMake syntax with imported targets, this would be:

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
find_package(Boost 1.45.0 COMPONENTS filesystem regex) 

if(Boost_FOUND)
    add_executable(progname file1.cxx file2.cxx) 
    target_link_libraries(progname Boost::filesystem Boost::regex)
endif()

Note that it is not necessary anymore to specify the include directories manually, since it is already taken care of through the imported targets Boost::filesystem and Boost::regex.
regex and filesystem can be replaced by any boost libraries you need.

oLen
  • 5,177
  • 1
  • 32
  • 48
  • 1
    How would this look if you wanted to say to link against all of boost? I mean without listing all libraries there are in boost. – levzettelin Jul 22 '17 at 18:16
  • 6
    If you only use header-only parts of boost, 'Boost::boost' will be sufficient. All compiled boost libraries must be specified explicitly. – oLen Jul 22 '17 at 19:41
  • 3
    @oLen Where do I find a list of all imported cmake Boost::* targets? How do I know to which I have to link to? – Markus Aug 10 '18 at 08:47
9

May this could helpful for some people. I had a naughty error: undefined reference to symbol '_ZN5boost6system15system_categoryEv' //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: error adding symbols: DSO missing from command line There were some issue of cmakeList.txt and somehow I was missing to explicitly include the "system" and "filesystem" libraries. So, I wrote these lines in CMakeLists.txt

These lines are written at the beginning before creating the executable of the project, as at this stage we don't need to link boost library to our project executable.

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
set(Boost_NO_SYSTEM_PATHS TRUE) 

if (Boost_NO_SYSTEM_PATHS)
  set(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../3p/boost")
  set(BOOST_INCLUDE_DIRS "${BOOST_ROOT}/include")
  set(BOOST_LIBRARY_DIRS "${BOOST_ROOT}/lib")
endif (Boost_NO_SYSTEM_PATHS)


find_package(Boost COMPONENTS regex date_time system filesystem thread graph program_options) 

find_package(Boost REQUIRED regex date_time system filesystem thread graph program_options)
find_package(Boost COMPONENTS program_options REQUIRED)

Now at the end of the file, I wrote these lines by considering "KeyPointEvaluation" as my project executable.

if(Boost_FOUND)
    include_directories(${BOOST_INCLUDE_DIRS})
    link_directories(${Boost_LIBRARY_DIRS})
    add_definitions(${Boost_DEFINITIONS})

    include_directories(${Boost_INCLUDE_DIRS})  
    target_link_libraries(KeyPointEvaluation ${Boost_LIBRARIES})
    target_link_libraries( KeyPointEvaluation ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY})
endif()
Tanmoy Mondal
  • 449
  • 1
  • 6
  • 12
4

Try as saying Boost documentation:

set(Boost_USE_STATIC_LIBS        ON)  # only find static libs
set(Boost_USE_DEBUG_LIBS         OFF) # ignore debug libs and 
set(Boost_USE_RELEASE_LIBS       ON)  # only find release libs 
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF) 
find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...)
if(Boost_FOUND)   
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(foo foo.cc)   
    target_link_libraries(foo ${Boost_LIBRARIES})
endif()

Don't forget to replace foo to your project name and components to yours!

Nikolay Pakudin
  • 630
  • 6
  • 12
2

I agree with the answers 1 and 2. However, I prefer to specify each library separately. This makes the depencencies clearer in big projects. Yet, there is the danger of mistyping the (case-sensitive) variable names. In that case there is no direct cmake error but some undefined references linker issues later on, which may take some time to resolve. Therefore I use the following cmake function:

function(VerifyVarDefined)
  foreach(lib ${ARGV}) 
    if(DEFINED ${lib})
    else(DEFINED ${lib})
      message(SEND_ERROR "Variable ${lib} is not defined")
    endif(DEFINED ${lib})
  endforeach()
endfunction(VerifyVarDefined)

For the example mentioned above, this looks like:

VerifyVarDefined(Boost_PROGRAM_OPTIONS_LIBRARY Boost_REGEX_LIBRARY)
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )

If I had written "BOOST_PROGRAM_OPTIONS_LIBRARY" there would have been an error triggered by cmake and not much later triggered by the linker.

Community
  • 1
  • 1
MarkusParker
  • 1,264
  • 2
  • 17
  • 35
1

Additional information to answers above for those still having problems.

  1. Last version of Cmake's FindBoost.cmake may not content last version fo Boost. Add it if needed.
  2. Use -DBoost_DEBUG=0 configuration flag to see info on problems.
  3. See for library naming format. Use Boost_COMPILER and Boost_ARCHITECTURE suffix vars if needed.
ephemerr
  • 1,833
  • 19
  • 22
  • You can find the minimum required CMake version for a given Boost version in this answer: https://stackoverflow.com/a/42124857/2799037 – usr1234567 Feb 10 '22 at 05:44
0

If you are using custome boost path, set CMAKE_PREFIX_PATH firstly. So, cmake can find your custome boost.

list(FIND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX} _INDEX)
if (_INDEX EQUAL -1)
    list(APPEND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX})
    # set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
endif ()

By the way, if you run above code in sub cmake file, should set CMAKE_PREFIX_PATH back to parent scope.

set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)

If you want find all components of boost, using below code.

find_package(Boost 1.76 COMPONENTS ALL)
bovenson
  • 1,170
  • 8
  • 6