Quellcode durchsuchen

project: Add infrastructure for recording CXX compiler features

Add a feature test using the compiler macros and the preprocessor to
determine available features.

Add a CMAKE_CXX_COMPILE_FEATURES variable which contains all features
known to the loaded compiler, and a CMAKE_CXX_KNOWN_FEATURES variable
containing all features known to CMake.  Add language standard specific
variables for internal use to determine the standard-specific compile
flags to use.

This will be extended to other languages in the future.  Follow-up
commits will add features which will be recorded by the feature test.
Stephen Kelly vor 12 Jahren
Ursprung
Commit
faeddf64f2

+ 2 - 0
Help/manual/cmake-variables.7.rst

@@ -257,6 +257,8 @@ Variables for Languages
    :maxdepth: 1
 
    /variable/CMAKE_COMPILER_IS_GNULANG
+   /variable/CMAKE_CXX_COMPILE_FEATURES
+   /variable/CMAKE_CXX_KNOWN_FEATURES
    /variable/CMAKE_CXX_STANDARD
    /variable/CMAKE_CXX_EXTENSIONS
    /variable/CMAKE_Fortran_MODDIR_DEFAULT

+ 8 - 0
Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst

@@ -0,0 +1,8 @@
+CMAKE_CXX_COMPILE_FEATURES
+--------------------------
+
+List of features known to the C++ compiler
+
+These features are known to be available for use with the C++ compiler. This
+list is a subset of the features listed in the :variable:`CMAKE_CXX_KNOWN_FEATURES`
+variable.

+ 8 - 0
Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst

@@ -0,0 +1,8 @@
+CMAKE_CXX_KNOWN_FEATURES
+------------------------
+
+List of C++ features known to this version of CMake.
+
+The features listed in this variable may be known to be available to the
+C++ compiler.  If the feature is available with the C++ compiler, it will
+be listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable.

+ 3 - 0
Modules/CMakeCXXCompiler.cmake.in

@@ -2,6 +2,9 @@ set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
 set(CMAKE_CXX_COMPILER_ARG1 "@CMAKE_CXX_COMPILER_ARG1@")
 set(CMAKE_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@")
 set(CMAKE_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@")
+set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
+set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
+
 set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
 set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
 set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@")

+ 43 - 0
Modules/CMakeDetermineCompileFeatures.cmake

@@ -0,0 +1,43 @@
+
+#=============================================================================
+# Copyright 2013 Stephen Kelly <[email protected]>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+function(cmake_determine_compile_features lang)
+
+  if(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features)
+    message(STATUS "Detecting ${lang} compile features")
+
+    set(CMAKE_CXX11_COMPILE_FEATURES)
+
+    include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
+
+    cmake_record_cxx_compile_features()
+
+    if(NOT _result EQUAL 0)
+      message(STATUS "Detecting ${lang} compile features - failed")
+      return()
+    endif()
+
+    if(NOT CMAKE_CXX_COMPILE_FEATURES)
+      set(CMAKE_CXX_COMPILE_FEATURES
+        ${CMAKE_CXX11_COMPILE_FEATURES}
+      )
+    endif()
+
+    set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE)
+    set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
+
+    message(STATUS "Detecting ${lang} compile features - done")
+  endif()
+
+endfunction()

+ 3 - 0
Modules/CMakeTestCXXCompiler.cmake

@@ -66,6 +66,9 @@ else()
   # Try to identify the ABI and configure it into CMakeCXXCompiler.cmake
   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
   CMAKE_DETERMINE_COMPILER_ABI(CXX ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp)
+  # Try to identify the compiler features
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+  CMAKE_DETERMINE_COMPILE_FEATURES(CXX)
 
   # Re-configure to save learned information.
   configure_file(

+ 57 - 0
Modules/Internal/FeatureTesting.cmake

@@ -0,0 +1,57 @@
+
+macro(record_compiler_features lang compile_flags feature_list)
+  include("${CMAKE_ROOT}/Modules/Compiler/${CMAKE_${lang}_COMPILER_ID}-${lang}-FeatureTests.cmake" OPTIONAL)
+
+  string(TOLOWER ${lang} lang_lc)
+  file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
+  file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "
+  extern const char features[] = {\"\"\n")
+  foreach(feature ${CMAKE_${lang}_KNOWN_FEATURES})
+    if (_cmake_feature_test_${feature})
+      if (${_cmake_feature_test_${feature}} STREQUAL 1)
+        set(_feature_condition "\"1\" ")
+      else()
+        set(_feature_condition "#if ${_cmake_feature_test_${feature}}\n\"1\"\n#else\n\"0\"\n#endif\n")
+      endif()
+      file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "\"${lang}_FEATURE:\"\n${_feature_condition}\"${feature}\\n\"\n")
+    endif()
+  endforeach()
+  file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
+    "\n};\n\nint main(int, char **) { return 0; }\n")
+
+  try_compile(CMAKE_${lang}_FEATURE_TEST
+    ${CMAKE_BINARY_DIR} "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
+    COMPILE_DEFINITIONS "${compile_flags}"
+    OUTPUT_VARIABLE _output
+    COPY_FILE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
+    COPY_FILE_ERROR _copy_error
+    )
+  if(CMAKE_${lang}_FEATURE_TEST AND NOT _copy_error)
+    set(_result 0)
+  else()
+    set(_result 255)
+  endif()
+  unset(CMAKE_${lang}_FEATURE_TEST CACHE)
+
+  if (_result EQUAL 0)
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "\n\nDetecting ${lang} [${compile_flags}] compiler features compiled with the following output:\n${_output}\n\n")
+    if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
+      file(STRINGS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
+        features REGEX "${lang}_FEATURE:.*")
+      foreach(info ${features})
+        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+          "    Feature record: ${info}\n")
+        string(REPLACE "${lang}_FEATURE:" "" info ${info})
+        string(SUBSTRING ${info} 0 1 has_feature)
+        if(has_feature)
+          string(REGEX REPLACE "^1" "" feature ${info})
+          list(APPEND ${feature_list} ${feature})
+        endif()
+      endforeach()
+    endif()
+  else()
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Detecting ${lang} [${compile_flags}] compiler features failed to compile with the following output:\n${_output}\n${_copy_error}\n\n")
+  endif()
+endmacro()