@@ -48,46 +48,52 @@ struct ProcessResult {
48
48
}
49
49
}
50
50
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
+
51
82
/// Runs the provided executable with the provided arguments and returns the
52
83
/// contents of stdout and stderr as Data.
53
84
/// - Parameters:
54
85
/// - executable: The full file URL to the executable you're running.
55
86
/// - arguments: A list of strings to pass to the process as arguments.
56
87
/// - Returns: A ProcessResult containing stdout, stderr, and the exit code.
57
88
func run( _ executable: URL , arguments: [ String ] = [ ] ) -> ProcessResult {
89
+ #if _runtime(_ObjC)
58
90
// 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)
90
93
}
94
+ #else
95
+ return runCore ( executable, arguments)
96
+ #endif
91
97
}
92
98
93
99
/// Finds the dylib or executable which the provided address falls in.
@@ -100,7 +106,11 @@ func run(_ executable: URL, arguments: [String] = []) -> ProcessResult {
100
106
/// or executable. If unable to find the appropriate object, returns
101
107
/// `nil`.
102
108
func findFirstObjectFile( for dsohandle: UnsafeRawPointer = #dsohandle) -> URL ? {
109
+ #if os(Linux)
110
+ var info = Dl_info ( )
111
+ #else
103
112
var info = dl_info ( )
113
+ #endif
104
114
if dladdr ( dsohandle, & info) == 0 {
105
115
return nil
106
116
}
@@ -136,16 +146,21 @@ struct SwiftcRunner {
136
146
/// - lib/
137
147
/// - swift/
138
148
/// - ${target}/
139
- /// - libswiftSwiftSyntax.[dylib|so]
149
+ /// - ${arch}/ (only on !Darwin)
150
+ /// - libswiftSwiftSyntax.[dylib|so]
140
151
/// ```
141
152
static func locateSwiftc( ) -> URL ? {
142
153
guard let libraryPath = findFirstObjectFile ( ) else { return nil }
143
- let swiftcURL = libraryPath. deletingLastPathComponent ( )
154
+
155
+ var swiftcURL = libraryPath. deletingLastPathComponent ( )
144
156
. deletingLastPathComponent ( )
145
157
. deletingLastPathComponent ( )
146
158
. 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 " )
149
164
guard FileManager . default. fileExists ( atPath: swiftcURL. path) else {
150
165
return nil
151
166
}
0 commit comments