Merge topic 'vs-clang-cl-c++23'

30139913e9 VS: Restore support for mixing C++23 and C in one target with clang-cl
57da8712c1 VS: Factor out check for mixed C and C++ target

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !10082
This commit is contained in:
Brad King
2024-12-10 14:11:54 +00:00
committed by Kitware Robot
3 changed files with 44 additions and 15 deletions

View File

@@ -255,6 +255,11 @@ macro(__compiler_clang_cxx_standards lang)
endif()
if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "17.0")
# This version of clang-cl does not have a -std:c++23 flag.
# Pass the standard through to the underlying clang directly.
# Note that cmVisualStudio10TargetGenerator::ComputeClOptions
# has a special case to map this back to -std:c++latest in .vcxproj
# files that also have C sources.
set(CMAKE_${lang}23_STANDARD_COMPILE_OPTION "-clang:-std=c++23")
set(CMAKE_${lang}23_EXTENSION_COMPILE_OPTION "-clang:-std=c++23")
set(CMAKE_${lang}_STANDARD_LATEST 23)

View File

@@ -3375,6 +3375,14 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
langForClCompile, configName);
}
bool const isCXXwithC = [this, &configName]() -> bool {
if (this->LangForClCompile != "CXX"_s) {
return false;
}
std::set<std::string> languages;
this->GeneratorTarget->GetLanguages(languages, configName);
return languages.find("C") != languages.end();
}();
// Put the IPO enabled configurations into a set.
if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) {
@@ -3493,6 +3501,20 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
}
if (isCXXwithC) {
// Modules/Compiler/Clang.cmake has a special case for clang-cl versions
// that do not have a -std:c++23 flag to pass the standard through to the
// underlying clang directly. Unfortunately that flag applies to all
// sources in a single .vcxproj file, so if we have C sources too then we
// cannot use it. Map it back to -std::c++latest, even though that might
// end up enabling C++26 or later, so it does not apply to C sources.
static const std::string kClangStdCxx23 = "-clang:-std=c++23";
std::string::size_type p = flags.find(kClangStdCxx23);
if (p != std::string::npos) {
flags.replace(p, kClangStdCxx23.size(), "-std:c++latest");
}
}
clOptions.Parse(flags);
clOptions.Parse(defineFlags);
std::vector<std::string> targetDefines;
@@ -3525,21 +3547,17 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
// Add C-specific flags expressible in a ClCompile meant for C++.
if (langForClCompile == "CXX"_s) {
std::set<std::string> languages;
this->GeneratorTarget->GetLanguages(languages, configName);
if (languages.count("C")) {
std::string flagsC;
this->LocalGenerator->AddLanguageFlags(
flagsC, this->GeneratorTarget, cmBuildStep::Compile, "C", configName);
this->LocalGenerator->AddCompileOptions(flagsC, this->GeneratorTarget,
"C", configName);
Options optC(this->LocalGenerator, Options::Compiler,
gg->GetClFlagTable());
optC.Parse(flagsC);
if (const char* stdC = optC.GetFlag("LanguageStandard_C")) {
clOptions.AddFlag("LanguageStandard_C", stdC);
}
if (isCXXwithC) {
std::string flagsC;
this->LocalGenerator->AddLanguageFlags(
flagsC, this->GeneratorTarget, cmBuildStep::Compile, "C", configName);
this->LocalGenerator->AddCompileOptions(flagsC, this->GeneratorTarget, "C",
configName);
Options optC(this->LocalGenerator, Options::Compiler,
gg->GetClFlagTable());
optC.Parse(flagsC);
if (const char* stdC = optC.GetFlag("LanguageStandard_C")) {
clOptions.AddFlag("LanguageStandard_C", stdC);
}
}

View File

@@ -32,6 +32,12 @@ foreach(lang C CXX CUDA HIP)
endforeach()
endforeach()
if(("23" IN_LIST CMake_TEST_CXX_STANDARDS OR CMAKE_CXX23_STANDARD_COMPILE_OPTION)
AND ("11" IN_LIST CMake_TEST_C_STANDARDS OR CMAKE_C11_STANDARD_COMPILE_OPTION))
add_library(test_cxx_std_23_with_c_std_11 OBJECT cxx_std_23.cpp c_std_11.c)
target_compile_features(test_cxx_std_23_with_c_std_11 PRIVATE cxx_std_23 c_std_11)
endif()
macro(run_test feature lang)
if (${feature} IN_LIST CMAKE_${lang}_COMPILE_FEATURES)
add_library(test_${feature} OBJECT ${feature}.${ext_${lang}})