Ошибка Cmake неопределенная ссылка на `pthread_create’

#c #linux #cmake

#c #linux #cmake

Вопрос:

Я делаю тест для cmake FindThreads. Вот мой исходный код test.cpp и CMakeLists.txt:

 #include <pthread.h>                                                                                                                                                                                                                          
void* test_func(void* data)                                                                                                                                                                                                                   
{                                                                                                                                                                                                                                             
  return data;                                                                                                                                                                                                                                
}                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                              
int main(void)                                                                                                                                                                                                                                
{                                                                                                                                                                                                                                             
  pthread_t thread;                                                                                                                                                                                                                           
  pthread_create(amp;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 .
  

Я получаю выходной:

 -- 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 — сбой, и поскольку он не удался, действительно ли
он находил потоки, я в полном замешательстве. Спасибо за любой ответ!

Комментарии:

1. Где находится src.c в вашем файле CMake? И где в вашем файле CMake эта cmTC_55ab6 цель упоминается в выводе make? Вывод, похоже, не соответствует вашему коду CMake…

2. @squareskittles Спасибо за ваш ответ, эти файлы являются временными файлами, они генерируются cmake find_packge, сообщение об ошибке генерируется find_package (ТРЕБУЮТСЯ потоки)

3. По сути, я копирую тестовый код C в FindThreads.cmake для выполнения этого теста. моя версия cmake — 3.17.4, система Fedora 31

Ответ №1:

Есть небольшая причина для проверки CMakeError.txt , пока CMake не сообщит о нерабочем компиляторе или CMake не сообщит о недоступной функции, которая обнаруживается при компиляции / компоновке проб, но вы ожидаете, что эта функция будет доступна.

В вашем случае у вас есть успешная настройка CMake (посмотрите на последние строки в выводе CMake), и вы успешно обнаружили библиотеку, связанную с потоками (см. Ниже). Нет причин для беспокойства и нет причин для изучения CMakeError.txt .

действительно ли он находил потоки?

Да, потоки найдены. Например, CMake четко указывает

 -- Found Threads: TRUE  
  

Другие способы вывести, что потоки были найдены:

  1. Вы используете REQUIRED ключевое слово with find_package(Threads) . Если потоки не найдены, CMake сообщит об ошибке и завершит настройку.

  2. Вы можете проверить Threads_FOUND переменную после find_package(Threads) вызова. (С REQUIRED ключевым словом эта проверка повторяется).

  3. Вы можете проверить Threads::Threads цель после find_package(Threads) вызова. (С REQUIRED ключевым словом эта проверка повторяется).

Комментарии:

1. Спасибо за ваш ответ. вы даете мне более подробную информацию о cmake, вы и @fdk1342 мне очень помогли. Большое вам спасибо

Ответ №2:

FindThreads.cmake пытается лучше всего определить, поддерживает ли компилятор pthreads как библиотеку, переключатель времени компиляции или переключатель времени соединения и т. Д.

Ошибка, которую вы видите, заключается pthreads в том, существует ли библиотека. Это не так. Вместо этого вы должны скомпилировать файлы, с -pthreads которыми используется переключатель времени компиляции, который принимает ваш компилятор. Это соответствует clang документации, которая показывает, что -pthreads это опция компилятора, а не опция компоновщика. https://clang.llvm.org/docs/ClangCommandLineReference.html#compilation-flags

Итак, он нашел потоки? Не совсем, искать нечего. Определило ли это, как использовать pthreads? ДА.

Вы не показали никаких ошибок при создании целевого test test.cpp объекта. Вы опубликовали только ошибки, которые можно было бы ожидать, когда pthreads не реализовано как отдельная библиотека.

Комментарии:

1. спасибо за ваш ответ, то есть вы имеете в виду, что во время компиляции это не удалось, но во время соединения это удалось, и -pthread — это время компиляции, поэтому я должен добавить флаг компиляции, на самом деле при построении целевого теста с помощью test.cpp . Вот почему я в замешательстве, у него были ошибки при сборке cmake.

2. Я пытаюсь добавить флаг компиляции, он работает, ошибка исчезла! Вы даете мне знать, что флаги Clang отличаются от gcc, о которых я никогда раньше не думал. Большое вам спасибо