【问题标题】:Why is CMake not linking pthread in this CMakeList.txt?为什么 CMake 没有在这个 CMakeList.txt 中链接 pthread?
【发布时间】:2019-09-05 00:20:17
【问题描述】:

在使用 pthread 库的程序上运行 make 时,我收到错误“未定义对 'pthread_create' 的引用”。当我直接用 g++ 构建它时它可以工作:

g++ -std=c++11 -pthread pthread_Mutex.c stopwatch.o -o pthread_Mutex

但不使用 CMake。

我研究了一些很好的例子,包括这里:cmake and libpthread

我已经尝试了 thehouse 的 3.1+ 和 2.8+ 版本的 CMake 示例。我在 Ubuntu 上运行 3.5.1。这是我的 CMakeList.txt。

cmake_minimum_required(VERSION 3.5)
project(pthread_Mutex)
set (CMAKE_CXX_STANDARD 11)
set(THREADS_PREFER_PTHREAD_FLAG ON)

find_package(Threads REQUIRED)

include_directories(include)
file(GLOB SOURCES "src/*.cpp") 
add_executable(stopwatch ${SOURCES})
add_executable(pthread_Mutex ${SOURCES})

# I've tried this one by itself 
#target_link_libraries(pthread_Mutex Threads::Threads)


if(THREADS_HAVE_PTHREAD_ARG)
  target_compile_options(pthread_Mutex PUBLIC "-pthread")
endif()
if(CMAKE_THREAD_LIBS_INIT)
  target_link_libraries(pthread_Mutex "${CMAKE_THREAD_LIBS_INIT}")
endif()

target_link_libraries(pthread_Mutex pthread) 

这是我的目录结构:

├── build
├── CMakeLists.txt
├── include
│   └── stopwatch.h
├── src
    ├── pthread_Mutex.cpp
    └── stopwatch.cpp

pthread_Mutex.cpp 是我的主程序。 stopwatch.cpp 是一个不使用 pthread 的库。

但是在运行 cmake VERBOSE=1 时出现以下错误:

/usr/bin/cmake -H/home/ben/workspaces/c++/thread_experiments -B/home/ben/workspaces/c++/thread_experiments/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
make -f CMakeFiles/pthread_Mutex.dir/build.make CMakeFiles/pthread_Mutex.dir/depend
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
cd /home/ben/workspaces/c++/thread_experiments/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles/pthread_Mutex.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
make -f CMakeFiles/pthread_Mutex.dir/build.make CMakeFiles/pthread_Mutex.dir/build
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
make[2]: Nothing to be done for 'CMakeFiles/pthread_Mutex.dir/build'.
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
[ 50%] Built target pthread_Mutex
make -f CMakeFiles/stopwatch.dir/build.make CMakeFiles/stopwatch.dir/depend
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
cd /home/ben/workspaces/c++/thread_experiments/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles/stopwatch.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
make -f CMakeFiles/stopwatch.dir/build.make CMakeFiles/stopwatch.dir/build
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
[ 66%] Linking CXX executable stopwatch
/usr/bin/cmake -E cmake_link_script CMakeFiles/stopwatch.dir/link.txt --verbose=1
/usr/bin/c++      CMakeFiles/stopwatch.dir/src/pthread_Mutex.cpp.o CMakeFiles/stopwatch.dir/src/stopwatch.cpp.o  -o stopwatch 
CMakeFiles/stopwatch.dir/src/pthread_Mutex.cpp.o: In function `main':
pthread_Mutex.cpp:(.text+0x15a): undefined reference to `pthread_attr_getstacksize'
pthread_Mutex.cpp:(.text+0x19f): undefined reference to `pthread_attr_setstacksize'
pthread_Mutex.cpp:(.text+0x260): undefined reference to `pthread_create'
pthread_Mutex.cpp:(.text+0x29d): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
CMakeFiles/stopwatch.dir/build.make:120: recipe for target 'stopwatch' failed
make[2]: *** [stopwatch] Error 1
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/stopwatch.dir/all' failed
make[1]: *** [CMakeFiles/stopwatch.dir/all] Error 2
make[1]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

所以我在 CMakeList.txt 文件中一定有问题,但我已经没有想法可以尝试了。

谢谢

【问题讨论】:

  • 你在运行 CMake 后检查了make VERBOSE=1 的输出吗?这可以帮助验证 g++ 获得的编译选项与没有 CMake 时获得的编译选项相同(当您直接运行 g++ 时)。
  • 我认为# target_link_libraries(pthread_Mutex Threads::Threads) 应该只适用于 3.1。看起来 cmake 没有为您设置正确的导入目标 Threads::Threads。您可以尝试 cmake --trace 查看详细的 cmake 内部日志以了解问题所在。
  • @squareskittles,我将 make VERBOSE=1 输出添加到我的原始帖子中。在我看来, -pthread 似乎被包括在内。我不清楚。
  • @2power10,我做了 cmake --trace。它用各种各样的东西填满了缓冲区。我应该寻找什么?

标签: c++ c++11 cmake pthreads


【解决方案1】:

您使用了target_compile_options,这对于编译标志非常有用,但是您忘记对链接选项执行相同的操作。在同一行中添加target_link_options

【讨论】:

  • 嗨 Matthieu Brucher,我使用的是 cmake 3.5.1。此版本中似乎不包含 target_link_options。
  • 在这种情况下,只需更改 CMAKE_LINK_SHARED_FLAGS 变量即可。
【解决方案2】:

target_compile_options 为编译步骤添加标志。您还需要链接到 pthread 库 -

target_link_libraries(pthread_Mutex pthread)

【讨论】:

  • 嗨,Shubham Goyal,我已经尝试过了,但仍然出现错误。我将更改添加到我的原始帖子中。对吗?
  • 我不确定 CMake 对相同的项目和可执行文件名称做了什么,也许尝试将可执行文件命名为 pthread_Mutex_bin 并将输出名称设置为 pthread_Mutex 通过 set_target_properties(pthread_Mutex_bin PROPERTIES OUTPUT_NAME pthread_Mutex) 另外,你可以试试 - set_target_properties(pthread_Mutex PROPERTIES LINK_FLAGS -pthread)
猜你喜欢
  • 2021-11-12
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多