mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 14:08:35 +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:
@@ -255,6 +255,11 @@ macro(__compiler_clang_cxx_standards lang)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "17.0")
|
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_STANDARD_COMPILE_OPTION "-clang:-std=c++23")
|
||||||
set(CMAKE_${lang}23_EXTENSION_COMPILE_OPTION "-clang:-std=c++23")
|
set(CMAKE_${lang}23_EXTENSION_COMPILE_OPTION "-clang:-std=c++23")
|
||||||
set(CMAKE_${lang}_STANDARD_LATEST 23)
|
set(CMAKE_${lang}_STANDARD_LATEST 23)
|
||||||
|
@@ -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(flags);
|
||||||
clOptions.Parse(defineFlags);
|
clOptions.Parse(defineFlags);
|
||||||
std::vector<std::string> targetDefines;
|
std::vector<std::string> targetDefines;
|
||||||
|
@@ -32,6 +32,12 @@ foreach(lang C CXX CUDA HIP)
|
|||||||
endforeach()
|
endforeach()
|
||||||
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)
|
macro(run_test feature lang)
|
||||||
if (${feature} IN_LIST CMAKE_${lang}_COMPILE_FEATURES)
|
if (${feature} IN_LIST CMAKE_${lang}_COMPILE_FEATURES)
|
||||||
add_library(test_${feature} OBJECT ${feature}.${ext_${lang}})
|
add_library(test_${feature} OBJECT ${feature}.${ext_${lang}})
|
||||||
|
Reference in New Issue
Block a user