Преглед изворни кода

Features: Add infrastructure for C++ 17 language standard

Issue: #16468
Brad King пре 9 година
родитељ
комит
ae1a6815b6

+ 3 - 0
Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst

@@ -23,6 +23,9 @@ The features known to this version of CMake are:
 ``cxx_std_14``
   Compiler mode is aware of C++ 14.
 
+``cxx_std_17``
+  Compiler mode is aware of C++ 17.
+
 ``cxx_aggregate_default_initializers``
   Aggregate default initializers, as defined in N3605_.
 

+ 1 - 1
Help/prop_tgt/CXX_STANDARD.rst

@@ -8,7 +8,7 @@ to build this target.  For some compilers, this results in adding a
 flag such as ``-std=gnu++11`` to the compile line.  For compilers that
 have no notion of a standard level, such as MSVC, this has no effect.
 
-Supported values are ``98``, ``11`` and ``14``.
+Supported values are ``98``, ``11``, ``14``, and ``17``.
 
 If the value requested does not result in a compile flag being added for
 the compiler in use, a previous standard flag will be added instead.  This

+ 3 - 1
Modules/CMakeCUDACompilerId.cu.in

@@ -14,7 +14,9 @@ char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
 @CMAKE_CUDA_COMPILER_ID_ERROR_FOR_TEST@
 
 const char* info_language_dialect_default = "INFO" ":" "dialect_default["
-#if __cplusplus >= 201402L
+#if __cplusplus > 201402L
+  "17"
+#elif __cplusplus >= 201402L
   "14"
 #elif __cplusplus >= 201103L
   "11"

+ 1 - 0
Modules/CMakeCXXCompiler.cmake.in

@@ -8,6 +8,7 @@ set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
 set(CMAKE_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@")
 set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
 set(CMAKE_CXX14_COMPILE_FEATURES "@CMAKE_CXX14_COMPILE_FEATURES@")
+set(CMAKE_CXX17_COMPILE_FEATURES "@CMAKE_CXX17_COMPILE_FEATURES@")
 
 set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
 set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")

+ 3 - 1
Modules/CMakeCXXCompilerId.cpp.in

@@ -28,7 +28,9 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
 @CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@
 
 const char* info_language_dialect_default = "INFO" ":" "dialect_default["
-#if __cplusplus >= 201402L
+#if __cplusplus > 201402L
+  "17"
+#elif __cplusplus >= 201402L
   "14"
 #elif __cplusplus >= 201103L
   "11"

+ 6 - 0
Modules/CMakeDetermineCompileFeatures.cmake

@@ -48,6 +48,7 @@ function(cmake_determine_compile_features lang)
     set(CMAKE_CXX98_COMPILE_FEATURES)
     set(CMAKE_CXX11_COMPILE_FEATURES)
     set(CMAKE_CXX14_COMPILE_FEATURES)
+    set(CMAKE_CXX17_COMPILE_FEATURES)
 
     include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
 
@@ -58,6 +59,9 @@ function(cmake_determine_compile_features lang)
       return()
     endif()
 
+    if (CMAKE_CXX14_COMPILE_FEATURES AND CMAKE_CXX17_COMPILE_FEATURES)
+      list(REMOVE_ITEM CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES})
+    endif()
     if (CMAKE_CXX11_COMPILE_FEATURES AND CMAKE_CXX14_COMPILE_FEATURES)
       list(REMOVE_ITEM CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES})
     endif()
@@ -70,6 +74,7 @@ function(cmake_determine_compile_features lang)
         ${CMAKE_CXX98_COMPILE_FEATURES}
         ${CMAKE_CXX11_COMPILE_FEATURES}
         ${CMAKE_CXX14_COMPILE_FEATURES}
+        ${CMAKE_CXX17_COMPILE_FEATURES}
       )
     endif()
 
@@ -77,6 +82,7 @@ function(cmake_determine_compile_features lang)
     set(CMAKE_CXX98_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES} PARENT_SCOPE)
+    set(CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES} PARENT_SCOPE)
 
     message(STATUS "Detecting ${lang} compile features - done")
   endif()

+ 1 - 0
Modules/Compiler/MSVC-CXX.cmake

@@ -10,6 +10,7 @@ macro(cmake_record_cxx_compile_features)
       cxx_std_98
       cxx_std_11
       cxx_std_14
+      cxx_std_17
       )
     _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
   endif()

+ 1 - 0
Source/cmLocalGenerator.cxx

