Просмотр исходного кода

cxxmodules: Scan only targets that explicitly enable C++ 20

Previously we scanned any targets for which C++ 20 is enabled,
even if enabled only by the compiler's default, such as when
`CXXFLAGS=-std=c++20`.
Brad King 2 лет назад
Родитель
Сommit
b8ead378de

+ 5 - 7
Source/cmGeneratorTarget.cxx

@@ -9142,13 +9142,11 @@ cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
   }
 
   cmStandardLevelResolver standardResolver(this->Makefile);
-  if (!standardResolver.HaveStandardAvailable(this, "CXX", config,
-                                              "cxx_std_20") ||
-      // During the ABI detection step we do not know the compiler's features.
-      // HaveStandardAvailable may return true as a fallback, but in this code
-      // path we do not want to assume C++ 20 is available.
-      this->Makefile->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")
-        .IsEmpty()) {
+  cmStandardLevel const cxxStd20 =
+    *standardResolver.LanguageStandardLevel("CXX", "20");
+  cm::optional<cmStandardLevel> explicitLevel =
+    this->GetExplicitStandardLevel("CXX", config);
+  if (!explicitLevel || *explicitLevel < cxxStd20) {
     return Cxx20SupportLevel::NoCxx20;
   }
 

+ 13 - 0
Tests/RunCMake/CXXModules/ImplicitCXX20.cmake

@@ -0,0 +1,13 @@
+# Enable scanning by default for targets that explicitly use C++ 20.
+cmake_policy(SET CMP0155 NEW)
+
+# Force CMAKE_CXX_STANDARD_DEFAULT to be C++ 20.
+set(ENV{CXXFLAGS} "$ENV{CXXFLAGS} ${CMAKE_CXX20_STANDARD_COMPILE_OPTION}")
+enable_language(CXX)
+
+# Hide any real scanning rule that may be available.
+unset(CMAKE_CXX_SCANDEP_SOURCE)
+
+# Create a target that does not explicitly use C++ 20 to verify it works
+# without any scanning rule available.
+add_executable(cmp0155-new sources/module-use.cxx)

+ 2 - 0
Tests/RunCMake/CXXModules/Inspect.cmake

@@ -23,6 +23,8 @@ set(forced_cxx_standard \"${forced_cxx_standard}\")
 set(CMAKE_CXX_COMPILER_VERSION \"${CMAKE_CXX_COMPILER_VERSION}\")
 set(CMAKE_CXX_OUTPUT_EXTENSION \"${CMAKE_CXX_OUTPUT_EXTENSION}\")
 set(CXXModules_default_build_type \"${CMAKE_BUILD_TYPE}\")
+set(CMAKE_CXX_STANDARD_DEFAULT \"${CMAKE_CXX_STANDARD_DEFAULT}\")
+set(CMAKE_CXX20_STANDARD_COMPILE_OPTION \"${CMAKE_CXX20_STANDARD_COMPILE_OPTION}\")
 ")
 
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")

+ 3 - 0
Tests/RunCMake/CXXModules/RunCMakeTest.cmake

@@ -13,6 +13,9 @@ if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
   # standard. If the compiler forces a standard to be used, skip it.
   if (NOT forced_cxx_standard)
     run_cmake(NoCXX20)
+    if(CMAKE_CXX_STANDARD_DEFAULT AND CMAKE_CXX20_STANDARD_COMPILE_OPTION)
+      run_cmake_with_options(ImplicitCXX20 -DCMAKE_CXX20_STANDARD_COMPILE_OPTION=${CMAKE_CXX20_STANDARD_COMPILE_OPTION})
+    endif()
   endif ()
 
   run_cmake(NoScanningSourceFileProperty)