summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-11-30 20:25:01 (GMT)
committerBrad King <brad.king@kitware.com>2016-12-02 16:22:46 (GMT)
commitae1a6815b6e2c0a45df51e994b75f9005e1794fe (patch)
treec8ccf890ced342e9287c8115ac525d062cb6ce0b
parent684e4d205d64ff8b98c00a1d6a358bffbf509c62 (diff)
downloadCMake-ae1a6815b6e2c0a45df51e994b75f9005e1794fe.zip
CMake-ae1a6815b6e2c0a45df51e994b75f9005e1794fe.tar.gz
CMake-ae1a6815b6e2c0a45df51e994b75f9005e1794fe.tar.bz2
Features: Add infrastructure for C++ 17 language standard
Issue: #16468
-rw-r--r--Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst3
-rw-r--r--Help/prop_tgt/CXX_STANDARD.rst2
-rw-r--r--Modules/CMakeCUDACompilerId.cu.in4
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in1
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in4
-rw-r--r--Modules/CMakeDetermineCompileFeatures.cmake6
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake1
-rw-r--r--Source/cmLocalGenerator.cxx1
-rw-r--r--Source/cmMakefile.cxx33
-rw-r--r--Source/cmMakefile.h3
-rw-r--r--Source/cmake.h1
-rw-r--r--Tests/CompileFeatures/CMakeLists.txt3
-rw-r--r--Tests/CompileFeatures/default_dialect.cpp6
13 files changed, 55 insertions, 13 deletions
diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
index 00a5104..2ad8157 100644
--- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/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_.
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index 5b186c1..30a612d 100644
--- a/Help/prop_tgt/CXX_STANDARD.rst
+++ b/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
diff --git a/Modules/CMakeCUDACompilerId.cu.in b/Modules/CMakeCUDACompilerId.cu.in
index 5fa85da..a20f1b1 100644
--- a/Modules/CMakeCUDACompilerId.cu.in
+++ b/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"
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index c295b74..6d56488 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/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@")
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index 3e5c0fc..9aa096d 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/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"
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index 5ca72cc..3ed92be 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/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()
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
index f103832..8fcfa0f 100644
--- a/Modules/Compiler/MSVC-CXX.cmake
+++ b/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()
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 46e49dc..ead1e72 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/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");
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index fecc983..ed0f73b 100644
--- a/Source/cmMakefile.cxx
+++ b/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) {
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 859b3c8..3484e5a 100644
--- a/Source/cmMakefile.h
+++ b/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;
diff --git a/Source/cmake.h b/Source/cmake.h
index 0f1891d..5347745 100644
--- a/Source/cmake.h
+++ b/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) \
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
index 8acdd93..0405def 100644
--- a/Tests/CompileFeatures/CMakeLists.txt
+++ b/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>
diff --git a/Tests/CompileFeatures/default_dialect.cpp b/Tests/CompileFeatures/default_dialect.cpp
index 0efaefa..9b65b42 100644
--- a/Tests/CompileFeatures/default_dialect.cpp
+++ b/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