mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 19:00:54 -06:00
Features: Add infrastructure for C++ 20 language standard
Issue: #17849
This commit is contained in:
@@ -26,6 +26,9 @@ The features known to this version of CMake are:
|
||||
``cxx_std_17``
|
||||
Compiler mode is aware of C++ 17.
|
||||
|
||||
``cxx_std_20``
|
||||
Compiler mode is aware of C++ 20.
|
||||
|
||||
``cxx_aggregate_default_initializers``
|
||||
Aggregate default initializers, as defined in N3605_.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ flag such as ``-std=gnu++11`` to the compile line. For compilers that
|
||||
have no notion of a standard level, such as Microsoft Visual C++ before
|
||||
2015 Update 3, this has no effect.
|
||||
|
||||
Supported values are ``98``, ``11``, ``14``, and ``17``.
|
||||
Supported values are ``98``, ``11``, ``14``, ``17``, and ``20``.
|
||||
|
||||
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
|
||||
|
||||
@@ -17,7 +17,9 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
|
||||
@CMAKE_CUDA_COMPILER_ID_ERROR_FOR_TEST@
|
||||
|
||||
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
|
||||
#if __cplusplus > 201402L
|
||||
#if __cplusplus > 201703L
|
||||
"20"
|
||||
#elif __cplusplus >= 201703L
|
||||
"17"
|
||||
#elif __cplusplus >= 201402L
|
||||
"14"
|
||||
|
||||
@@ -10,6 +10,7 @@ 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_CXX20_COMPILE_FEATURES "@CMAKE_CXX20_COMPILE_FEATURES@")
|
||||
|
||||
set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
|
||||
set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
|
||||
|
||||
@@ -34,7 +34,9 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
|
||||
#endif
|
||||
|
||||
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
|
||||
#if CXX_STD > 201402L
|
||||
#if CXX_STD > 201703L
|
||||
"20"
|
||||
#elif CXX_STD >= 201703L
|
||||
"17"
|
||||
#elif CXX_STD >= 201402L
|
||||
"14"
|
||||
|
||||
@@ -49,6 +49,7 @@ function(cmake_determine_compile_features lang)
|
||||
set(CMAKE_CXX11_COMPILE_FEATURES)
|
||||
set(CMAKE_CXX14_COMPILE_FEATURES)
|
||||
set(CMAKE_CXX17_COMPILE_FEATURES)
|
||||
set(CMAKE_CXX20_COMPILE_FEATURES)
|
||||
|
||||
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
|
||||
|
||||
@@ -59,6 +60,9 @@ function(cmake_determine_compile_features lang)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX17_COMPILE_FEATURES AND CMAKE_CXX20_COMPILE_FEATURES)
|
||||
list(REMOVE_ITEM CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES})
|
||||
endif()
|
||||
if (CMAKE_CXX14_COMPILE_FEATURES AND CMAKE_CXX17_COMPILE_FEATURES)
|
||||
list(REMOVE_ITEM CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES})
|
||||
endif()
|
||||
@@ -75,6 +79,7 @@ function(cmake_determine_compile_features lang)
|
||||
${CMAKE_CXX11_COMPILE_FEATURES}
|
||||
${CMAKE_CXX14_COMPILE_FEATURES}
|
||||
${CMAKE_CXX17_COMPILE_FEATURES}
|
||||
${CMAKE_CXX20_COMPILE_FEATURES}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -83,6 +88,7 @@ function(cmake_determine_compile_features lang)
|
||||
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)
|
||||
set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE)
|
||||
|
||||
message(STATUS "Detecting ${lang} compile features - done")
|
||||
endif()
|
||||
|
||||
@@ -78,6 +78,9 @@ endmacro()
|
||||
# Define to allow compile features to be automatically determined
|
||||
macro(cmake_record_cxx_compile_features)
|
||||
set(_result 0)
|
||||
if(_result EQUAL 0 AND DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION)
|
||||
_record_compiler_features_cxx(20)
|
||||
endif()
|
||||
if(_result EQUAL 0 AND DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION)
|
||||
_record_compiler_features_cxx(17)
|
||||
endif()
|
||||
|
||||
@@ -49,6 +49,8 @@ else()
|
||||
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
|
||||
endif()
|
||||
|
||||
if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||
|
||||
@@ -29,6 +29,12 @@ if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND
|
||||
# for meta-features for C++14 and above. Override the default macro
|
||||
# to avoid doing unnecessary work.
|
||||
macro(cmake_record_cxx_compile_features)
|
||||
if (DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION)
|
||||
list(APPEND CMAKE_CXX20_COMPILE_FEATURES cxx_std_20)
|
||||
endif()
|
||||
# The main cmake_record_cxx_compile_features macro makes all
|
||||
# these conditional on CMAKE_CXX##_STANDARD_COMPILE_OPTION,
|
||||
# but we can skip the conditions because we set them above.
|
||||
list(APPEND CMAKE_CXX17_COMPILE_FEATURES cxx_std_17)
|
||||
list(APPEND CMAKE_CXX14_COMPILE_FEATURES cxx_std_14)
|
||||
list(APPEND CMAKE_CXX98_COMPILE_FEATURES cxx_std_11) # no flag needed for 11
|
||||
@@ -46,6 +52,8 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
|
||||
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
|
||||
|
||||
# There is no meaningful default for this
|
||||
set(CMAKE_CXX_STANDARD_DEFAULT "")
|
||||
@@ -60,6 +68,7 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
|
||||
cxx_std_11
|
||||
cxx_std_14
|
||||
cxx_std_17
|
||||
cxx_std_20
|
||||
)
|
||||
_record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
|
||||
endmacro()
|
||||
|
||||
@@ -1564,6 +1564,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("20");
|
||||
langStdMap["CXX"].push_back("17");
|
||||
langStdMap["CXX"].push_back("14");
|
||||
langStdMap["CXX"].push_back("11");
|
||||
|
||||
@@ -4223,7 +4223,7 @@ static const char* const CXX_FEATURES[] = { 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", "17" };
|
||||
static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" };
|
||||
|
||||
bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
|
||||
const std::string& feature,
|
||||
@@ -4473,8 +4473,9 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
|
||||
bool needCxx11 = false;
|
||||
bool needCxx14 = false;
|
||||
bool needCxx17 = false;
|
||||
bool needCxx20 = false;
|
||||
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
|
||||
needCxx17);
|
||||
needCxx17, needCxx20);
|
||||
|
||||
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
|
||||
if (!existingCxxStandard) {
|
||||
@@ -4494,7 +4495,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
|
||||
|
||||
/* clang-format off */
|
||||
const char* const* needCxxLevel =
|
||||
needCxx17 ? &CXX_STANDARDS[3]
|
||||
needCxx20 ? &CXX_STANDARDS[4]
|
||||
: needCxx17 ? &CXX_STANDARDS[3]
|
||||
: needCxx14 ? &CXX_STANDARDS[2]
|
||||
: needCxx11 ? &CXX_STANDARDS[1]
|
||||
: needCxx98 ? &CXX_STANDARDS[0]
|
||||
@@ -4506,7 +4508,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
|
||||
|
||||
void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
|
||||
bool& needCxx98, bool& needCxx11,
|
||||
bool& needCxx14, bool& needCxx17) const
|
||||
bool& needCxx14, bool& needCxx17,
|
||||
bool& needCxx20) const
|
||||
{
|
||||
if (const char* propCxx98 =
|
||||
this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
|
||||
@@ -4532,6 +4535,12 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
|
||||
cmSystemTools::ExpandListArgument(propCxx17, props);
|
||||
needCxx17 = std::find(props.begin(), props.end(), feature) != props.end();
|
||||
}
|
||||
if (const char* propCxx20 =
|
||||
this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) {
|
||||
std::vector<std::string> props;
|
||||
cmSystemTools::ExpandListArgument(propCxx20, props);
|
||||
needCxx20 = std::find(props.begin(), props.end(), feature) != props.end();
|
||||
}
|
||||
}
|
||||
|
||||
bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
|
||||
@@ -4542,9 +4551,10 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
|
||||
bool needCxx11 = false;
|
||||
bool needCxx14 = false;
|
||||
bool needCxx17 = false;
|
||||
bool needCxx20 = false;
|
||||
|
||||
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
|
||||
needCxx17);
|
||||
needCxx17, needCxx20);
|
||||
|
||||
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
|
||||
const char* const* existingCxxLevel = nullptr;
|
||||
@@ -4589,7 +4599,8 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
|
||||
|
||||
/* clang-format off */
|
||||
const char* const* needCxxLevel =
|
||||
needCxx17 ? &CXX_STANDARDS[3]
|
||||
needCxx20 ? &CXX_STANDARDS[4]
|
||||
: needCxx17 ? &CXX_STANDARDS[3]
|
||||
: needCxx14 ? &CXX_STANDARDS[2]
|
||||
: needCxx11 ? &CXX_STANDARDS[1]
|
||||
: needCxx98 ? &CXX_STANDARDS[0]
|
||||
|
||||
@@ -991,7 +991,7 @@ private:
|
||||
bool& needC99, bool& needC11) const;
|
||||
void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
|
||||
bool& needCxx11, bool& needCxx14,
|
||||
bool& needCxx17) const;
|
||||
bool& needCxx17, bool& needCxx20) const;
|
||||
|
||||
bool HaveCStandardAvailable(cmTarget const* target,
|
||||
const std::string& feature) const;
|
||||
|
||||
@@ -574,6 +574,7 @@ private:
|
||||
F(cxx_std_11) \
|
||||
F(cxx_std_14) \
|
||||
F(cxx_std_17) \
|
||||
F(cxx_std_20) \
|
||||
F(cxx_aggregate_default_initializers) \
|
||||
F(cxx_alias_templates) \
|
||||
F(cxx_alignas) \
|
||||
|
||||
@@ -280,6 +280,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_CXX20=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},20>
|
||||
DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
|
||||
DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
|
||||
DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
|
||||
@@ -434,6 +435,7 @@ else()
|
||||
HAVE_CXX_STD_11=$<COMPILE_FEATURES:cxx_std_11>
|
||||
HAVE_CXX_STD_14=$<COMPILE_FEATURES:cxx_std_14>
|
||||
HAVE_CXX_STD_17=$<COMPILE_FEATURES:cxx_std_17>
|
||||
HAVE_CXX_STD_20=$<COMPILE_FEATURES:cxx_std_20>
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -8,7 +8,11 @@ struct Outputter;
|
||||
#define CXX_STD __cplusplus
|
||||
#endif
|
||||
|
||||
#if DEFAULT_CXX17
|
||||
#if DEFAULT_CXX20
|
||||
#if CXX_STD <= 201703L
|
||||
Outputter<CXX_STD> o;
|
||||
#endif
|
||||
#elif DEFAULT_CXX17
|
||||
#if CXX_STD <= 201402L
|
||||
Outputter<CXX_STD> o;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user