Skip to content

Commit 061ecc4

Browse files
authored
Merge pull request #18638 from compnerd/SwiftSyntax-port
SwiftSyntax: some basic changes needed for Linux support
2 parents 9648318 + a4c604f commit 061ecc4

File tree

1 file changed

+50
-35
lines changed

1 file changed

+50
-35
lines changed

tools/SwiftSyntax/SwiftcInvocation.swift

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,46 +48,52 @@ struct ProcessResult {
4848
}
4949
}
5050

51+
internal func runCore(_ executable: URL, _ arguments: [String] = [])
52+
-> ProcessResult {
53+
let stdoutPipe = Pipe()
54+
var stdoutData = Data()
55+
stdoutPipe.fileHandleForReading.readabilityHandler = { file in
56+
stdoutData.append(file.availableData)
57+
}
58+
59+
let stderrPipe = Pipe()
60+
var stderrData = Data()
61+
stderrPipe.fileHandleForReading.readabilityHandler = { file in
62+
stderrData.append(file.availableData)
63+
}
64+
65+
let process = Process()
66+
process.terminationHandler = { process in
67+
stdoutPipe.fileHandleForReading.readabilityHandler = nil
68+
stderrPipe.fileHandleForReading.readabilityHandler = nil
69+
}
70+
process.launchPath = executable.path
71+
process.arguments = arguments
72+
process.standardOutput = stdoutPipe
73+
process.standardError = stderrPipe
74+
process.launch()
75+
process.waitUntilExit()
76+
77+
return ProcessResult(exitCode: Int(process.terminationStatus),
78+
stdoutData: stdoutData,
79+
stderrData: stderrData)
80+
}
81+
5182
/// Runs the provided executable with the provided arguments and returns the
5283
/// contents of stdout and stderr as Data.
5384
/// - Parameters:
5485
/// - executable: The full file URL to the executable you're running.
5586
/// - arguments: A list of strings to pass to the process as arguments.
5687
/// - Returns: A ProcessResult containing stdout, stderr, and the exit code.
5788
func run(_ executable: URL, arguments: [String] = []) -> ProcessResult {
89+
#if _runtime(_ObjC)
5890
// Use an autoreleasepool to prevent memory- and file-descriptor leaks.
59-
return autoreleasepool {
60-
() -> ProcessResult in
61-
62-
let stdoutPipe = Pipe()
63-
var stdoutData = Data()
64-
stdoutPipe.fileHandleForReading.readabilityHandler = { file in
65-
stdoutData.append(file.availableData)
66-
}
67-
68-
let stderrPipe = Pipe()
69-
var stderrData = Data()
70-
stderrPipe.fileHandleForReading.readabilityHandler = { file in
71-
stderrData.append(file.availableData)
72-
}
73-
74-
let process = Process()
75-
76-
process.terminationHandler = { process in
77-
stdoutPipe.fileHandleForReading.readabilityHandler = nil
78-
stderrPipe.fileHandleForReading.readabilityHandler = nil
79-
}
80-
81-
process.launchPath = executable.path
82-
process.arguments = arguments
83-
process.standardOutput = stdoutPipe
84-
process.standardError = stderrPipe
85-
process.launch()
86-
process.waitUntilExit()
87-
return ProcessResult(exitCode: Int(process.terminationStatus),
88-
stdoutData: stdoutData,
89-
stderrData: stderrData)
91+
return autoreleasepool { () -> ProcessResult in
92+
runCore(executable, arguments)
9093
}
94+
#else
95+
return runCore(executable, arguments)
96+
#endif
9197
}
9298

9399
/// Finds the dylib or executable which the provided address falls in.
@@ -100,7 +106,11 @@ func run(_ executable: URL, arguments: [String] = []) -> ProcessResult {
100106
/// or executable. If unable to find the appropriate object, returns
101107
/// `nil`.
102108
func findFirstObjectFile(for dsohandle: UnsafeRawPointer = #dsohandle) -> URL? {
109+
#if os(Linux)
110+
var info = Dl_info()
111+
#else
103112
var info = dl_info()
113+
#endif
104114
if dladdr(dsohandle, &info) == 0 {
105115
return nil
106116
}
@@ -136,16 +146,21 @@ struct SwiftcRunner {
136146
/// - lib/
137147
/// - swift/
138148
/// - ${target}/
139-
/// - libswiftSwiftSyntax.[dylib|so]
149+
/// - ${arch}/ (only on !Darwin)
150+
/// - libswiftSwiftSyntax.[dylib|so]
140151
/// ```
141152
static func locateSwiftc() -> URL? {
142153
guard let libraryPath = findFirstObjectFile() else { return nil }
143-
let swiftcURL = libraryPath.deletingLastPathComponent()
154+
155+
var swiftcURL = libraryPath.deletingLastPathComponent()
144156
.deletingLastPathComponent()
145157
.deletingLastPathComponent()
146158
.deletingLastPathComponent()
147-
.appendingPathComponent("bin")
148-
.appendingPathComponent("swiftc")
159+
#if !os(macOS)
160+
swiftcURL = swiftcURL.deletingLastPathComponent()
161+
#endif
162+
swiftcURL = swiftcURL.appendingPathComponent("bin")
163+
.appendingPathComponent("swiftc")
149164
guard FileManager.default.fileExists(atPath: swiftcURL.path) else {
150165
return nil
151166
}

0 commit comments

Comments
 (0)