From 579472d877fb6a953d0d554e05578c17a1974612 Mon Sep 17 00:00:00 2001 From: Evan Wilde Date: Fri, 5 Apr 2024 14:13:22 -0700 Subject: Swift: Ninja: Remove module dependency for executables We shouldn't include the swiftmodule in the ninja dependency graph unless that target emits a swiftmodule. Fixes: #25869 --- Source/cmNinjaTargetGenerator.cxx | 41 ++++++++++++++++++++++++++------------- Tests/SwiftOnly/CMakeLists.txt | 3 +++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index d4bbaa0..e2642b2 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -2016,11 +2016,21 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement( this->LocalGenerator->AppendFlags(vars["FLAGS"], "-static"); } + // Does this swift target emit a module file for importing into other + // targets? + auto isImportableTarget = [](cmGeneratorTarget const& tgt) -> bool { + // Everything except for executables that don't export anything should emit + // some way to import them. + if (tgt.GetType() == cmStateEnums::EXECUTABLE) { + return tgt.IsExecutableWithExports(); + } + return true; + }; + // Swift modules only make sense to emit from things that can be imported. // Executables that don't export symbols can't be imported, so don't try to // emit a swiftmodule for them. It will break. - if (target.GetType() != cmStateEnums::EXECUTABLE || - target.IsExecutableWithExports()) { + if (isImportableTarget(target)) { std::string const emitModuleFlag = "-emit-module"; std::string const modulePathFlag = "-emit-module-path"; this->LocalGenerator->AppendFlags( @@ -2089,18 +2099,21 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement( if (!dep->IsLanguageUsed("Swift", config)) { continue; } - // Add dependencies on the emitted swiftmodule file from swift targets we - // depend on - std::string const depModuleName = - getTargetPropertyOrDefault(*dep, "Swift_MODULE_NAME", dep->GetName()); - std::string const depModuleDir = getTargetPropertyOrDefault( - *dep, "Swift_MODULE_DIRECTORY", - dep->LocalGenerator->GetCurrentBinaryDirectory()); - std::string const depModuleFilename = getTargetPropertyOrDefault( - *dep, "Swift_MODULE", cmStrCat(depModuleName, ".swiftmodule")); - std::string const depModuleFilepath = - this->ConvertToNinjaPath(cmStrCat(depModuleDir, '/', depModuleFilename)); - objBuild.ImplicitDeps.push_back(depModuleFilepath); + + // If the dependency emits a swiftmodule, add a dependency edge on that + // swiftmodule to the ninja build graph. + if (isImportableTarget(*dep)) { + std::string const depModuleName = + getTargetPropertyOrDefault(*dep, "Swift_MODULE_NAME", dep->GetName()); + std::string const depModuleDir = getTargetPropertyOrDefault( + *dep, "Swift_MODULE_DIRECTORY", + dep->LocalGenerator->GetCurrentBinaryDirectory()); + std::string const depModuleFilename = getTargetPropertyOrDefault( + *dep, "Swift_MODULE", cmStrCat(depModuleName, ".swiftmodule")); + std::string const depModuleFilepath = this->ConvertToNinjaPath( + cmStrCat(depModuleDir, '/', depModuleFilename)); + objBuild.ImplicitDeps.push_back(depModuleFilepath); + } } objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config)); diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt index 2aa5710..c5a4b83 100644 --- a/Tests/SwiftOnly/CMakeLists.txt +++ b/Tests/SwiftOnly/CMakeLists.txt @@ -50,6 +50,9 @@ if(NOT XCODE_VERSION OR XCODE_VERSION VERSION_GREATER_EQUAL 9.0) set_target_properties(O PROPERTIES Swift_COMPILATION_MODE "incremental") endif() +add_library(P L.swift) +add_dependencies(P SwiftOnly) + # Dummy to make sure generation works with such targets. add_library(SwiftIface INTERFACE) target_link_libraries(SwiftOnly PRIVATE SwiftIface) -- cgit v0.12