Skip to content

Commit 0d296c5

Browse files
committed
Properly set [DY]LD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH for immediate mode
1 parent c0ef6b1 commit 0d296c5

File tree

4 files changed

+122
-2
lines changed

4 files changed

+122
-2
lines changed

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
}
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
@@ -890,6 +890,12 @@ final class SwiftDriverTests: XCTestCase {
890890
XCTAssertTrue(job.commandLine.contains(.flag("foo")))
891891

892892
XCTAssertFalse(job.commandLine.contains(.flag("--")))
893+
894+
#if os(macOS)
895+
XCTAssertTrue(job.extraEnvironment.keys.contains("DYLD_LIBRARY_PATH"))
896+
#elseif os(Linux)
897+
XCTAssertTrue(job.extraEnvironment.keys.contains("LD_LIBRARY_PATH"))
898+
#endif
893899
}
894900

895901
do {
@@ -909,6 +915,30 @@ final class SwiftDriverTests: XCTestCase {
909915
XCTAssertTrue(job.commandLine.contains(.flag("args")))
910916
XCTAssertTrue(job.commandLine.contains(.flag("-for=foo")))
911917
}
918+
#if os(macOS)
919+
do {
920+
var driver = try Driver(args: ["swift", "-L/path/to/lib", "-F/path/to/framework", "foo.swift"])
921+
let plannedJobs = try driver.planBuild()
922+
XCTAssertEqual(plannedJobs.count, 1)
923+
let job = plannedJobs[0]
924+
XCTAssertEqual(job.inputs.count, 1)
925+
XCTAssertEqual(job.inputs[0].file, .relative(RelativePath("foo.swift")))
926+
XCTAssertEqual(job.outputs.count, 0)
927+
XCTAssertTrue(job.extraEnvironment.contains { $0 == "DYLD_LIBRARY_PATH" && $1.contains("/path/to/lib") })
928+
XCTAssertTrue(job.extraEnvironment.contains { $0 == "DYLD_FRAMEWORK_PATH" && $1.contains("/path/to/framework") })
929+
}
930+
#elseif os(Linux)
931+
do {
932+
var driver = try Driver(args: ["swift", "-L/path/to/lib", "foo.swift"])
933+
let plannedJobs = try driver.planBuild()
934+
XCTAssertEqual(plannedJobs.count, 1)
935+
let job = plannedJobs[0]
936+
XCTAssertEqual(job.inputs.count, 1)
937+
XCTAssertEqual(job.inputs[0].file, .relative(RelativePath("foo.swift")))
938+
XCTAssertEqual(job.outputs.count, 0)
939+
XCTAssertTrue(job.extraEnvironment.contains { $0 == "LD_LIBRARY_PATH" && $1.contains("/path/to/lib") })
940+
}
941+
#endif
912942
}
913943

914944
func testTargetTriple() throws {

0 commit comments

Comments
 (0)