11
11
//===----------------------------------------------------------------------===//
12
12
13
13
import ArgumentParser
14
- import Basics
14
+ @ _spi ( SwiftPMInternal ) import Basics
15
15
import CoreCommands
16
16
import Foundation
17
17
import PackageGraph
@@ -233,7 +233,9 @@ public struct SwiftRunCommand: AsyncSwiftCommand {
233
233
let runnerPath : AbsolutePath
234
234
let arguments : [ String ]
235
235
236
- if let debugger = try swiftCommandState. getTargetToolchain ( ) . swiftSDK. toolset. knownTools [ . debugger] ,
236
+ let toolchain = try swiftCommandState. getTargetToolchain ( )
237
+
238
+ if let debugger = toolchain. swiftSDK. toolset. knownTools [ . debugger] ,
237
239
let debuggerPath = debugger. path {
238
240
runnerPath = debuggerPath
239
241
arguments = debugger. extraCLIOptions + [ productAbsolutePath. pathString] + options. arguments
@@ -242,11 +244,23 @@ public struct SwiftRunCommand: AsyncSwiftCommand {
242
244
arguments = options. arguments
243
245
}
244
246
247
+ // For Linux, need to point LD_LIBRARY_PATH at the swift runtime
248
+ let environment : [ String : String ] ?
249
+ if toolchain. targetTriple. isLinux ( ) {
250
+ var current = Environment . current
251
+ let pathVar : EnvironmentKey = " LD_LIBRARY_PATH "
252
+ current. prependPath ( key: pathVar, value: try toolchain. linuxSwiftStdlib. pathString)
253
+ environment = . init( current)
254
+ } else {
255
+ environment = nil
256
+ }
257
+
245
258
try self . run (
246
259
fileSystem: swiftCommandState. fileSystem,
247
260
executablePath: runnerPath,
248
261
originalWorkingDirectory: swiftCommandState. originalWorkingDirectory,
249
- arguments: arguments
262
+ arguments: arguments,
263
+ environment: environment
250
264
)
251
265
} catch Diagnostics . fatalError {
252
266
throw ExitCode . failure
@@ -294,7 +308,8 @@ public struct SwiftRunCommand: AsyncSwiftCommand {
294
308
fileSystem: FileSystem ,
295
309
executablePath: AbsolutePath ,
296
310
originalWorkingDirectory: AbsolutePath ,
297
- arguments: [ String ]
311
+ arguments: [ String ] ,
312
+ environment: [ String : String ] ? = nil
298
313
) throws {
299
314
// Make sure we are running from the original working directory.
300
315
let cwd : AbsolutePath ? = fileSystem. currentWorkingDirectory
@@ -303,7 +318,7 @@ public struct SwiftRunCommand: AsyncSwiftCommand {
303
318
}
304
319
305
320
let pathRelativeToWorkingDirectory = executablePath. relative ( to: originalWorkingDirectory)
306
- try execute ( path: executablePath. pathString, args: [ pathRelativeToWorkingDirectory. pathString] + arguments)
321
+ try execute ( path: executablePath. pathString, args: [ pathRelativeToWorkingDirectory. pathString] + arguments, env : environment )
307
322
}
308
323
309
324
/// Determines if a path points to a valid swift file.
@@ -327,7 +342,7 @@ public struct SwiftRunCommand: AsyncSwiftCommand {
327
342
}
328
343
329
344
/// A safe wrapper of TSCBasic.exec.
330
- private func execute( path: String , args: [ String ] ) throws -> Never {
345
+ private func execute( path: String , args: [ String ] , env : [ String : String ] ? ) throws -> Never {
331
346
#if !os(Windows)
332
347
// Dispatch will disable almost all asynchronous signals on its worker threads, and this is called from `async`
333
348
// context. To correctly `exec` a freshly built binary, we will need to:
@@ -358,6 +373,13 @@ public struct SwiftRunCommand: AsyncSwiftCommand {
358
373
#endif /* os(FreeBSD) || os(OpenBSD) */
359
374
#endif
360
375
376
+ if let env {
377
+ // set the env before we exec.
378
+ // TODO: we should really use execve here.
379
+ // Though, Windows doesn't really exec anyway.
380
+ try env. forEach { try ProcessEnv . setVar ( $0, value: $1) }
381
+ }
382
+
361
383
try TSCBasic . exec ( path: path, args: args)
362
384
}
363
385
0 commit comments