Skip to content

Commit 037ad7c

Browse files
committed
Manifest changes for conditional target dependencies
1 parent 4c3a21b commit 037ad7c

File tree

17 files changed

+286
-151
lines changed

17 files changed

+286
-151
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
@@ -448,6 +448,7 @@ extension Target.Dependency: Encodable {
448448
case type
449449
case name
450450
case package
451+
case condition
451452
}
452453

453454
private enum Kind: String, Codable {
@@ -473,16 +474,19 @@ extension Target.Dependency: Encodable {
473474
}
474475
#else
475476
switch self {
476-
case ._targetItem(let name):
477+
case ._targetItem(let name, let condition):
477478
try container.encode(Kind.target, forKey: .type)
478479
try container.encode(name, forKey: .name)
479-
case ._productItem(let name, let package):
480+
try container.encode(condition, forKey: .condition)
481+
case ._productItem(let name, let package, let condition):
480482
try container.encode(Kind.product, forKey: .type)
481483
try container.encode(name, forKey: .name)
482484
try container.encode(package, forKey: .package)
483-
case ._byNameItem(let name):
485+
try container.encode(condition, forKey: .condition)
486+
case ._byNameItem(let name, let condition):
484487
try container.encode(Kind.byName, forKey: .type)
485488
try container.encode(name, forKey: .name)
489+
try container.encode(condition, forKey: .condition)
486490
}
487491
#endif
488492
}

Sources/PackageDescription4/Target.swift

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
*/
1010

