Cmake错误:undefined reference to `pthread_create'。

4

我对CMake FindThreads进行了测试。这是我的源代码test.cpp和CMakeLists.txt:

#include <pthread.h>                                                                                                                                                                                                                          
void* test_func(void* data)                                                                                                                                                                                                                   
{                                                                                                                                                                                                                                             
  return data;                                                                                                                                                                                                                                
}                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                              
int main(void)                                                                                                                                                                                                                                
{                                                                                                                                                                                                                                             
  pthread_t thread;                                                                                                                                                                                                                           
  pthread_create(&thread, NULL, test_func, NULL);                                                                                                                                                                                             
  pthread_detach(thread);                                                                                                                                                                                                                     
  pthread_cancel(thread);                                                                                                                                                                                                                     
  pthread_join(thread, NULL);                                                                                                                                                                                                                 
  pthread_atfork(NULL, NULL, NULL);                                                                                                                                                                                                           
  pthread_exit(NULL);                                                                                                                                                                                                                         
  return 0;                                                                                                                                                                                                                                   
}     

cmake_minimum_required(VERSION 3.5)                                                                                                                                                                                                           
                                                                                                                                                                                                                                              
project(test C CXX)                                                                                                                                                                                                                           
                                                                                                                                                                                                                                              
set(CMAKE_THREAD_PREFER_PTHREAD ON)                                                                                                                                                                                                           
set(THREADS_PREFER_PTHREAD_FLAG ON)                                                                                                                                                                                                           
find_package(Threads REQUIRED)                                                                                                                                                                                                                
add_executable(test test.cpp)                                                                                                                                                                                                                 
if(TARGET Threads::Threads)                                                                                                                                                                                                                   
  target_link_libraries(test PRIVATE Threads::Threads)                                                                                                                                                                                        
endif()

当我运行:

cmake .

I get the outpu:

-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE  

然后我检查了CMakeError.txt,发现:

gmake[1]: Entering directory '/home/hye/tmp/cmake-error/CMakeFiles/CMakeTmp'                                                                                                                                                                  
Building C object CMakeFiles/cmTC_55ab6.dir/src.c.o                                                                                                                                                                                           
/usr/bin/clang   -DCMAKE_HAVE_LIBC_PTHREAD   -o CMakeFiles/cmTC_55ab6.dir/src.c.o   -c /home/hye/tmp/cmake-error/CMakeFiles/CMakeTmp/src.c                                                                                                    
Linking C executable cmTC_55ab6                                                                                                                                                                                                               
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_55ab6.dir/link.txt --verbose=1                                                                                                                                                            
/usr/bin/clang  -DCMAKE_HAVE_LIBC_PTHREAD    CMakeFiles/cmTC_55ab6.dir/src.c.o  -o cmTC_55ab6                                                                                                                                                 
/usr/bin/ld: CMakeFiles/cmTC_55ab6.dir/src.c.o: in function `main':                                                                                                                                                                           
src.c:(.text+0x35): undefined reference to `pthread_create'                                                                                                                                                                                   
/usr/bin/ld: src.c:(.text+0x41): undefined reference to `pthread_detach'                                                                                                                                                                      
/usr/bin/ld: src.c:(.text+0x4d): undefined reference to `pthread_cancel'                                                                                                                                                                      
/usr/bin/ld: src.c:(.text+0x5f): undefined reference to `pthread_join'                                                                                                                                                                        
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)                                                                                                                                                             
gmake[1]: *** [CMakeFiles/cmTC_55ab6.dir/build.make:107: cmTC_55ab6] Error 1                                                                                                                                                                  
gmake[1]: Leaving directory '/home/hye/tmp/cmake-error/CMakeFiles/CMakeTmp'                                                                                                                                                                   
gmake: *** [Makefile:141: cmTC_55ab6/fast] Error 2         

我的问题是为什么执行测试 CMAKE_HAVE_LIBC_PTHREAD - 失败,并且既然它失败了,那么它是否真的找到了线程,我完全困惑了。谢谢任何回复!


你的CMake文件中src.c在哪里?而且在你的CMake文件中,这个cmTC_55ab6目标在make输出中提到了吗?输出似乎与你的CMake代码不匹配... - Kevin
@squareskittles 感谢您的回复,这些文件是临时文件,它们是由cmake find_package生成的,错误消息是由find_package(Threads REQUIRED)生成的。 - Coco
基本上,我复制了FindThreads.cmake中的C测试代码来进行此测试。我的cmake版本是3.17.4,系统为Fedora 31。 - Coco
2个回答

3

在CMake报告编译器不工作或探测编译/链接的功能不可用时,才需要查看CMakeError.txt文件,但您预期该功能可用。

在您的情况下,您已成功配置CMake(请查看CMake输出中的最后几行),并且已成功探测到与线程相关的库(请参见下文)。无需担心,也无需查看CMakeError.txt文件。

它真的找到了Threads吗?

是的,找到了Threads。例如,CMake明确说明:

-- Found Threads: TRUE  

找到 Threads 线程的其他方法:

  1. 使用 REQUIRED 关键字和 find_package(Threads)。如果没有找到 Threads,CMake 将报告错误并终止配置。

  2. find_package(Threads) 调用后,您可以检查 Threads_FOUND 变量。(在使用 REQUIRED 关键字时,此检查是多余的)。

  3. find_package(Threads) 调用后,您可以检查 Threads::Threads 目标。(在使用 REQUIRED 关键字时,此检查是多余的)。


谢谢你的回答。你给了我更多关于cmake的细节,你和@fdk1342帮了我很多。非常感谢。 - Coco

0

FindThreads.cmake 尽力确定编译器是否支持 pthreads 作为库、编译时开关或链接时开关等。

您看到的错误是如果存在 pthreads 库。它不存在。相反,您应该使用 -pthreads 编译文件,这是编译器接受的编译时开关。这与 clang 文档一致,其中显示 -pthreads 是编译器选项,而不是链接器选项。https://clang.llvm.org/docs/ClangCommandLineReference.html#compilation-flags

那么,它找到了线程吗?并没有,没有什么可以找到的。它确定如何使用 pthreads 吗?是的。

在使用 test.cpp 构建目标 test 时,您没有显示任何错误。您只发布了当未将 pthreads 实现为单独的库时所期望的错误。


谢谢您的回答,您的意思是在编译时失败了,但在链接时成功了,并且-pthread是编译时的选项,所以我应该添加一个编译标志。事实上,在使用test.cpp构建目标测试时没有任何错误。这就是为什么我感到困惑,因为cmake构建时确实出现了错误。 - Coco
我尝试添加一个编译标志,它起作用了,错误消失了!你让我知道Clang的标志与gcc的不同,这是我以前从未考虑过的。非常感谢你。 - Coco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接