How to link C++ program with Boost using CMake
Asked Answered
P

7

142

What should my CMake file look like for linking my program with the Boost library under Ubuntu?

The errors shown during running make:

main.cpp:(.text+0x3b): undefined reference to `boost::program_options::options_description::m_default_line_length'

The main file is really simple:

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/option.hpp>
using namespace std;
#include <iostream>

namespace po = boost::program_options;

int main(int argc, char** argv) {

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ;

    return 0;
}

I've managed to do that. The only lines that I've added to my CMake files were:

target_link_libraries(
my_target_file
${Boost_PROGRAM_OPTIONS_LIBRARY}
)
Patois answered 9/10, 2010 at 20:52 Comment(0)
C
171

In CMake you could use find_package to find libraries you need. There usually is a FindBoost.cmake along with your CMake installation.

As far as I remember, it will be installed to /usr/share/cmake/Modules/ along with other find-scripts for common libraries. You could just check the documentation in that file for more information about how it works.

An example out of my head:

FIND_PACKAGE( Boost 1.40 COMPONENTS program_options REQUIRED )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )

ADD_EXECUTABLE( anyExecutable myMain.cpp )

TARGET_LINK_LIBRARIES( anyExecutable LINK_PUBLIC ${Boost_LIBRARIES} )

I hope this code helps.

Convolution answered 12/10, 2010 at 16:44 Comment(5)
Added a working link from Kitwares Github repo. Also added a link to the official documentation about FindBoost.cmakeConvolution
Why Boost 1.40 in particular? When did the base functionalities of the library stopped changing?Seasonal
Because why not? It's just an example... Fill in whatever suits you bestConvolution
An important detail is to place target_link_libraries after the add_executable and find_package lines, so all linked components are known.Wickliffe
This answer is inappropriate for new code. oLen's answer should be preferredLett
I
63

Adapting @MOnsDaR answer for modern CMake syntax with imported targets, this would be:

find_package(Boost 1.40 COMPONENTS program_options REQUIRED)

add_executable(anyExecutable myMain.cpp)

target_link_libraries(anyExecutable Boost::program_options)

Note that it is not necessary to specify the include directories manually, since it is already taken care of through the imported target Boost::program_options.

Inofficious answered 10/5, 2017 at 6:50 Comment(4)
The downside to this target approach is if your Boost version is newer than your CMake version, this will probably fail. The FindBoost.cmake originally builds these only if it explicitly lists your Boost version. At some point this was supposed to be improved, but I'm still seeing failures with CMake 3.10.2 and Boost 1.66 (newest copies from brew).Fina
stackoverflow starts failing because there are so many outdated answers that often it is hard to find the right answer (this one).Lebaron
@HenrySchreiner helpful comment! It helps me understanding why my cmake/conan/boost/g++ version mix is not linking correctly. Is there a way to determine compatible versions for Boost and CMake?Coarsegrained
They've actually really improved this - CMake will now assume the most recent Boost's targets extend to the current one if you mismatch. Also it will use the Boost's CMake module if it provides one, which newer ones do if they used CMake. Best source I think is checking the CMake FindBoost source - starting at gitlab.kitware.com/cmake/cmake/-/blob/master/Modules/… .Fina
M
56

The following is my configuration:

cmake_minimum_required(VERSION 2.8)
set(Boost_INCLUDE_DIR /usr/local/src/boost_1_46_1)
set(Boost_LIBRARY_DIR /usr/local/src/boost_1_46_1/stage/lib)
find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})

add_executable(main main.cpp)
target_link_libraries( main ${Boost_LIBRARIES} )
Meaty answered 28/6, 2011 at 3:48 Comment(3)
The link_directories isn't required as Boost_LIBRARIES will be fully qualified paths.Gene
In my case link_directories was necessary.Leung
This answer is inappropriate for new code. oLen's answer should be preferredLett
F
7

Two ways, using system default install path, usually /usr/lib/x86_64-linux-gnu/:

find_package(Boost REQUIRED regex date_time system filesystem thread graph)
include_directories(${BOOST_INCLUDE_DIRS})
message("boost lib: ${Boost_LIBRARIES}")
message("boost inc:${Boost_INCLUDE_DIR}")

add_executable(use_boost use_boost.cpp)
target_link_libraries(use_boost
        ${Boost_LIBRARIES}
        )

If you install Boost in a local directory or choose local install instead of system install, you can do it by this:

set( BOOST_ROOT "/home/xy/boost_install/lib/" CACHE PATH "Boost library path" )
set( Boost_NO_SYSTEM_PATHS on CACHE BOOL "Do not search system for Boost" )

find_package(Boost REQUIRED regex date_time system filesystem thread graph)
include_directories(${BOOST_INCLUDE_DIRS})
message("boost lib: ${Boost_LIBRARIES}, inc:${Boost_INCLUDE_DIR}")

add_executable(use_boost use_boost.cpp)
target_link_libraries(use_boost
        ${Boost_LIBRARIES}
        )

Note the above dir /home/xy/boost_install/lib/ is where I install Boost:

xy@xy:~/boost_install/lib$ ll -th
total 16K
drwxrwxr-x 2 xy xy 4.0K May 28 19:23 lib/
drwxrwxr-x 3 xy xy 4.0K May 28 19:22 include/

xy@xy:~/boost_install/lib$ ll -th lib/
total 57M
drwxrwxr-x 2 xy xy 4.0K May 28 19:23 ./
-rw-rw-r-- 1 xy xy 2.3M May 28 19:23 libboost_test_exec_monitor.a
-rw-rw-r-- 1 xy xy 2.2M May 28 19:23 libboost_unit_test_framework.a
.......

xy@xy:~/boost_install/lib$ ll -th include/
total 20K
drwxrwxr-x 110 xy xy  12K May 28 19:22 boost/

If you are interested in how to use a local installed Boost, you can see this question How can I get CMake to find my alternative Boost installation?.

Foldaway answered 4/8, 2018 at 3:8 Comment(0)
T
4

Here is my take:

cmake_minimum_required(VERSION 3.15)

project(TryOuts LANGUAGES CXX)

find_package(Boost QUIET REQUIRED COMPONENTS program_options)

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

add_executable(helloworld main.cpp)

target_link_libraries(helloworld PUBLIC Boost::program_options)
Turner answered 26/12, 2019 at 12:3 Comment(3)
target_link_libraries(helloworld PUBLIC Boost::program_options) will give a CMAKE error: -- Configuring done CMake Error at CMakeLists.txt:102 (add_executable): Target "DB32" links to target "Boost::program_options" but the target was not found. Perhaps a find_package() call is missing for an IMPORTED target, or an ALIAS target is missing?Corrode
Hi, thanks for the feedback. It seems like the CMake can't locate Boost on your system. Maybe you better to make a fresh build of the Boost from the source. Before that you might want to try the following: Find the package with find_package(Boost QUIET REQUIRED) and link to your target (DB32): target_link_libraries(DB32 PUBLIC Boost::headers)Turner
Because you put REQUIRED, NOT Boost_FOUND is never true, so that whole if statement is pointless.Lett
H
1

Which Boost library? Many of them are pure templates and do not require linking.

Now with that actually shown concrete example which tells us that you want Boost program options (and even more told us that you are on Ubuntu), you need to do two things:

  1. Install libboost-program-options-dev so that you can link against it.
  2. Tell cmake to link against libboost_program_options.

I mostly use Makefiles so here is the direct command-line use:

$ g++ boost_program_options_ex1.cpp -o bpo_ex1 -lboost_program_options
$ ./bpo_ex1
$ ./bpo_ex1 -h
$ ./bpo_ex1 --help
$ ./bpo_ex1 -help
$

It doesn't do a lot it seems.

For CMake, you need to add boost_program_options to the list of libraries, and IIRC this is done via SET(liblist boost_program_options) in your CMakeLists.txt.

Hubert answered 9/10, 2010 at 20:54 Comment(1)
Your CMake advice is wrong (see the accepted answer), and your commandline advice not very helpful as the question was about CMake.Pallium
N
0

Another possible cause of the error:

If you built boost with ABI=0

./b2 -q cxxflags=-D_GLIBCXX_USE_CXX11_ABI=0 install

then you must also build application with ABI=0

add_cxx_flags( "-D_GLIBCXX_USE_CXX11_ABI=0" )
Nightrider answered 9/11, 2023 at 0:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.