From b3e28587dba17ce4e9f2e84fc5564218c2c6c13e Mon Sep 17 00:00:00 2001 From: Caesar Wirth Date: Mon, 22 Sep 2025 15:21:37 +0900 Subject: [PATCH 1/2] Add a 'Dependency.excludeFromTransitiveLinking' property --- Sources/ProjectSpec/Dependency.swift | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index f7a72c0a9..2d0ca2d25 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -5,6 +5,7 @@ public struct Dependency: Equatable { public static let removeHeadersDefault = true public static let implicitDefault = false public static let weakLinkDefault = false + public static let excludeFromTransitiveLinkingDefault = false public static let platformFilterDefault: PlatformFilter = .all public var type: DependencyType @@ -15,6 +16,7 @@ public struct Dependency: Equatable { public var link: Bool? public var implicit: Bool = implicitDefault public var weakLink: Bool = weakLinkDefault + public var excludeFromTransitiveLinking: Bool = excludeFromTransitiveLinkingDefault public var platformFilter: PlatformFilter = platformFilterDefault public var destinationFilters: [SupportedDestination]? public var platforms: Set? @@ -28,6 +30,7 @@ public struct Dependency: Equatable { link: Bool? = nil, implicit: Bool = implicitDefault, weakLink: Bool = weakLinkDefault, + excludeFromTransitiveLinking: Bool = excludeFromTransitiveLinkingDefault, platformFilter: PlatformFilter = platformFilterDefault, destinationFilters: [SupportedDestination]? = nil, platforms: Set? = nil, @@ -40,6 +43,7 @@ public struct Dependency: Equatable { self.link = link self.implicit = implicit self.weakLink = weakLink + self.excludeFromTransitiveLinking = excludeFromTransitiveLinking self.platformFilter = platformFilter self.destinationFilters = destinationFilters self.platforms = platforms @@ -139,13 +143,16 @@ extension Dependency: JSONObjectConvertible { if let bool: Bool = jsonDictionary.json(atKeyPath: "weak") { weakLink = bool } - + if let bool: Bool = jsonDictionary.json(atKeyPath: "excludeFromTransitiveLinking") { + excludeFromTransitiveLinking = bool + } + if let platformFilterString: String = jsonDictionary.json(atKeyPath: "platformFilter"), let platformFilter = PlatformFilter(rawValue: platformFilterString) { self.platformFilter = platformFilter } else { self.platformFilter = .all } - + if let destinationFilters: [SupportedDestination] = jsonDictionary.json(atKeyPath: "destinationFilters") { self.destinationFilters = destinationFilters } @@ -180,6 +187,9 @@ extension Dependency: JSONEncodable { if weakLink != Dependency.weakLinkDefault { dict["weak"] = weakLink } + if excludeFromTransitiveLinking != Dependency.excludeFromTransitiveLinkingDefault { + dict["excludeFromTransitiveLinking"] = excludeFromTransitiveLinking + } switch type { case .target: From 3f5a304bf56a82793db079ef2c9e1c2733ea6be3 Mon Sep 17 00:00:00 2001 From: Caesar Wirth Date: Mon, 22 Sep 2025 17:00:24 +0900 Subject: [PATCH 2/2] Omit dependencies that specify they don't want to be linked transitively --- Sources/XcodeGenKit/PBXProjGenerator.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 8dcad5afb..75eba608d 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -1569,6 +1569,11 @@ public class PBXProjGenerator { continue } + // don't include dependencies from lower levels if they ask to not be included in transitive linking + if !isTopLevel && dependency.excludeFromTransitiveLinking { + continue + } + // don't want a dependency if it's going to be embedded or statically linked in a non-top level target // in .target check we filter out targets that will embed all of their dependencies // For some more context about the `dependency.embed != true` lines, refer to https://github.com/yonaskolb/XcodeGen/pull/820