Skip to content

Commit 521275f

Browse files
authored
Merge pull request #40 from owenv/job-env-vars
Allow specifying custom environment variables for jobs
2 parents d547504 + 0d296c5 commit 521275f

File tree

6 files changed

+136
-4
lines changed

6 files changed

+136
-4
lines changed

Sources/SwiftDriver/Execution/JobExecutor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ class ExecuteJobRule: LLBuildRule {
333333
private func executeJob(_ engine: LLTaskBuildEngine) {
334334
let context = engine.jobExecutorContext
335335
let resolver = context.argsResolver
336-
let env = context.env
337336
let job = key.job
337+
let env = context.env.merging(job.extraEnvironment, uniquingKeysWith: { $1 })
338338

339339
let value: DriverBuildValue
340340
var pid = 0

Sources/SwiftDriver/Jobs/InterpretJob.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,17 @@ extension Driver {
3636
// The immediate arguments must be last.
3737
try commandLine.appendLast(.DASHDASH, from: &parsedOptions)
3838

39-
// FIXME: Set [DY]LD_LIBRARY_PATH, DYLD_FRAMEWORK_PATH if needed.
39+
let extraEnvironment = try toolchain.platformSpecificInterpreterEnvironmentVariables(
40+
env: self.env, parsedOptions: &parsedOptions, sdkPath: self.sdkPath,
41+
targetTriple: self.targetTriple)
4042

4143
return Job(
4244
kind: .interpret,
4345
tool: .absolute(try toolchain.getToolPath(.swiftCompiler)),
4446
commandLine: commandLine,
4547
inputs:inputs,
46-
outputs: []
48+
outputs: [],
49+
extraEnvironment: extraEnvironment
4750
)
4851
}
4952
}

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public struct Job: Codable, Equatable {
4545

4646
/// The outputs produced by the job.
4747
public var outputs: [TypedVirtualPath]
48+
49+
/// Any extra environment variables which should be set while running the job.
50+
public var extraEnvironment: [String: String]
4851

4952
/// The kind of job.
5053
public var kind: Kind
@@ -55,14 +58,16 @@ public struct Job: Codable, Equatable {
5558
commandLine: [ArgTemplate],
5659
displayInputs: [TypedVirtualPath]? = nil,
5760
inputs: [TypedVirtualPath],
58-
outputs: [TypedVirtualPath]
61+
outputs: [TypedVirtualPath],
62+
extraEnvironment: [String: String] = [:]
5963
) {
6064
self.kind = kind
6165
self.tool = tool
6266
self.commandLine = commandLine
6367
self.displayInputs = displayInputs ?? []
6468
self.inputs = inputs
6569
self.outputs = outputs
70+
self.extraEnvironment = extraEnvironment
6671
}
6772
}
6873

@@ -80,6 +85,13 @@ extension Job: CustomStringConvertible {
8085
}
8186
}
8287

88+
if !self.extraEnvironment.isEmpty {
89+
result += " #"
90+
for (envVar, val) in extraEnvironment {
91+
result += " \(envVar)=\(val)"
92+
}
93+
}
94+
8395
return result
8496
}
8597
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===----- Toolchain+InterpreterSupport.swift - Swift Interpreter Support -===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
14+
extension Toolchain {
15+
func addPathEnvironmentVariableIfNeeded(
16+
_ environmentVariable: String,
17+
to env: inout [String : String],
18+
currentEnv: [String: String],
19+
option: Option,
20+
parsedOptions: inout ParsedOptions,
21+
extraPaths: [String] = []
22+
) {
23+
let argPaths = parsedOptions.arguments(for: option)
24+
guard !argPaths.isEmpty || !extraPaths.isEmpty else { return }
25+
26+
env[environmentVariable] = (argPaths.map({ $0.argument.asSingle }) +
27+
extraPaths + [currentEnv[environmentVariable]]).compactMap{ $0 }.joined(separator: ":")
28+
}
29+
}
30+
31+
extension DarwinToolchain {
32+
public func platformSpecificInterpreterEnvironmentVariables(
33+
env: [String : String],
34+
parsedOptions: inout ParsedOptions,
35+
sdkPath: String?,
36+
targetTriple: Triple) throws -> [String: String] {
37+
var envVars: [String: String] = [:]
38+
39+
let runtimePaths = try runtimeLibraryPaths(
40+
for: targetTriple,
41+
parsedOptions: &parsedOptions,
42+
sdkPath: sdkPath,
43+
isShared: true
44+
).map { $0.pathString }
45+
46+
addPathEnvironmentVariableIfNeeded("DYLD_LIBRARY_PATH", to: &envVars,
47+
currentEnv: env, option: .L,
48+
parsedOptions: &parsedOptions,
49+
extraPaths: runtimePaths)
50+
51+
addPathEnvironmentVariableIfNeeded("DYLD_FRAMEWORK_PATH", to: &envVars,
52+
currentEnv: env, option: .F,
53+
parsedOptions: &parsedOptions)
54+
55+
return envVars
56+
}
57+
}
58+
59+
extension GenericUnixToolchain {
60+
public func platformSpecificInterpreterEnvironmentVariables(
61+
env: [String : String],
62+
parsedOptions: inout ParsedOptions,
63+
sdkPath: String?,
64+
targetTriple: Triple) throws -> [String: String] {
65+
var envVars: [String: String] = [:]
66+
67+
let runtimePaths = try runtimeLibraryPaths(
68+
for: targetTriple,
69+
parsedOptions: &parsedOptions,
70+
sdkPath: sdkPath,
71+
isShared: true
72+
).map { $0.pathString }
73+
74+
addPathEnvironmentVariableIfNeeded("LD_LIBRARY_PATH", to: &envVars,
75+
currentEnv: env, option: .L,
76+
parsedOptions: &parsedOptions,
77+
extraPaths: runtimePaths)
78+
79+
return envVars
80+
}
81+
}

