mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 16:32:14 -06:00
FindThreads: Use complete program to test for pthreads in libc
Our check for just `pthread_create` is not sufficient because there are cases where that symbol may be found in libc but not all of pthreads. We first tried to address this in commite9a1ddc594(FindThreads: Replace the pthread symbol checking in libc., 2018-11-18, v3.14.0-rc1~292^2) by switching to `pthread_kill`, but that had to be reverted by commit18320230ec(FindThreads: Revert libc symbol check to pthread_create, 2019-02-27, v3.14.0-rc3~6^2) because there are other cases where `pthread_kill` is in libc but the rest of pthreads is not. Update our check to try a complete program using pthreads as an actual application might. Fixes: #18994
This commit is contained in:
@@ -38,19 +38,42 @@ This module is not needed for C++11 and later if threading is done using
|
||||
#]=======================================================================]
|
||||
|
||||
include (CheckLibraryExists)
|
||||
include (CheckSymbolExists)
|
||||
set(Threads_FOUND FALSE)
|
||||
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
|
||||
set(CMAKE_REQUIRED_QUIET ${Threads_FIND_QUIETLY})
|
||||
|
||||
if(CMAKE_C_COMPILER_LOADED)
|
||||
include (CheckIncludeFile)
|
||||
include (CheckCSourceCompiles)
|
||||
elseif(CMAKE_CXX_COMPILER_LOADED)
|
||||
include (CheckIncludeFileCXX)
|
||||
include (CheckCXXSourceCompiles)
|
||||
else()
|
||||
message(FATAL_ERROR "FindThreads only works if either C or CXX language is enabled")
|
||||
endif()
|
||||
|
||||
# simple pthread test code
|
||||
set(PTHREAD_C_CXX_TEST_SOURCE [====[
|
||||
#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_join(thread, NULL);
|
||||
pthread_atfork(NULL, NULL, NULL);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
]====])
|
||||
|
||||
# Internal helper macro.
|
||||
# Do NOT even think about using it outside of this file!
|
||||
macro(_check_threads_lib LIBNAME FUNCNAME VARNAME)
|
||||
@@ -109,8 +132,8 @@ if(CMAKE_C_COMPILER_LOADED)
|
||||
else()
|
||||
CHECK_INCLUDE_FILE_CXX("pthread.h" CMAKE_HAVE_PTHREAD_H)
|
||||
endif()
|
||||
if(CMAKE_HAVE_PTHREAD_H)
|
||||
|
||||
if(CMAKE_HAVE_PTHREAD_H)
|
||||
#
|
||||
# We have pthread.h
|
||||
# Let's check for the library now.
|
||||
@@ -118,13 +141,19 @@ if(CMAKE_HAVE_PTHREAD_H)
|
||||
set(CMAKE_HAVE_THREADS_LIBRARY)
|
||||
if(NOT THREADS_HAVE_PTHREAD_ARG)
|
||||
# Check if pthread functions are in normal C library.
|
||||
CHECK_SYMBOL_EXISTS(pthread_create pthread.h CMAKE_HAVE_LIBC_CREATE)
|
||||
if(CMAKE_HAVE_LIBC_CREATE)
|
||||
# We list some pthread functions in PTHREAD_C_CXX_TEST_SOURCE test code.
|
||||
# If the pthread functions already exist in C library, we could just use
|
||||
# them instead of linking to the additional pthread library.
|
||||
if(CMAKE_C_COMPILER_LOADED)
|
||||
CHECK_C_SOURCE_COMPILES("${PTHREAD_C_CXX_TEST_SOURCE}" CMAKE_HAVE_LIBC_PTHREAD)
|
||||
elseif(CMAKE_CXX_COMPILER_LOADED)
|
||||
CHECK_CXX_SOURCE_COMPILES("${PTHREAD_C_CXX_TEST_SOURCE}" CMAKE_HAVE_LIBC_PTHREAD)
|
||||
endif()
|
||||
if(CMAKE_HAVE_LIBC_PTHREAD)
|
||||
set(CMAKE_THREAD_LIBS_INIT "")
|
||||
set(CMAKE_HAVE_THREADS_LIBRARY 1)
|
||||
set(Threads_FOUND TRUE)
|
||||
else()
|
||||
|
||||
# Check for -pthread first if enabled. This is the recommended
|
||||
# way, but not backwards compatible as one must also pass -pthread
|
||||
# as compiler flag then.
|
||||
@@ -144,7 +173,7 @@ if(CMAKE_HAVE_PTHREAD_H)
|
||||
_check_pthreads_flag()
|
||||
endif()
|
||||
|
||||
if(CMAKE_THREAD_LIBS_INIT OR CMAKE_HAVE_LIBC_CREATE)
|
||||
if(CMAKE_THREAD_LIBS_INIT OR CMAKE_HAVE_LIBC_PTHREAD)
|
||||
set(CMAKE_USE_PTHREADS_INIT 1)
|
||||
set(Threads_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
Reference in New Issue
Block a user