I want to use the newest version of Boost library and have the following contents of a CMakeLists.txt
file:
cmake_minimum_required (VERSION 3.0)
project (foo)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DBOOST_ERROR_CODE_HEADER_ONLY -lpthread")
# set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")
add_executable (first first.cpp)
With that I keep getting the following linker error:
undefined reference to `pthread_detach
However, if I compile my code without the use of CMake, with the following command:
g++ foo.cpp -std=c++11 -DBOOST_ERROR_CODE_HEADER_ONLY -lpthread
It works fine.
The question is how to get it to work using CMake. Why doesn't it work when I specify the compiler flags via setting CMAKE_CXX_FLAGS
? I thought I might have to specify CMAKE_EXE_LINKER_FLAGS
instead, but doing that doesn't help at all.
CMake has native support for all the things you're trying to solve by explicit flag specification, so you should use that instead:
cmake_minimum_required (VERSION 3.0)
project (foo)
add_executable (first first.cpp)
target_compile_options (first PRIVATE -std=c++11)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)
If you can increase your minimum CMake version requirement to 3.1, you can replace the hard-coded std
flag with native CMake too:
cmake_minimum_required (VERSION 3.1)
project (foo)
add_executable (first first.cpp)
set_target_properties (first PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED TRUE
CXX_EXTENSIONS FALSE
)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)
The advatange is that not all compilers express "use C++11 without extensions" the same way, and CMake will translate the requirement to the correct flags for you.
If you're going to need the same C++11 setup for many executables, you can instead set CMake variables which prepopulate the properties. Note that the variables must be set before the executables are created:
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED TRUE)
set (CMAKE_CXX_EXTENSIONS FALSE)
add_executable (first first.cpp)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)
add_executable (second second.cpp)
target_compile_definitions (second PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (second pthread)
# ... and so on
In general, one should specify libraries using target_link_libraries
instead of overriding linker flags directly.
In this case, you can do it differently:
add_executable (first first.cpp)
find_package(Threads REQUIRED)
target_link_libraries(first PRIVATE Threads::Threads)
Threads::Threads
above stands for threading library for your system. This has the advantage of being cross platform - when you want to compile your project on, e. g. Windows, linker won't complain about unknown pthread
library.
For the same reason, setting C++ version the way @Angew does in theirs answer is preferred - it just works, without having to manually adjust flags for each compiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With