summaryrefslogtreecommitdiffstats
path: root/Modules/FindThreads.cmake
diff options
context:
space:
mode:
authorJerryShih <bignose1007@gmail.com>2019-02-28 08:30:43 (GMT)
committerJerryShih <bignose1007@gmail.com>2019-03-06 03:16:32 (GMT)
commitd53317130e84898c5328c237186dbd995aaf1c12 (patch)
treebf20567ae222dfeb0bc459da8309473c769424c7 /Modules/FindThreads.cmake
parent2f59cd637181cd246ab700767ea3e3cbd6cc3df4 (diff)
downloadCMake-d53317130e84898c5328c237186dbd995aaf1c12.zip
CMake-d53317130e84898c5328c237186dbd995aaf1c12.tar.gz
CMake-d53317130e84898c5328c237186dbd995aaf1c12.tar.bz2
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 commit e9a1ddc594 (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 commit 18320230ec (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
Diffstat (limited to 'Modules/FindThreads.cmake')
-rw-r--r--Modules/FindThreads.cmake41
1 files changed, 35 insertions, 6 deletions
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index 919392a..3684f01 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -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()