1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-15 03:48:02 +08:00

VS: Restore support for mixing C++23 and C in one target with clang-cl

Since commit 474eafe28c (clang-cl: Add support for C++23, 2024-09-13,
v3.31.0-rc1~97^2) we use a Clang-specific flag to enable C++23 since
`clang-cl` has no `-std:c++23` flag, and `-std:c++latest` may enable an
even newer version of C++.  However, in `.vcxproj` files there is no way
to express a target-wide `-clang:-std=c++23` flag for only C++ sources
when the target also has C sources.  Add a special case to map back to
`-std:c++latest` for targets with C++23 and C together.

Fixes: #26508
This commit is contained in:
Brad King
2024-12-09 12:27:44 -05:00
parent 57da8712c1
commit 30139913e9
3 changed files with 25 additions and 0 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

@@ -3480,6 +3480,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;

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}})