Fix dependency diagnostics for dynamic target variants#1457
Merged
owenv merged 1 commit intoJun 17, 2026
Conversation
Contributor
Author
|
@swift-ci test |
Collaborator
|
@swift-ci test |
Collaborator
|
Linux CI may temporarily fail until swiftlang/swift#89917 lands in a toolchain. |
Collaborator
|
@swift-ci test |
Collaborator
|
@yimajo could you please rebase this on |
bb8cefb to
df71c8b
Compare
Contributor
Author
|
@swift-ci test |
Collaborator
|
@swift-ci test |
owenv
approved these changes
Jun 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A missing target dependency warning or error can be emitted during dependency scanning even when the target dependency is configured correctly.
Example warning:
In this case, FirebaseCore does have a dependency on FirebaseCoreInternal, but the warning can still be emitted.
This issue can be reproduced with a small test case.
The problem happens when the dependent target is replaced with a dynamic variant. swift-build has logic that changes targets to be dynamically linked, and dependency validation needs to use the result of that transformation.
Cause
BuildOperation.transitiveDependencyExists(target:antecedent:)checks whether target can reachantecedentusing the dependency graph built fromBuildDescription.targetDependencies.However,
BuildDescription.targetDependencieswas populated withbuildGraph.targetDependenciesByGuid, which represents the pre-dynamic-linkage target graph.As a result, even when the actual task was executed for a post-dynamic-linkage target, the dependency graph used for reachability checks was still based on the pre-dynamic-linkage target.
This caused the reachability check from the post-dynamic-linkage target to its dependency target to fail, and swift-build could emit a missing target dependency warning/error even though the target dependency was configured correctly.
Changes
Add GlobalProductPlan.targetDependenciesByGuid
This PR adds targetDependenciesByGuid to GlobalProductPlan.
This property builds target dependency relationships from GlobalProductPlan.allTargets and
GlobalProductPlan.resolvedDependencies(of:), so the relationships are based on the post-dynamic-linkage target graph.BuildDescriptionconstruction now passesGlobalProductPlan.targetDependenciesByGuidinstead ofTargetBuildGraph.targetDependenciesByGuid.This makes dependency validation use the same post-dynamic-linkage target graph when the dependent target has been replaced with a dynamic variant.
Build
definingTargetsByModuleNamefromGlobalProductPlanThe dependency target can also be a post-dynamic-linkage target.
For that reason,
definingTargetsByModuleName, which is used to resolve a dependency target from a module name, is now built fromplan.globalProductPlan.allTargetsinstead of buildGraph.allTargets.Test case
The regression test sets up a dynamically linked embedded framework named
macOSFwk.In this configuration, both
CommonandCorehave diamond linkage, so swift-build replaces them with dynamic variants.Commoncontainsimport Core, so dependency scanning detects a module dependency fromCommontoCore.Before this PR, the actual task was executed as
Common-dynamic, but the dependency graph used for the reachability check was built from the pre-dynamic-linkagebuildGraph.targetDependenciesByGuid. Therefore, dependency validation could not look up dependency relationships starting fromCommon-dynamic.Also,
definingTargetsByModuleName, which is used to resolve the dependency target from the module name, was not built fromGlobalProductPlan. Therefore, it treated the dependency target as the pre-dynamic-linkageCoreinstead of the post-dynamic-linkageCore-dynamic.As a result, a warning or error could be emitted even though the target dependency was configured correctly.
Not addressed in this PR
After this change,
BuildDescriptionconstruction no longer usesTargetBuildGraph.targetDependenciesByGuid. This PR keeps it in place because it is a public API. If reviewers think it should be removed, please let me know.