Browse Source

Features: Add infrastructure for C++ 17 language standard

Issue: #16468
pull/162/merge
Brad King 9 years ago
parent
commit
ae1a6815b6
  1. 3
      Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
  2. 2
      Help/prop_tgt/CXX_STANDARD.rst
  3. 4
      Modules/CMakeCUDACompilerId.cu.in
  4. 1
      Modules/CMakeCXXCompiler.cmake.in
  5. 4
      Modules/CMakeCXXCompilerId.cpp.in
  6. 6
      Modules/CMakeDetermineCompileFeatures.cmake
  7. 1
      Modules/Compiler/MSVC-CXX.cmake
  8. 1
      Source/cmLocalGenerator.cxx
  9. 33
      Source/cmMakefile.cxx
  10. 3
      Source/cmMakefile.h
  11. 1
      Source/cmake.h
  12. 3
      Tests/CompileFeatures/CMakeLists.txt
  13. 6
      Tests/CompileFeatures/default_dialect.cpp

3
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_.

2
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

4
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
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@")

4
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
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
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
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");

33
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) {

3
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
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) \

3
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>

6
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

Loading…
Cancel
Save