Avoid using C11 to build CMake if _Thread_local support is broken

Support for C11's _Thread_local was introduced in GCC in the 4.9 series,
even though we make the C11 compiler flags available in CMake with GCC
>= 4.6.

FreeBSD's runetype.h uses _Thread_local, which causes CMake's own build
to fail when using GCC < 4.9 and -std=gnu11:

  /usr/include/runetype.h:92:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'const'
   extern _Thread_local const _RuneLocale *_ThreadRuneLocale;

Add a test for _Thread_local support and only build CMake itself with
C11 support if it works.

Bug: http://www.cmake.org/Bug/view.php?id=15741
This commit is contained in:
Raphael Kubo da Costa 2015-09-15 16:31:12 +02:00 committed by Brad King
parent cda189356e
commit ffa6f057b4
3 changed files with 41 additions and 1 deletions

View File

@ -38,7 +38,12 @@ endif()
# Use most-recent available language dialects with GNU and Clang
if(NOT DEFINED CMAKE_C_STANDARD AND NOT CMake_NO_C_STANDARD)
set(CMAKE_C_STANDARD 11)
include(${CMake_SOURCE_DIR}/Source/Checks/cm_c11_thread_local.cmake)
if(NOT CMake_C11_THREAD_LOCAL_BROKEN)
set(CMAKE_C_STANDARD 11)
else()
set(CMAKE_C_STANDARD 99)
endif()
endif()
if(NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMake_NO_CXX_STANDARD)
include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx14_cstdio.cmake)

View File

@ -0,0 +1,2 @@
_Thread_local int i = 42;
int main(void) { return 0; }

View File

@ -0,0 +1,33 @@
set(CMake_C11_THREAD_LOCAL_BROKEN 0)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_C11_STANDARD_COMPILE_OPTION)
if(NOT DEFINED CMake_C11_THREAD_LOCAL_WORKS)
message(STATUS "Checking if compiler supports C11 _Thread_local")
try_compile(CMake_C11_THREAD_LOCAL_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_c11_thread_local.c
CMAKE_FLAGS -DCMAKE_C_STANDARD=11
OUTPUT_VARIABLE OUTPUT
)
if(CMake_C11_THREAD_LOCAL_WORKS AND "${OUTPUT}" MATCHES "error: expected '=', ',', ';', 'asm' or '__attribute__' before 'int'")
set_property(CACHE CMake_C11_THREAD_LOCAL_WORKS PROPERTY VALUE 0)
endif()
if(CMake_C11_THREAD_LOCAL_WORKS)
message(STATUS "Checking if compiler supports C11 _Thread_local - yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports C11 _Thread_local passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
message(STATUS "Checking if compiler supports C11 _Thread_local - no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports C11 _Thread_local failed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
endif()
endif()
if(NOT CMake_C11_THREAD_LOCAL_WORKS)
set(CMake_C11_THREAD_LOCAL_BROKEN 1)
endif()
endif()