@@ -1470,6 +1470,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
   static std::map<std::string, std::vector<std::string> > langStdMap;
   if (langStdMap.empty()) {
     // Maintain sorted order, most recent first.
+    langStdMap["CXX"].push_back("17");
     langStdMap["CXX"].push_back("14");
     langStdMap["CXX"].push_back("11");
     langStdMap["CXX"].push_back("98");

+ 26 - 7
Source/cmMakefile.cxx

@@ -4064,7 +4064,7 @@ static const char* const CXX_FEATURES[] = { CM_NULLPTR FOR_EACH_CXX_FEATURE(
 #undef FEATURE_STRING
 
 static const char* const C_STANDARDS[] = { "90", "99", "11" };
-static const char* const CXX_STANDARDS[] = { "98", "11", "14" };
+static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17" };
 
 bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
                                           const std::string& feature,
@@ -4297,7 +4297,9 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
   bool needCxx98 = false;
   bool needCxx11 = false;
   bool needCxx14 = false;
-  this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14);
+  bool needCxx17 = false;
+  this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+                               needCxx17);
 
   const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
   if (!existingCxxStandard) {
@@ -4336,7 +4338,7 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
 
 void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
                                         bool& needCxx98, bool& needCxx11,
-                                        bool& needCxx14) const
+                                        bool& needCxx14, bool& needCxx17) const
 {
   if (const char* propCxx98 =
         this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
@@ -4356,6 +4358,12 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
     cmSystemTools::ExpandListArgument(propCxx14, props);
     needCxx14 = std::find(props.begin(), props.end(), feature) != props.end();
   }
+  if (const char* propCxx17 =
+        this->GetDefinition("CMAKE_CXX17_COMPILE_FEATURES")) {
+    std::vector<std::string> props;
+    cmSystemTools::ExpandListArgument(propCxx17, props);
+    needCxx17 = std::find(props.begin(), props.end(), feature) != props.end();
+  }
 }
 
 bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
@@ -4365,8 +4373,10 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
   bool needCxx98 = false;
   bool needCxx11 = false;
   bool needCxx14 = false;
+  bool needCxx17 = false;
 
-  this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14);
+  this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+                               needCxx17);
 
   const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
   if (existingCxxStandard) {
@@ -4393,11 +4403,17 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
   bool setCxx98 = needCxx98 && !existingCxxStandard;
   bool setCxx11 = needCxx11 && !existingCxxStandard;
   bool setCxx14 = needCxx14 && !existingCxxStandard;
+  bool setCxx17 = needCxx17 && !existingCxxStandard;
 
-  if (needCxx14 && existingCxxStandard &&
+  if (needCxx17 && existingCxxStandard &&
       existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
                                    cmArrayEnd(CXX_STANDARDS),
-                                   cmStrCmp("14"))) {
+                                   cmStrCmp("17"))) {
+    setCxx17 = true;
+  } else if (needCxx14 && existingCxxStandard &&
+             existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
+                                          cmArrayEnd(CXX_STANDARDS),
+                                          cmStrCmp("14"))) {
     setCxx14 = true;
   } else if (needCxx11 && existingCxxStandard &&
              existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
@@ -4411,7 +4427,10 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
     setCxx98 = true;
   }
 
-  if (setCxx14) {
+  if (setCxx17) {
+    target->SetProperty("CXX_STANDARD", "17");
+    target->SetProperty("CUDA_STANDARD", "17");
+  } else if (setCxx14) {
     target->SetProperty("CXX_STANDARD", "14");
     target->SetProperty("CUDA_STANDARD", "14");
   } else if (setCxx11) {

+ 2 - 1
Source/cmMakefile.h

@@ -905,7 +905,8 @@ private:
   void CheckNeededCLanguage(const std::string& feature, bool& needC90,
                             bool& needC99, bool& needC11) const;
   void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
-                              bool& needCxx11, bool& needCxx14) const;
+                              bool& needCxx11, bool& needCxx14,
+                              bool& needCxx17) const;
 
   bool HaveCStandardAvailable(cmTarget const* target,
                               const std::string& feature) const;

+ 1 - 0
Source/cmake.h

@@ -549,6 +549,7 @@ private:
   F(cxx_std_98)                                                               \
   F(cxx_std_11)                                                               \
   F(cxx_std_14)                                                               \
+  F(cxx_std_17)                                                               \
   F(cxx_aggregate_default_initializers)                                       \
   F(cxx_alias_templates)                                                      \
   F(cxx_alignas)                                                              \

+ 2 - 1
Tests/CompileFeatures/CMakeLists.txt

@@ -28,7 +28,7 @@ foreach(feature ${c_features})
   run_test(${feature} C)
 endforeach()
 get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
-list(REMOVE_ITEM cxx_features cxx_std_98 cxx_std_11 cxx_std_14)
+list(REMOVE_ITEM cxx_features cxx_std_98 cxx_std_11 cxx_std_14 cxx_std_17)
 foreach(feature ${cxx_features})
   run_test(${feature} CXX)
 endforeach()
@@ -268,6 +268,7 @@ if (CMAKE_CXX_COMPILE_FEATURES)
     if (std_flag_idx EQUAL -1)
       add_executable(default_dialect default_dialect.cpp)
       target_compile_definitions(default_dialect PRIVATE
+        DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
         DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
         DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
         DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98>

+ 5 - 1
Tests/CompileFeatures/default_dialect.cpp

@@ -2,7 +2,11 @@
 template <long l>
 struct Outputter;
 
-#if DEFAULT_CXX14
+#if DEFAULT_CXX17
+#if __cplusplus <= 201402L
+Outputter<__cplusplus> o;
+#endif
+#elif DEFAULT_CXX14
 #if __cplusplus != 201402L
 Outputter<__cplusplus> o;
 #endif