1111
/// A target, the basic building block of a Swift package.
12-
///
12+
///
1313
/// Each target contains a set of source files that are compiled into a module or test suite.
1414
/// You can vend targets to other packages by defining products that include the targets.
15-
///
15+
///
1616
/// A target may depend on other targets within the same package and on products vended by the package's dependencies.
1717
public final class Target {
1818

@@ -30,9 +30,9 @@ public final class Target {
3030
case productItem(name: String, package: String?)
3131
case byNameItem(name: String)
3232
#else
33-
case _targetItem(name: String)
34-
case _productItem(name: String, package: String?)
35-
case _byNameItem(name: String)
33+
case _targetItem(name: String, condition: BuildSettingCondition?)
34+
case _productItem(name: String, package: String?, condition: BuildSettingCondition?)
35+
case _byNameItem(name: String, condition: BuildSettingCondition?)
3636
#endif
3737
}
3838

@@ -93,7 +93,7 @@ public final class Target {
9393

9494
/// The `pkgconfig` name to use for a system library target.
9595
///
96-
/// If present, the Swift Package Manager tries to
96+
/// If present, the Swift Package Manager tries to
9797
/// search for the `<name>.pc` file to get the additional flags needed for the
9898
/// system target.
9999
public let pkgConfig: String?
@@ -400,7 +400,7 @@ public final class Target {
400400

401401
#if !PACKAGE_DESCRIPTION_4
402402
/// Create a system library target.
403-
///
403+
///
404404
/// Use system library targets to adapt a library installed on the system to work with Swift packages.
405405
/// Such libraries are generally installed by system package managers (such as Homebrew and apt-get)
406406
/// and exposed to Swift packages by providing a `modulemap` file along with other metadata such as the library's `pkgConfig` name.
@@ -487,11 +487,12 @@ extension Target.Dependency {
487487
///
488488
/// - parameters:
489489
/// - name: The name of the target.
490+
@available(_PackageDescription, obsoleted: 5.3)
490491
public static func target(name: String) -> Target.Dependency {
491492
#if PACKAGE_DESCRIPTION_4
492493
return .targetItem(name: name)
493494
#else
494-
return ._targetItem(name: name)
495+
return ._targetItem(name: name, condition: nil)
495496
#endif
496497
}
497498

@@ -500,11 +501,12 @@ extension Target.Dependency {
500501
/// - parameters:
501502
/// - name: The name of the product.
502503
/// - package: The name of the package.
504+
@available(_PackageDescription, obsoleted: 5.3)
503505
public static func product(name: String, package: String? = nil) -> Target.Dependency {
504506
#if PACKAGE_DESCRIPTION_4
505507
return .productItem(name: name, package: package)
506508
#else
507-
return ._productItem(name: name, package: package)
509+
return ._productItem(name: name, package: package, condition: nil)
508510
#endif
509511
}
510512

@@ -513,13 +515,52 @@ extension Target.Dependency {
513515
///
514516
/// - parameters:
515517
/// - name: The name of the dependency, either a target or a product.
518+
@available(_PackageDescription, obsoleted: 5.3)
516519
public static func byName(name: String) -> Target.Dependency {
517520
#if PACKAGE_DESCRIPTION_4
518521
return .byNameItem(name: name)
519522
#else
520-
return ._byNameItem(name: name)
523+
return ._byNameItem(name: name, condition: nil)
521524
#endif
522525
}
526+
527+
#if !PACKAGE_DESCRIPTION_4
528+
/// Creates a dependency on a target in the same package.
529+
///
530+
/// - parameters:
531+
/// - name: The name of the target.
532+
/// - condition: The condition under which the dependency is exercised.
533+
@available(_PackageDescription, introduced: 5.3)
534+
public static func target(name: String, condition: BuildSettingCondition? = nil) -> Target.Dependency {
535+
return ._targetItem(name: name, condition: condition)
536+
}
537+
538+
/// Creates a dependency on a product from a package dependency.
539+
///
540+
/// - parameters:
541+
/// - name: The name of the product.
542+
/// - package: The name of the package.
543+
/// - condition: The condition under which the dependency is exercised.
544+
@available(_PackageDescription, introduced: 5.3)
545+
public static func product(
546+
name: String,
547+
package: String? = nil,
548+
condition: BuildSettingCondition? = nil
549+
) -> Target.Dependency {
550+
return ._productItem(name: name, package: package, condition: condition)
551+
}
552+
553+
/// Creates a by-name dependency that resolves to either a target or a product but
554+
/// after the package graph has been loaded.
555+
///
556+
/// - parameters:
557+
/// - name: The name of the dependency, either a target or a product.
558+
/// - condition: The condition under which the dependency is exercised.
559+
@available(_PackageDescription, introduced: 5.3)
560+
public static func byName(name: String, condition: BuildSettingCondition? = nil) -> Target.Dependency {
561+
return ._byNameItem(name: name, condition: condition)
562+
}
563+
#endif
523564
}
524565

525566
// MARK: ExpressibleByStringLiteral
@@ -534,7 +575,7 @@ extension Target.Dependency: ExpressibleByStringLiteral {
534575
#if PACKAGE_DESCRIPTION_4
535576
self = .byNameItem(name: value)
536577
#else
537-
self = ._byNameItem(name: value)
578+
self = ._byNameItem(name: value, condition: nil)
538579
#endif
539580
}
540581
}

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
@@ -144,11 +144,7 @@ extension ManifestBuilder {
144144
func parseBuildSetting(_ json: JSON, tool: TargetBuildSettingDescription.Tool) throws -> TargetBuildSettingDescription.Setting {
145145
let json = try json.getJSON("data")
146146
let name = try TargetBuildSettingDescription.SettingName(rawValue: json.get("name"))!
147-
148-
var condition: TargetBuildSettingDescription.Condition?
149-
if let conditionJSON = try? json.getJSON("condition") {
150-
condition = try parseCondition(conditionJSON)
151-
}
147+
let condition = try (try? json.getJSON("condition")).flatMap(ManifestConditionDescription.init(v4:))
152148

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

@@ -170,14 +166,6 @@ extension ManifestBuilder {
170166

171167
/// Looks for Xcode-style build setting macros "$()".
172168
private static let invalidValueRegex = try! RegEx(pattern: #"(\$\(.*?\))"#)
173-
174-
func parseCondition(_ json: JSON) throws -> TargetBuildSettingDescription.Condition {
175-
let platformNames: [String]? = try? json.getArray("platforms").map({ try $0.get("name") })
176-
return .init(
177-
platformNames: platformNames ?? [],
178-
config: try? json.get("config").get("config")
179-
)
180-
}
181169
}
182170

183171
extension SystemPackageProviderDescription {
@@ -323,20 +311,32 @@ extension TargetDescription.TargetType {
323311
extension TargetDescription.Dependency {
324312
fileprivate init(v4 json: JSON) throws {
325313
let type = try json.get(String.self, forKey: "type")
314+
let condition = try (try? json.getJSON("condition")).flatMap(ManifestConditionDescription.init(v4:))
326315

327316
switch type {
328317
case "target":
329-
self = try .target(name: json.get("name"))
318+
self = try .target(name: json.get("name"), condition: condition)
330319

331320
case "product":
332321
let name = try json.get(String.self, forKey: "name")
333-
self = .product(name: name, package: json.get("package"))
322+
self = .product(name: name, package: json.get("package"), condition: condition)
334323

335324
case "byname":
336-
self = try .byName(name: json.get("name"))
325+
self = try .byName(name: json.get("name"), condition: condition)
337326

338327
default:
339328
fatalError()
340329
}
341330
}
342331
}
332+
333+
extension ManifestConditionDescription {
334+
fileprivate init?(v4 json: JSON) throws {
335+
if case .null = json { return nil }
336+
let platformNames: [String]? = try? json.getArray("platforms").map({ try $0.get("name") })
337+
self.init(
338+
platformNames: platformNames ?? [],
339+
config: try? json.get("config").get("config")
340+
)
341+
}
342+
}

0 commit comments

Comments
 (0)