浏览代码

Autogen: Fix multi-config generated file issue

The default config was an empty string when a `multi-config`
generator is used. An if check was added for those situations.
If a source file has a specific config configuration,
it is used with `$<CONFIG>` in the `multi-config` generator usage.

Fixes: #24848
Orkun Tokdemir 2 年之前
父节点
当前提交
2bb3d9b644

+ 39 - 10
Source/cmQtAutoGenInitializer.cxx

@@ -662,8 +662,6 @@ bool cmQtAutoGenInitializer::InitMoc()
       return sanitizer(dirs);
     };
 
-    // Default configuration include directories
-    this->Moc.Includes.Default = getDirs(this->ConfigDefault);
     // Other configuration settings
     if (this->MultiConfig) {
       for (std::string const& cfg : this->ConfigsList) {
@@ -673,6 +671,9 @@ bool cmQtAutoGenInitializer::InitMoc()
         }
         this->Moc.Includes.Config[cfg] = std::move(dirs);
       }
+    } else {
+      // Default configuration include directories
+      this->Moc.Includes.Default = getDirs(this->ConfigDefault);
     }
   }
 
@@ -690,8 +691,6 @@ bool cmQtAutoGenInitializer::InitMoc()
       return defines;
     };
 
-    // Default configuration defines
-    this->Moc.Defines.Default = getDefs(this->ConfigDefault);
     // Other configuration defines
     if (this->MultiConfig) {
       for (std::string const& cfg : this->ConfigsList) {
@@ -701,6 +700,9 @@ bool cmQtAutoGenInitializer::InitMoc()
         }
         this->Moc.Defines.Config[cfg] = std::move(defines);
       }
+    } else {
+      // Default configuration defines
+      this->Moc.Defines.Default = getDefs(this->ConfigDefault);
     }
   }
 
@@ -1024,8 +1026,24 @@ bool cmQtAutoGenInitializer::InitScanFiles()
   if (this->MocOrUicEnabled() && !this->AutogenTarget.FilesGenerated.empty()) {
     if (this->CMP0071Accept) {
       // Let the autogen target depend on the GENERATED files
-      for (MUFile* muf : this->AutogenTarget.FilesGenerated) {
-        this->AutogenTarget.DependFiles.insert(muf->FullPath);
+      if (this->MultiConfig &&
+          this->Makefile->GetSafeDefinition("CMAKE_CROSS_CONFIGS").empty()) {
+        for (MUFile const* muf : this->AutogenTarget.FilesGenerated) {
+          if (muf->Configs.empty()) {
+            this->AutogenTarget.DependFiles.insert(muf->FullPath);
+          } else {
+            for (size_t ci : muf->Configs) {
+              std::string const& config = this->ConfigsList[ci];
+              std::string const& pathWithConfig =
+                cmStrCat("$<$<CONFIG:", config, ">:", muf->FullPath, '>');
+              this->AutogenTarget.DependFiles.insert(pathWithConfig);
+            }
+          }
+        }
+      } else {
+        for (MUFile const* muf : this->AutogenTarget.FilesGenerated) {
+          this->AutogenTarget.DependFiles.insert(muf->FullPath);
+        }
       }
     } else if (this->CMP0071Warn) {
       cm::string_view property;
@@ -1738,10 +1756,21 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
       this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr);
     EvaluatedTargetPropertyEntries InterfaceAutoMocMacroNamesEntries;
 
-    AddInterfaceEntries(this->GenTarget, this->ConfigDefault,
-                        "INTERFACE_AUTOMOC_MACRO_NAMES", "CXX", &dagChecker,
-                        InterfaceAutoMocMacroNamesEntries,
-                        IncludeRuntimeInterface::Yes);
+    if (this->MultiConfig) {
+      for (auto const& cfg : this->ConfigsList) {
+        if (!cfg.empty()) {
+          AddInterfaceEntries(this->GenTarget, cfg,
+                              "INTERFACE_AUTOMOC_MACRO_NAMES", "CXX",
+                              &dagChecker, InterfaceAutoMocMacroNamesEntries,
+                              IncludeRuntimeInterface::Yes);
+        }
+      }
+    } else {
+      AddInterfaceEntries(this->GenTarget, this->ConfigDefault,
+                          "INTERFACE_AUTOMOC_MACRO_NAMES", "CXX", &dagChecker,
+                          InterfaceAutoMocMacroNamesEntries,
+                          IncludeRuntimeInterface::Yes);
+    }
 
     for (auto const& entry : InterfaceAutoMocMacroNamesEntries.Entries) {
       this->Moc.MacroNames.insert(this->Moc.MacroNames.end(),

+ 15 - 0
Tests/RunCMake/Autogen/MocGeneratedFile.cmake

@@ -0,0 +1,15 @@
+enable_language(CXX)
+
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core)
+
+set(CMAKE_AUTOMOC ON)
+
+set(GEN_SRC "class_$<CONFIG>.cpp")
+add_custom_command(
+  OUTPUT "${GEN_SRC}"
+  COMMAND ${CMAKE_COMMAND} -E echo "// cpp src" > "${GEN_SRC}"
+  VERBATIM
+)
+
+add_library(libgen STATIC ${GEN_SRC})
+target_link_libraries(libgen Qt${with_qt_version}::Core)

+ 19 - 0
Tests/RunCMake/Autogen/RunCMakeTest.cmake

@@ -103,4 +103,23 @@ if (DEFINED with_qt_version)
       endblock()
     endif()
   endif()
+
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG AND NOT RunCMake_GENERATOR MATCHES "Xcode")
+    block()
+      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocGeneratedFile-build)
+      run_cmake(MocGeneratedFile)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      run_cmake_command(MocGeneratedFile-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+    if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+      block()
+        set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocGeneratedFile-cross-config-build)
+        list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_CROSS_CONFIGS=all)
+        run_cmake(MocGeneratedFile)
+        set(RunCMake_TEST_NO_CLEAN 1)
+        run_cmake_command(MocGeneratedFile-cross-config-build ${CMAKE_COMMAND} --build . --config Release --target libgen:Debug)
+        run_cmake_command(MocGeneratedFile-cross-config-build ${CMAKE_COMMAND} --build . --config Debug --target libgen:Release)
+      endblock()
+    endif()
+  endif()
 endif ()