Sources/SwiftDriver/Toolchains/Toolchain.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public protocol Toolchain {
5959
targetTriple: Triple,
6060
isShared: Bool
6161
) throws -> String
62+
63+
func platformSpecificInterpreterEnvironmentVariables(
64+
env: [String: String],
65+
parsedOptions: inout ParsedOptions,
66+
sdkPath: String?,
67+
targetTriple: Triple) throws -> [String: String]
6268
}
6369

6470
extension Toolchain {

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,12 @@ final class SwiftDriverTests: XCTestCase {
899899
XCTAssertTrue(job.commandLine.contains(.flag("foo")))
900900

901901
XCTAssertFalse(job.commandLine.contains(.flag("--")))
902+
903+
#if os(macOS)
904+
XCTAssertTrue(job.extraEnvironment.keys.contains("DYLD_LIBRARY_PATH"))
905+
#elseif os(Linux)
906+
XCTAssertTrue(job.extraEnvironment.keys.contains("LD_LIBRARY_PATH"))
907+
#endif
902908
}
903909

904910
do {
@@ -918,6 +924,30 @@ final class SwiftDriverTests: XCTestCase {
918924
XCTAssertTrue(job.commandLine.contains(.flag("args")))
919925
XCTAssertTrue(job.commandLine.contains(.flag("-for=foo")))
920926
}
927+
#if os(macOS)
928+
do {
929+
var driver = try Driver(args: ["swift", "-L/path/to/lib", "-F/path/to/framework", "foo.swift"])
930+
let plannedJobs = try driver.planBuild()
931+
XCTAssertEqual(plannedJobs.count, 1)
932+
let job = plannedJobs[0]
933+
XCTAssertEqual(job.inputs.count, 1)
934+
XCTAssertEqual(job.inputs[0].file, .relative(RelativePath("foo.swift")))
935+
XCTAssertEqual(job.outputs.count, 0)
936+
XCTAssertTrue(job.extraEnvironment.contains { $0 == "DYLD_LIBRARY_PATH" && $1.contains("/path/to/lib") })
937+
XCTAssertTrue(job.extraEnvironment.contains { $0 == "DYLD_FRAMEWORK_PATH" && $1.contains("/path/to/framework") })
938+
}
939+
#elseif os(Linux)
940+
do {
941+
var driver = try Driver(args: ["swift", "-L/path/to/lib", "foo.swift"])
942+
let plannedJobs = try driver.planBuild()
943+
XCTAssertEqual(plannedJobs.count, 1)
944+
let job = plannedJobs[0]
945+
XCTAssertEqual(job.inputs.count, 1)
946+
XCTAssertEqual(job.inputs[0].file, .relative(RelativePath("foo.swift")))
947+
XCTAssertEqual(job.outputs.count, 0)
948+
XCTAssertTrue(job.extraEnvironment.contains { $0 == "LD_LIBRARY_PATH" && $1.contains("/path/to/lib") })
949+
}
950+
#endif
921951
}
922952

923953
func testTargetTriple() throws {

0 commit comments

Comments
 (0)