3

I have a linking issue with CMake 3.10 and Boost 1_66_0. I'm using the asio async timer tutorial for testing as I prepare to do some networking. I'm on a bleeding edge Linux maching working on a project that required me to install Boost into a custom directory:

/home/myuser/boost/boost_1_66_0

I set the following environment variables in my .bash_profile:

export BOOST_ROOT=/home/myuser/boost/boost_1_66_0
export BOOST_LIBRARYDIR=/home/myuser/boost/boost_1_66_0/stage/lib

Although I managed to get this working, the build fails unless pthread is called on the target_link_libraries() command, even though I am calling Boost's own thread library on the find_package() command.

I did not find any mention of the need to call pthread in Boost's getting started guide, or in CMake's documentation.

Here is my full CMakeLists.txt file:

  1 cmake_minimum_required(VERSION 3.0)
  2 project(asio_tut)
  3 set(Boost_DEBUG ON)
  4 
  5 if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  6   set(CMAKE_INSTALL_PREFIX=/home/myuser/projects/asio_tut/build CACHE PATH test FORCE)
  7 endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  8 
  9 find_package(Boost REQUIRED COMPONENTS system thread)
 10 
 11 if(Boost_FOUND)
 12   include_directories(${Boost_INCLUDE_DIR})
 13   add_executable(asio_tut timer_async.cpp)
 14   target_link_libraries(asio_tut ${Boost_LIBRARIES})
 15 endif()

CMake finds the thread library:

-- [ /home/myuser/builds/cmake/share/cmake-3.10/Modules/FindBoost.cmake:1767 ] Boost_FOUND = 1
-- Boost version: 1.66.0
-- Found the following Boost libraries:
--   system
--   thread
--   chrono
--   date_time
--   atomic
-- Configuring done
-- Generating done
-- Build files have been written to: /home/myuser/projects/asio_tut/build

But then it fails on the proceeding make command as it insists on pthread:

[myuser@linux build]$ make
Scanning dependencies of target asio_tut
[ 50%] Building CXX object CMakeFiles/asio_tut.dir/timer_async.cpp.o
[100%] Linking CXX executable asio_tut
/usr/bin/ld: CMakeFiles/asio_tut.dir/timer_async.cpp.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
/usr/lib/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/asio_tut.dir/build.make:100: asio_tut] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/asio_tut.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

To fix this I had to add pthread to the targe_link_libraries() command:

target_link_libraries(asio_tut ${Boost_LIBRARIES} pthread)

Is this normal? Will this come back to haunt me later on? Will it cause any problems with portability? Should I just ignore it?

My CMakeCache.txt file shows that CMake found all of my Boost libraries and headers in the custom directories. I won't include the entire cache file, but I examined the cache entries and they are correct.

Side Point

Not sure if this is related but I did get one warning during the CMake build about my Boost version as it is bleeding edge:

CMake Warning at /home/myuser/builds/cmake/share/cmake-3.10/Modules/FindBoost.cmake:801 (message):
  New Boost version may have incorrect or missing dependencies and imported
  targets
  • Have you tried adding `threads` as a requirement ? `find_package(Threads REQUIRED)`. – iamauser Jan 13 '18 at 05:46
  • 3
    Note, that your Boost version is not supported by any released CMake version. This might cause subtle bugs. Not sure whether you are affected. https://stackoverflow.com/a/42124857/2799037 – usr1234567 Jan 13 '18 at 09:03
  • Interesting. I did get one warning about my Boost version as it is bleeding edge. I added that to my question. –  Jan 13 '18 at 14:13

2 Answers2

6

I also thought that CMake would have used Boost's thread library instead of demanding pthread.

Yes, Boost has its own thread library (which is wrapper around pthread, actually). For use this library you need to request corresponding component when find the Boost:

find_package(BOOST REQUIRED COMPONENTS system thread)
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • Hello. I added 'thread' to the 'find_package()' command, but it still requires 'pthread' on the 'target_link_libraries()' command or else the build will fail on the proceeding 'make' command. I re-organized my question. Thank you for your time. –  Jan 14 '18 at 14:04
  • 2
    Probably, Boost version is actually too new for CMake, as the warning says. In master version of CMake's [FindBoost.cmake](https://github.com/Kitware/CMake/blob/master/Modules/FindBoost.cmake) `Thread::Thread` dependency is added automatically when Boost's "thread" component is requested: `list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Threads::Threads)`. (On Linux `Threads::Threads` is normally CMake's alias for pthread). You may check output of `make VERBOSE=1` and find which libraries are actually passed to the linker. – Tsyvarev Jan 14 '18 at 15:44
0

I have also get this error sometime ago. I just added this lines to my CMakeList:

SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} )
SET(CMAKE_CXX_FLAGS " -pthread") 

And also for my 3.0 CMakeList (also for higher version too) i added this lines:

if (CMAKE_VERSION VERSION_LESS "3.1")
    if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
    endif ()
  else ()
    set_property(TARGET app_name PROPERTY CXX_STANDARD 11)
    set_property(TARGET app_name PROPERTY CXX_STANDARD_REQUIRED ON)
  endif ()

Hope it will help you.

Marijke Buurlage
  • 331
  • 5
  • 21
  • 3
    Note that CMake has also been shipping a [`FindThreads`](https://cmake.org/cmake/help/v2.8.12/cmake.html#module:FindThreads) module for some time, which is a bit more robust than handcoding the flag. – ComicSansMS Jan 15 '18 at 08:34
  • ComicSansMS this is really nice. Thanks for the tip. –  Jan 17 '18 at 02:09