How do you add Boost libraries in CMakeLists.txt?
BoostCmakeBoost Problem Overview
I need to add Boost libraries into my CMakeLists.txt. How do you do it or how do you add it?
Boost Solutions
Solution 1 - Boost
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)
Solution 2 - Boost
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 )
- My advice is to disable auto-linking and use cmake's dependency handling:
Solution 3 - Boost
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.
Solution 4 - Boost
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()
Solution 5 - Boost
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!
Solution 6 - Boost
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.
Solution 7 - Boost
Additional information to answers above for those still having problems.
- Last version of Cmake's
FindBoost.cmake
may not content last version fo Boost. Add it if needed. - Use -DBoost_DEBUG=0 configuration flag to see info on problems.
- See for library naming format. Use
Boost_COMPILER
andBoost_ARCHITECTURE
suffix vars if needed.
Solution 8 - Boost
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)