CMake构建失败,除非在target_link_directories()命令上调用了pthread

til*_*oom 2 c++ linux boost cmake

我与CMake 3.10和存在链接问题Boost 1_66_0。我准备进行一些联网时,正在使用asio异步计时器教程进行测试。我正在使用Linux进行开发的前沿项目,该项目需要我将Boost安装到自定义目录中:

/home/myuser/boost/boost_1_66_0
Run Code Online (Sandbox Code Playgroud)

我在我的环境中设置了以下环境变量.bash_profile

export BOOST_ROOT=/home/myuser/boost/boost_1_66_0
export BOOST_LIBRARYDIR=/home/myuser/boost/boost_1_66_0/stage/lib
Run Code Online (Sandbox Code Playgroud)

尽管我设法使它正常工作,但是即使我在命令上调用Boost自己的库,除非pthreadtarget_link_libraries()命令上调用,否则构建都会失败。threadfind_package()

pthread在Boost的入门指南或CMake的文档中,我没有提到需要调用的任何内容

这是我的完整CMakeLists.txt文件:

  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()
Run Code Online (Sandbox Code Playgroud)

CMake找到该thread库:

-- [ /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
Run Code Online (Sandbox Code Playgroud)

但是随后make ,它坚持要求执行命令失败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
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我必须添加pthreadtarge_link_libraries()命令中:

target_link_libraries(asio_tut ${Boost_LIBRARIES} pthread)
Run Code Online (Sandbox Code Playgroud)

这正常吗?以后会再次困扰我吗?会引起便携性问题吗?我应该忽略它吗?

我的CMakeCache.txt文件显示CMake在自定义目录中找到了我所有的Boost库和标头。我不会包括整个缓存文件,但是我检查了缓存条目,它们是正确的。

侧面点

不知道这是否相关,但是在CMake构建期间,我确实收到了有关我的Boost版本的警告,因为它处于前沿:

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
Run Code Online (Sandbox Code Playgroud)

Tsy*_*rev 6

我还认为CMake会使用Boost的线程库而不是要求pthread。

是的,Boost有自己的线程库(实际上是pthread的包装器)。要使用此库,您需要在找到Boost时请求相应的组件:

find_package(BOOST REQUIRED COMPONENTS system thread)
Run Code Online (Sandbox Code Playgroud)

  • 如警告所示,Boost版本实际上对于CMake来说还太新。在CMake的[FindBoost.cmake]主版本中(https://github.com/Kitware/CMake/blob/master/Modules/FindBoost.cmake),当Boost的“线程”组件被添加时,会自动添加Thread :: Thread`依赖性请求:“列表(APPEND _Boost _ $ {UPPERCOMPONENT} _TARGET_DEPENDENCIES Threads :: Threads)”。(在Linux上,“ Threads :: Threads”通常是pake的CMake别名)。您可以检查`make VERBOSE = 1`的输出,并确定哪些库实际上已传递给链接器。 (2认同)