Skip to content

Commit

Permalink
Allow SwiftTargetDescription, ClangTargetDescription, and ProductDesc…
Browse files Browse the repository at this point in the history
…ription to know the tools version of the package in which they are defined. This allows compiler flags and other semantically significant changes to be conditionalized on the tools version.

In the cases where tools versions are synthesized, they get the tools version of the package defining the product or target for which they are being synthesized.  The fallback for anything that cannot be determined at all is always `.vNext`, which is the same as has been the case until now.
  • Loading branch information
abertelrud committed Mar 3, 2021
1 parent 4e791bb commit 5b0597d
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions Sources/Build/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ public final class ClangTargetBuildDescription {
public var clangTarget: ClangTarget {
return target.underlyingTarget as! ClangTarget
}

/// The tools version of the package that declared the target. This can
/// can be used to conditionalize semantically significant changes in how
/// a target is built.
public let toolsVersion: ToolsVersion

/// The build parameters.
let buildParameters: BuildParameters
Expand Down Expand Up @@ -249,11 +254,12 @@ public final class ClangTargetBuildDescription {
}

/// Create a new target description with target and build parameters.
init(target: ResolvedTarget, buildParameters: BuildParameters, fileSystem: FileSystem = localFileSystem, diagnostics: DiagnosticsEngine) throws {
init(target: ResolvedTarget, toolsVersion: ToolsVersion, buildParameters: BuildParameters, fileSystem: FileSystem = localFileSystem, diagnostics: DiagnosticsEngine) throws {
assert(target.underlyingTarget is ClangTarget, "underlying target type mismatch \(target)")
self.fileSystem = fileSystem
self.diagnostics = diagnostics
self.target = target
self.toolsVersion = toolsVersion
self.buildParameters = buildParameters
self.tempsPath = buildParameters.buildPath.appending(component: target.c99name + ".build")
self.derivedSources = Sources(paths: [], root: tempsPath.appending(component: "DerivedSources"))
Expand Down Expand Up @@ -472,6 +478,11 @@ public final class SwiftTargetBuildDescription {
/// The target described by this target.
public let target: ResolvedTarget

/// The tools version of the package that declared the target. This can
/// can be used to conditionalize semantically significant changes in how
/// a target is built.
public let toolsVersion: ToolsVersion

/// The build parameters.
let buildParameters: BuildParameters

Expand Down Expand Up @@ -555,6 +566,7 @@ public final class SwiftTargetBuildDescription {
/// Create a new target description with target and build parameters.
init(
target: ResolvedTarget,
toolsVersion: ToolsVersion,
buildParameters: BuildParameters,
pluginInvocationResults: [PluginInvocationResult] = [],
prebuildCommandResults: [PrebuildCommandResult] = [],
Expand All @@ -564,6 +576,7 @@ public final class SwiftTargetBuildDescription {
) throws {
assert(target.underlyingTarget is SwiftTarget, "underlying target type mismatch \(target)")
self.target = target
self.toolsVersion = toolsVersion
self.buildParameters = buildParameters
// Unless mentioned explicitly, use the target type to determine if this is a test target.
self.isTestTarget = isTestTarget ?? (target.type == .test)
Expand Down Expand Up @@ -1018,6 +1031,11 @@ public final class ProductBuildDescription {
/// The reference to the product.
public let product: ResolvedProduct

/// The tools version of the package that declared the product. This can
/// can be used to conditionalize semantically significant changes in how
/// a target is built.
public let toolsVersion: ToolsVersion

/// The build parameters.
let buildParameters: BuildParameters

Expand Down Expand Up @@ -1067,9 +1085,10 @@ public final class ProductBuildDescription {
let diagnostics: DiagnosticsEngine

/// Create a build description for a product.
init(product: ResolvedProduct, buildParameters: BuildParameters, fs: FileSystem, diagnostics: DiagnosticsEngine) {
init(product: ResolvedProduct, toolsVersion: ToolsVersion, buildParameters: BuildParameters, fs: FileSystem, diagnostics: DiagnosticsEngine) {
assert(product.type != .library(.automatic), "Automatic type libraries should not be described.")
self.product = product
self.toolsVersion = toolsVersion
self.buildParameters = buildParameters
self.fs = fs
self.diagnostics = diagnostics
Expand Down Expand Up @@ -1327,9 +1346,11 @@ public class BuildPlan {
// if test manifest exists, prefer that over test detection,
// this is designed as an escape hatch when test discovery is not appropriate
// and for backwards compatibility for projects that have existing test manifests (LinuxMain.swift)
let toolsVersion = graph.package(for: testProduct)?.manifest.toolsVersion ?? .vNext
if let testManifestTarget = testProduct.testManifestTarget, !generate {
let desc = try SwiftTargetBuildDescription(
target: testManifestTarget,
toolsVersion: toolsVersion,
buildParameters: buildParameters,
isTestTarget: true
)
Expand Down Expand Up @@ -1361,6 +1382,7 @@ public class BuildPlan {

let target = try SwiftTargetBuildDescription(
target: testManifestTarget,
toolsVersion: toolsVersion,
buildParameters: buildParameters,
isTestTarget: true,
testDiscoveryTarget: true
Expand Down Expand Up @@ -1403,18 +1425,24 @@ public class BuildPlan {
}
}
}

// Determine the appropriate tools version to use for the target.
// This can affect what flags to pass and other semantics.
let toolsVersion = graph.package(for: target)?.manifest.toolsVersion ?? .vNext

switch target.underlyingTarget {
case is SwiftTarget:
targetMap[target] = try .swift(SwiftTargetBuildDescription(
target: target,
toolsVersion: toolsVersion,
buildParameters: buildParameters,
pluginInvocationResults: pluginInvocationResults[target] ?? [],
prebuildCommandResults: prebuildCommandResults[target] ?? [],
fs: fileSystem))
case is ClangTarget:
targetMap[target] = try .clang(ClangTargetBuildDescription(
target: target,
toolsVersion: toolsVersion,
buildParameters: buildParameters,
fileSystem: fileSystem,
diagnostics: diagnostics))
Expand Down Expand Up @@ -1448,8 +1476,14 @@ public class BuildPlan {
// Create product description for each product we have in the package graph except
// for automatic libraries and plugins, because they don't produce any output.
for product in graph.allProducts where product.type != .library(.automatic) && product.type != .plugin {

// Determine the appropriate tools version to use for the product.
// This can affect what flags to pass and other semantics.
let toolsVersion = graph.package(for: product)?.manifest.toolsVersion ?? .vNext
productMap[product] = ProductBuildDescription(
product: product, buildParameters: buildParameters,
product: product,
toolsVersion: toolsVersion,
buildParameters: buildParameters,
fs: fileSystem,
diagnostics: diagnostics
)
Expand Down

0 comments on commit 5b0597d

Please sign in to comment.