Просмотр исходного кода

Compile CMake as C++17 if supported by the compiler

Add a check that a simple source file can compile as C++17 that uses
some of the features we need.  Do this only when hosted by CMake 3.8
or above because those versions are aware of C++17.

Check for unordered_map as we do in bootstrap since commit 375eca7881
(bootstrap: Check support for unordered_map from compiler mode,
2017-11-30).  Also maintain the existing C++14 cstdio check.
Brad King 8 лет назад
Родитель
Сommit
31d59ff3b1
3 измененных файлов с 56 добавлено и 4 удалено
  1. 13 4
      CMakeLists.txt
  2. 36 0
      Source/Checks/cm_cxx17_check.cmake
  3. 7 0
      Source/Checks/cm_cxx17_check.cpp

+ 13 - 4
CMakeLists.txt

@@ -64,11 +64,20 @@ if(NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMake_NO_CXX_STANDARD)
   if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.14)
     set(CMAKE_CXX_STANDARD 98)
   else()
-    include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx14_check.cmake)
-    if(NOT CMake_CXX14_BROKEN)
-      set(CMAKE_CXX_STANDARD 14)
+    if(NOT CMAKE_VERSION VERSION_LESS 3.8)
+      include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx17_check.cmake)
     else()
-      set(CMAKE_CXX_STANDARD 11)
+      set(CMake_CXX17_BROKEN 1)
+    endif()
+    if(NOT CMake_CXX17_BROKEN)
+      set(CMAKE_CXX_STANDARD 17)
+    else()
+      include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx14_check.cmake)
+      if(NOT CMake_CXX14_BROKEN)
+        set(CMAKE_CXX_STANDARD 14)
+      else()
+        set(CMAKE_CXX_STANDARD 11)
+      endif()
     endif()
   endif()
 endif()

+ 36 - 0
Source/Checks/cm_cxx17_check.cmake

@@ -0,0 +1,36 @@
+set(CMake_CXX17_BROKEN 0)
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+  if(NOT CMAKE_CXX17_STANDARD_COMPILE_OPTION)
+    set(CMake_CXX17_WORKS 0)
+  endif()
+  if(NOT DEFINED CMake_CXX17_WORKS)
+    message(STATUS "Checking if compiler supports needed C++17 constructs")
+    try_compile(CMake_CXX17_WORKS
+      ${CMAKE_CURRENT_BINARY_DIR}
+      ${CMAKE_CURRENT_LIST_DIR}/cm_cxx17_check.cpp
+      CMAKE_FLAGS -DCMAKE_CXX_STANDARD=17
+      OUTPUT_VARIABLE OUTPUT
+      )
+    if(CMake_CXX17_WORKS AND "${OUTPUT}" MATCHES "error: no member named.*gets.*in the global namespace")
+      set_property(CACHE CMake_CXX17_WORKS PROPERTY VALUE 0)
+    endif()
+    if(CMake_CXX17_WORKS)
+      message(STATUS "Checking if compiler supports needed C++17 constructs - yes")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Determining if compiler supports needed C++17 constructs passed with the following output:\n"
+        "${OUTPUT}\n"
+        "\n"
+        )
+    else()
+      message(STATUS "Checking if compiler supports needed C++17 constructs - no")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Determining if compiler supports needed C++17 constructs failed with the following output:\n"
+        "${OUTPUT}\n"
+        "\n"
+        )
+    endif()
+  endif()
+  if(NOT CMake_CXX17_WORKS)
+    set(CMake_CXX17_BROKEN 1)
+  endif()
+endif()

+ 7 - 0
Source/Checks/cm_cxx17_check.cpp

@@ -0,0 +1,7 @@
+#include <cstdio>
+#include <unordered_map>
+
+int main()
+{
+  return 0;
+}