Skip to content

Commit b4ff300

Browse files
authored
Merge pull request #148 from DougGregor/more-print-target-info
Use the frontend's -print-target-info more often
2 parents 9f297a9 + ab221b9 commit b4ff300

File tree

9 files changed

+159
-152
lines changed

9 files changed

+159
-152
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,19 @@ public struct Driver {
7777
/// The executor the driver uses to run jobs.
7878
public let executor: DriverExecutor
7979

80+
/// The toolchain to use for resolution.
81+
public let toolchain: Toolchain
82+
83+
/// Information about the target, as reported by the Swift frontend.
84+
let frontendTargetInfo: FrontendTargetInfo
85+
8086
/// The target triple.
81-
public let targetTriple: Triple
87+
public var targetTriple: Triple { frontendTargetInfo.target.triple }
8288

8389
/// The variant target triple.
84-
public let targetVariantTriple: Triple?
85-
86-
/// The toolchain to use for resolution.
87-
public let toolchain: Toolchain
90+
public var targetVariantTriple: Triple? {
91+
frontendTargetInfo.targetVariant?.triple
92+
}
8893

8994
/// The kind of driver.
9095
public let driverKind: DriverKind
@@ -246,12 +251,13 @@ public struct Driver {
246251
self.optionTable = OptionTable()
247252
self.parsedOptions = try optionTable.parse(Array(args), for: self.driverKind)
248253

249-
let explicitTarget = (self.parsedOptions.getLastArgument(.target)?.asSingle)
250-
.map {
251-
Triple($0, normalizing: true)
252-
}
253-
(self.toolchain, self.targetTriple) = try Self.computeToolchain(explicitTarget, diagnosticsEngine: diagnosticEngine, env: env, executor: self.executor, fileSystem: fileSystem)
254-
self.targetVariantTriple = self.parsedOptions.getLastArgument(.targetVariant).map { Triple($0.asSingle, normalizing: true) }
254+
(self.toolchain, self.frontendTargetInfo) = try Self.computeToolchain(
255+
&self.parsedOptions, diagnosticsEngine: diagnosticEngine, env: env,
256+
executor: self.executor, fileSystem: fileSystem)
257+
258+
// Local variable to alias the target triple, because self.targetTriple
259+
// is not available until the end of this initializer.
260+
let targetTriple = self.frontendTargetInfo.target.triple
255261

256262
// Find the Swift compiler executable.
257263
if let frontendPath = self.parsedOptions.getLastArgument(.driverUseFrontendPath) {
@@ -342,7 +348,8 @@ public struct Driver {
342348
actualSwiftVersion: try? toolchain.swiftCompilerVersion()
343349
)
344350

345-
self.sdkPath = Self.computeSDKPath(&parsedOptions, compilerMode: compilerMode, toolchain: toolchain, fileSystem: fileSystem, diagnosticsEngine: diagnosticEngine, env: env)
351+
self.sdkPath = Self.computeSDKPath(&parsedOptions, compilerMode: compilerMode, toolchain: toolchain, targetTriple: targetTriple,
352+
fileSystem: fileSystem, diagnosticsEngine: diagnosticEngine, env: env)
346353

347354
self.importedObjCHeader = try Self.computeImportedObjCHeader(&parsedOptions, compilerMode: compilerMode, diagnosticEngine: diagnosticEngine)
348355
self.bridgingPrecompiledHeader = try Self.computeBridgingPrecompiledHeader(&parsedOptions,
@@ -664,7 +671,7 @@ extension Driver {
664671

665672
if parsedOptions.contains(.driverPrintBindings) {
666673
for job in jobs {
667-
try printBindings(job)
674+
printBindings(job)
668675
}
669676
return
670677
}
@@ -728,8 +735,8 @@ extension Driver {
728735
print(result)
729736
}
730737

731-
private func printBindings(_ job: Job) throws {
732-
try stdoutStream <<< #"# ""# <<< toolchain.hostTargetTriple().triple
738+
private func printBindings(_ job: Job) {
739+
stdoutStream <<< #"# ""# <<< targetTriple.triple
733740
stdoutStream <<< #"" - ""# <<< job.tool.basename
734741
stdoutStream <<< #"", inputs: ["#
735742
stdoutStream <<< job.inputs.map { "\"" + $0.file.name + "\"" }.joined(separator: ", ")
@@ -1416,6 +1423,7 @@ extension Driver {
14161423
_ parsedOptions: inout ParsedOptions,
14171424
compilerMode: CompilerMode,
14181425
toolchain: Toolchain,
1426+
targetTriple: Triple,
14191427
fileSystem: FileSystem,
14201428
diagnosticsEngine: DiagnosticsEngine,
14211429
env: [String: String]
@@ -1427,8 +1435,7 @@ extension Driver {
14271435
} else if let SDKROOT = env["SDKROOT"] {
14281436
sdkPath = SDKROOT
14291437
} else if compilerMode == .immediate || compilerMode == .repl {
1430-
let triple = try? toolchain.hostTargetTriple()
1431-
if triple?.isMacOSX == true {
1438+
if targetTriple.isMacOSX == true {
14321439
// In immediate modes, use the SDK provided by xcrun.
14331440
// This will prefer the SDK alongside the Swift found by "xcrun swift".
14341441
// We don't do this in compilation modes because defaulting to the
@@ -1573,16 +1580,53 @@ extension Driver {
15731580
#endif
15741581

15751582
static func computeToolchain(
1576-
_ explicitTarget: Triple?,
1583+
_ parsedOptions: inout ParsedOptions,
15771584
diagnosticsEngine: DiagnosticsEngine,
15781585
env: [String: String],
15791586
executor: DriverExecutor,
15801587
fileSystem: FileSystem
1581-
) throws -> (Toolchain, Triple) {
1588+
) throws -> (Toolchain, FrontendTargetInfo) {
1589+
let explicitTarget = (parsedOptions.getLastArgument(.target)?.asSingle)
1590+
.map {
1591+
Triple($0, normalizing: true)
1592+
}
1593+
let explicitTargetVariant = (parsedOptions.getLastArgument(.targetVariant)?.asSingle)
1594+
.map {
1595+
Triple($0, normalizing: true)
1596+
}
1597+
1598+
// FIXME: Compute these.
1599+
let sdkPath: VirtualPath? = nil
1600+
let resourceDirPath: VirtualPath? = nil
1601+
15821602
let toolchainType = try explicitTarget?.toolchainType(diagnosticsEngine) ??
15831603
defaultToolchainType
15841604
let toolchain = toolchainType.init(env: env, executor: executor, fileSystem: fileSystem)
1585-
return (toolchain, try explicitTarget ?? toolchain.hostTargetTriple())
1605+
1606+
var info = try executor.execute(
1607+
job: toolchain.printTargetInfoJob(
1608+
target: explicitTarget, targetVariant: explicitTargetVariant,
1609+
sdkPath: sdkPath, resourceDirPath: resourceDirPath
1610+
),
1611+
capturingJSONOutputAs: FrontendTargetInfo.self,
1612+
forceResponseFiles: false,
1613+
recordedInputModificationDates: [:])
1614+
1615+
// Parse the runtime compatibility version. If present, it will override
1616+
// what is reported by the frontend.
1617+
if let versionString =
1618+
parsedOptions.getLastArgument(.runtimeCompatibilityVersion)?.asSingle {
1619+
if let version = SwiftVersion(string: versionString) {
1620+
info.target.swiftRuntimeCompatibilityVersion = version
1621+
info.targetVariant?.swiftRuntimeCompatibilityVersion = version
1622+
} else {
1623+
diagnosticsEngine.emit(
1624+
.error_invalid_arg_value(
1625+
arg: .runtimeCompatibilityVersion, value: versionString))
1626+
}
1627+
}
1628+
1629+
return (toolchain, info)
15861630
}
15871631
}
15881632

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ extension DarwinToolchain {
196196
outputFile: VirtualPath,
197197
sdkPath: String?,
198198
sanitizers: Set<Sanitizer>,
199-
targetTriple: Triple,
200-
targetVariantTriple: Triple?
199+
targetInfo: FrontendTargetInfo
201200
) throws -> AbsolutePath {
202201

203202
// FIXME: If we used Clang as a linker instead of going straight to ld,
@@ -209,6 +208,7 @@ extension DarwinToolchain {
209208
//
210209
// Note: Normally we'd just add this unconditionally, but it's valid to build
211210
// Swift and use it as a linker without building compiler_rt.
211+
let targetTriple = targetInfo.target.triple
212212
let darwinPlatformSuffix =
213213
targetTriple.darwinPlatform!.with(.device)!.libraryNameSuffix
214214
let compilerRTPath =
@@ -258,7 +258,7 @@ extension DarwinToolchain {
258258
to: &commandLine,
259259
parsedOptions: &parsedOptions,
260260
sdkPath: sdkPath,
261-
targetTriple: targetTriple,
261+
targetInfo: targetInfo,
262262
linkerOutputType: linkerOutputType,
263263
fileSystem: fileSystem
264264
)
@@ -280,6 +280,7 @@ extension DarwinToolchain {
280280
parsedOptions: &parsedOptions,
281281
targetTriple: targetTriple
282282
)
283+
let targetVariantTriple = targetInfo.targetVariant?.triple
283284
addDeploymentTargetArgs(
284285
to: &commandLine,
285286
targetTriple: targetTriple,

Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ extension GenericUnixToolchain {
5151
outputFile: VirtualPath,
5252
sdkPath: String?,
5353
sanitizers: Set<Sanitizer>,
54-
targetTriple: Triple,
55-
targetVariantTriple: Triple?
54+
targetInfo: FrontendTargetInfo
5655
) throws -> AbsolutePath {
56+
let targetTriple = targetInfo.target.triple
5757
switch linkerOutputType {
5858
case .dynamicLibrary:
5959
// Same options as an executable, just with '-shared'

Sources/SwiftDriver/Jobs/LinkJob.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ extension Driver {
4747
outputFile: outputFile,
4848
sdkPath: sdkPath,
4949
sanitizers: enabledSanitizers,
50-
targetTriple: targetTriple,
51-
targetVariantTriple: targetVariantTriple
50+
targetInfo: frontendTargetInfo
5251
)
5352

5453
// TODO: some, but not all, linkers support response files.

Sources/SwiftDriver/Jobs/PrintTargetInfoJob.swift

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,77 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
/// Swift versions are major.minor.
14+
struct SwiftVersion {
15+
var major: Int
16+
var minor: Int
17+
18+
init?(string: String) {
19+
let components = string.split(
20+
separator: ".", maxSplits: 2, omittingEmptySubsequences: false)
21+
.compactMap { Int($0)}
22+
guard components.count == 2 else { return nil }
23+
24+
self.major = components[0]
25+
self.minor = components[1]
26+
}
27+
}
28+
29+
extension SwiftVersion: CustomStringConvertible {
30+
var description: String { "\(major).\(minor)" }
31+
}
32+
33+
extension SwiftVersion: Codable {
34+
func encode(to encoder: Encoder) throws {
35+
var container = encoder.singleValueContainer()
36+
try container.encode(description)
37+
}
38+
39+
init(from decoder: Decoder) throws {
40+
let container = try decoder.singleValueContainer()
41+
let string = try container.decode(String.self)
42+
43+
guard let version = SwiftVersion(string: string) else {
44+
throw DecodingError.dataCorrupted(.init(
45+
codingPath: decoder.codingPath,
46+
debugDescription: "Invalid Swift version string \(string)"))
47+
}
48+
49+
self = version
50+
}
51+
}
52+
53+
/// Describes information about the target as provided by the Swift frontend.
54+
public struct FrontendTargetInfo: Codable {
55+
struct Target: Codable {
56+
/// The target triple
57+
let triple: Triple
58+
59+
/// The target triple without any version information.
60+
let unversionedTriple: Triple
61+
62+
/// The triple used for module names.
63+
let moduleTriple: Triple
64+
65+
/// The version of the Swift runtime that is present in the runtime
66+
/// environment of the target.
67+
var swiftRuntimeCompatibilityVersion: SwiftVersion?
68+
69+
/// Whether the Swift libraries need to be referenced in their system
70+
/// location (/usr/lib/swift) via rpath.
71+
let librariesRequireRPath: Bool
72+
}
73+
74+
struct Paths: Codable {
75+
let runtimeLibraryPaths: [String]
76+
let runtimeLibraryImportPaths: [String]
77+
let runtimeResourcePath: String
78+
}
79+
80+
var target: Target
81+
var targetVariant: Target?
82+
let paths: Paths
83+
}
1384

1485
extension Toolchain {
1586
func printTargetInfoJob(target: Triple?,

0 commit comments

Comments
 (0)