Skip to content

Commit b426d12

Browse files
committed
Manifest changes for conditional target dependencies
1 parent 06c5e23 commit b426d12

File tree

17 files changed

+259
-162
lines changed

17 files changed

+259
-162
lines changed

Sources/Build/BuildPlan.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ extension BuildParameters {
8888

8989
/// Returns the scoped view of build settings for a given target.
9090
fileprivate func createScope(for target: ResolvedTarget) -> BuildSettings.Scope {
91-
return BuildSettings.Scope(target.underlyingTarget.buildSettings, boundCondition: (currentPlatform, configuration))
91+
return BuildSettings.Scope(
92+
target.underlyingTarget.buildSettings,
93+
environment: BuildEnvironment(platform: currentPlatform, configuration: configuration)
94+
)
9295
}
9396
}
9497

Sources/PackageDescription4/BuildSettings.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public struct BuildConfiguration: Encodable {
4545
/// .define("ENABLE_SOMETHING", .when(configuration: .release)),
4646
/// ],
4747
/// linkerSettings: [
48-
/// .linkLibrary("openssl", .when(platforms: [.linux])),
48+
/// .linkedLibrary("openssl", .when(platforms: [.linux])),
4949
/// ]
5050
/// ),
5151
public struct BuildSettingCondition: Encodable {
@@ -228,7 +228,7 @@ public struct SwiftSetting: Encodable {
228228
/// Use compilation conditions to only compile statements if a certain condition is true.
229229
/// For example, the Swift compiler will only compile the
230230
/// statements inside the `#if` block when `ENABLE_SOMETHING` is defined:
231-
///
231+
///
232232
/// #if ENABLE_SOMETHING
233233
/// ...
234234
/// #endif

Sources/PackageDescription4/Package.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ extension Target.Dependency: Encodable {
452452
case type
453453
case name
454454
case package
455+
case condition
455456
}
456457

457458
private enum Kind: String, Codable {
@@ -477,16 +478,19 @@ extension Target.Dependency: Encodable {
477478
}
478479
#else
479480
switch self {
480-
case ._targetItem(let name):
481+
case ._targetItem(let name, let condition):
481482
try container.encode(Kind.target, forKey: .type)
482483
try container.encode(name, forKey: .name)
483-
case ._productItem(let name, let package):
484+
try container.encode(condition, forKey: .condition)
485+
case ._productItem(let name, let package, let condition):
484486
try container.encode(Kind.product, forKey: .type)
485487
try container.encode(name, forKey: .name)
486488
try container.encode(package, forKey: .package)
487-
case ._byNameItem(let name):
489+
try container.encode(condition, forKey: .condition)
490+
case ._byNameItem(let name, let condition):
488491
try container.encode(Kind.byName, forKey: .type)
489492
try container.encode(name, forKey: .name)
493+
try container.encode(condition, forKey: .condition)
490494
}
491495
#endif
492496
}

Sources/PackageDescription4/Target.swift

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ public final class Target {
3333
case productItem(name: String, package: String?)
3434
case byNameItem(name: String)
3535
#else
36-
case _targetItem(name: String)
37-
case _productItem(name: String, package: String?)
38-
case _byNameItem(name: String)
36+
case _targetItem(name: String, condition: BuildSettingCondition?)
37+
case _productItem(name: String, package: String?, condition: BuildSettingCondition?)
38+
case _byNameItem(name: String, condition: BuildSettingCondition?)
3939
#endif
4040
}
4141

@@ -490,11 +490,12 @@ extension Target.Dependency {
490490
///
491491
/// - parameters:
492492
/// - name: The name of the target.
493+
@available(_PackageDescription, obsoleted: 5.2)
493494
public static func target(name: String) -> Target.Dependency {
494495
#if PACKAGE_DESCRIPTION_4
495496
return .targetItem(name: name)
496497
#else
497-
return ._targetItem(name: name)
498+
return ._targetItem(name: name, condition: nil)
498499
#endif
499500
}
500501

@@ -508,36 +509,61 @@ extension Target.Dependency {
508509
#if PACKAGE_DESCRIPTION_4
509510
return .productItem(name: name, package: package)
510511
#else
511-
return ._productItem(name: name, package: package)
512+
return ._productItem(name: name, package: package, condition: nil)
512513
#endif
513514
}
514515

516+
/// Creates a by-name dependency that resolves to either a target or a product but
517+
/// after the package graph has been loaded.
518+
///
519+
/// - parameters:
520+
/// - name: The name of the dependency, either a target or a product.
521+
@available(_PackageDescription, obsoleted: 5.2)
522+
public static func byName(name: String) -> Target.Dependency {
523+
#if PACKAGE_DESCRIPTION_4
524+
return .byNameItem(name: name)
525+
#else
526+
return ._byNameItem(name: name, condition: nil)
527+
#endif
528+
}
529+
530+
#if !PACKAGE_DESCRIPTION_4
531+
/// Creates a dependency on a target in the same package.
532+
///
533+
/// - parameters:
534+
/// - name: The name of the target.
535+
/// - condition: The condition under which the dependency is exercised.
536+
@available(_PackageDescription, introduced: 5.2)
537+
public static func target(name: String, condition: BuildSettingCondition? = nil) -> Target.Dependency {
538+
return ._targetItem(name: name, condition: condition)
539+
}
540+
515541
/// Creates a dependency on a product from a package dependency.
516542
///
517543
/// - parameters:
518544
/// - name: The name of the product.
519545
/// - package: The name of the package.
546+
/// - condition: The condition under which the dependency is exercised.
520547
@available(_PackageDescription, introduced: 5.2)
521-
public static func product(name: String, package: String) -> Target.Dependency {
522-
#if PACKAGE_DESCRIPTION_4
523-
return .productItem(name: name, package: package)
524-
#else
525-
return ._productItem(name: name, package: package)
526-
#endif
548+
public static func product(
549+
name: String,
550+
package: String,
551+
condition: BuildSettingCondition? = nil
552+
) -> Target.Dependency {
553+
return ._productItem(name: name, package: package, condition: condition)
527554
}
528555

529556
/// Creates a by-name dependency that resolves to either a target or a product but
530557
/// after the package graph has been loaded.
531558
///
532559
/// - parameters:
533560
/// - name: The name of the dependency, either a target or a product.
534-
public static func byName(name: String) -> Target.Dependency {
535-
#if PACKAGE_DESCRIPTION_4
536-
return .byNameItem(name: name)
537-
#else
538-
return ._byNameItem(name: name)
539-
#endif
561+
/// - condition: The condition under which the dependency is exercised.
562+
@available(_PackageDescription, introduced: 5.2)
563+
public static func byName(name: String, condition: BuildSettingCondition? = nil) -> Target.Dependency {
564+
return ._byNameItem(name: name, condition: condition)
540565
}
566+
#endif
541567
}
542568

543569
// MARK: ExpressibleByStringLiteral
@@ -552,7 +578,7 @@ extension Target.Dependency: ExpressibleByStringLiteral {
552578
#if PACKAGE_DESCRIPTION_4
553579
self = .byNameItem(name: value)
554580
#else
555-
self = ._byNameItem(name: value)
581+
self = ._byNameItem(name: value, condition: nil)
556582
#endif
557583
}
558584
}

Sources/PackageLoading/ManifestLoader.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,14 @@ public final class ManifestLoader: ManifestLoaderProtocol {
275275
for targetDependency in target.dependencies {
276276
// If this is a target dependency (or byName that references a target), we don't need to check.
277277
if case .target = targetDependency { continue }
278-
if case .byName(let name) = targetDependency, targetNames.contains(name) { continue }
278+
if case .byName(let name, _) = targetDependency, targetNames.contains(name) { continue }
279279

280280
// If we can't find the package dependency it references, the manifest is invalid.
281281
if manifest.packageDependency(referencedBy: targetDependency) == nil {
282282
let packageName: String
283283
switch targetDependency {
284-
case .product(_, package: let name?),
285-
.byName(let name):
284+
case .product(_, package: let name?, _),
285+
.byName(let name, _):
286286
packageName = name
287287
default:
288288
fatalError("Invalid case: this shouldn't be a target, or a product with no name")

Sources/PackageLoading/PackageBuilder.swift

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -526,14 +526,14 @@ public final class PackageBuilder {
526526
guard let target = targetMap[$0.name] else { return [] }
527527
return target.dependencies.compactMap({
528528
switch $0 {
529-
case .target(let name):
529+
case .target(let name, _):
530530
// Since we already checked above that all referenced targets
531531
// has to present, we always expect this target to be present in
532532
// potentialModules dictionary.
533533
return potentialModuleMap[name]!
534534
case .product:
535535
return nil
536-
case .byName(let name):
536+
case .byName(let name, _):
537537
// By name dependency may or may not be a target dependency.
538538
return potentialModuleMap[name]
539539
}
@@ -559,12 +559,12 @@ public final class PackageBuilder {
559559
let deps: [Target] = targetMap[potentialModule.name].map({
560560
$0.dependencies.compactMap({
561561
switch $0 {
562-
case .target(let name):
562+
case .target(let name, _):
563563
// We don't create an object for targets which have no sources.
564564
if emptyModules.contains(name) { return nil }
565565
return targets[name]!
566566

567-
case .byName(let name):
567+
case .byName(let name, _):
568568
// We don't create an object for targets which have no sources.
569569
if emptyModules.contains(name) { return nil }
570570
return targets[name]
@@ -583,10 +583,10 @@ public final class PackageBuilder {
583583
switch $0 {
584584
case .target:
585585
return nil
586-
case .byName(let name):
586+
case .byName(let name, _):
587587
// If this dependency was not found locally, it is a product dependency.
588588
return potentialModuleMap[name] == nil ? (name, nil) : nil
589-
case .product(let name, let package):
589+
case .product(let name, let package, _):
590590
return (name, package)
591591
}
592592
}) ?? []
@@ -788,13 +788,12 @@ public final class PackageBuilder {
788788
assignment.value = setting.value
789789

790790
if let config = setting.condition?.config.map({ BuildConfiguration(rawValue: $0)! }) {
791-
let condition = BuildSettings.ConfigurationCondition(config)
791+
let condition = ConfigurationCondition(configuration: config)
792792
assignment.conditions.append(condition)
793793
}
794794

795795
if let platforms = setting.condition?.platformNames.map({ platformRegistry.platformByName[$0]! }), !platforms.isEmpty {
796-
var condition = BuildSettings.PlatformsCondition()
797-
condition.platforms = platforms
796+
let condition = PlatformsCondition(platforms: platforms)
798797
assignment.conditions.append(condition)
799798
}
800799

@@ -1116,7 +1115,7 @@ private extension Manifest {
11161115
let names = targets.flatMap({ target in
11171116
[target.name] + target.dependencies.compactMap({
11181117
switch $0 {
1119-
case .target(let name):
1118+
case .target(let name, _):
11201119
return name
11211120
case .byName, .product:
11221121
return nil

Sources/PackageLoading/PackageDescription4Loader.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,7 @@ extension ManifestBuilder {
150150
func parseBuildSetting(_ json: JSON, tool: TargetBuildSettingDescription.Tool) throws -> TargetBuildSettingDescription.Setting {
151151
let json = try json.getJSON("data")
152152
let name = try TargetBuildSettingDescription.SettingName(rawValue: json.get("name"))!
153-
154-
var condition: TargetBuildSettingDescription.Condition?
155-
if let conditionJSON = try? json.getJSON("condition") {
156-
condition = try parseCondition(conditionJSON)
157-
}
153+
let condition = try (try? json.getJSON("condition")).flatMap(ManifestConditionDescription.init(v4:))
158154

159155
let value = try json.get([String].self, forKey: "value")
160156

@@ -176,14 +172,6 @@ extension ManifestBuilder {
176172

177173
/// Looks for Xcode-style build setting macros "$()".
178174
private static let invalidValueRegex = try! RegEx(pattern: #"(\$\(.*?\))"#)
179-
180-
func parseCondition(_ json: JSON) throws -> TargetBuildSettingDescription.Condition {
181-
let platformNames: [String]? = try? json.getArray("platforms").map({ try $0.get("name") })
182-
return .init(
183-
platformNames: platformNames ?? [],
184-
config: try? json.get("config").get("config")
185-
)
186-
}
187175
}
188176

189177
extension SystemPackageProviderDescription {
@@ -332,20 +320,32 @@ extension TargetDescription.TargetType {
332320
extension TargetDescription.Dependency {
333321
fileprivate init(v4 json: JSON) throws {
334322
let type = try json.get(String.self, forKey: "type")
323+
let condition = try (try? json.getJSON("condition")).flatMap(ManifestConditionDescription.init(v4:))
335324

336325
switch type {
337326
case "target":
338-
self = try .target(name: json.get("name"))
327+
self = try .target(name: json.get("name"), condition: condition)
339328

340329
case "product":
341330
let name = try json.get(String.self, forKey: "name")
342-
self = .product(name: name, package: json.get("package"))
331+
self = .product(name: name, package: json.get("package"), condition: condition)
343332

344333
case "byname":
345-
self = try .byName(name: json.get("name"))
334+
self = try .byName(name: json.get("name"), condition: condition)
346335

347336
default:
348337
fatalError()
349338
}
350339
}
351340
}
341+
342+
extension ManifestConditionDescription {
343+
fileprivate init?(v4 json: JSON) throws {
344+
if case .null = json { return nil }
345+
let platformNames: [String]? = try? json.getArray("platforms").map({ try $0.get("name") })
346+
self.init(
347+
platformNames: platformNames ?? [],
348+
config: try? json.get("config").get("config")
349+
)
350+
}
351+
}

0 commit comments

Comments
 (0)