Skip to content

Commit d3e2eef

Browse files
committed
[Darwin] Add external plugin paths into platform specified by PLATFORM_DIR
The driver currently has logic to infer the location of the platform based on the conventional layout of SDKs within platforms. However, that doesn't work well when SDKs have been built up in other places. Introduce support for a second convention, that the PLATFORM_DIR environment variable can specify the path to the platform. When present, also add external plugin paths pointing into that platform. Fixes rdar://138370421.
1 parent 086c822 commit d3e2eef

File tree

2 files changed

+61
-21
lines changed

2 files changed

+61
-21
lines changed

Sources/SwiftDriver/Toolchains/DarwinToolchain.swift

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -456,29 +456,52 @@ public final class DarwinToolchain: Toolchain {
456456
}
457457

458458
if driver.isFrontendArgSupported(.externalPluginPath) {
459-
// Determine the platform path. For simulator platforms, look into the
460-
// corresponding device platform instance.
461-
let origPlatformPath = VirtualPath.lookup(sdkPath)
462-
.parentDirectory
463-
.parentDirectory
464-
.parentDirectory
465-
let platformPath: VirtualPath
466-
if let simulatorRange = origPlatformPath.basename.range(of: "Simulator.platform") {
467-
let devicePlatform = origPlatformPath.basename.replacingCharacters(in: simulatorRange, with: "OS.platform")
468-
platformPath = origPlatformPath.parentDirectory.appending(component: devicePlatform)
469-
} else {
470-
platformPath = origPlatformPath
471-
}
459+
// Determine the platform path based on the SDK path.
460+
addPluginPaths(
461+
forPlatform: VirtualPath.lookup(sdkPath)
462+
.parentDirectory
463+
.parentDirectory
464+
.parentDirectory,
465+
commandLine: &commandLine
466+
)
472467

473-
// Default paths for compiler plugins within the platform (accessed via that
474-
// platform's plugin server).
475-
let platformPathRoot = platformPath.appending(components: "Developer", "usr")
476-
commandLine.appendFlag(.externalPluginPath)
477-
commandLine.appendFlag("\(platformPathRoot.pluginPath.name)#\(platformPathRoot.pluginServerPath.name)")
468+
// If the PLATFORM_DIR environment variable is set, also add plugin
469+
// paths into it.
470+
if let platformDir = env["PLATFORM_DIR"],
471+
let platformPath = try? VirtualPath(path: platformDir) {
472+
addPluginPaths(
473+
forPlatform: platformPath,
474+
commandLine: &commandLine
475+
)
476+
}
477+
}
478+
}
478479

479-
commandLine.appendFlag(.externalPluginPath)
480-
commandLine.appendFlag("\(platformPathRoot.localPluginPath.name)#\(platformPathRoot.pluginServerPath.name)")
480+
/// Given the platform path (e.g., a path into something like iPhoneOS.platform),
481+
/// add external plugin path arguments for compiler plugins that are distributed
482+
/// within that path.
483+
func addPluginPaths(
484+
forPlatform origPlatformPath: VirtualPath,
485+
commandLine: inout [Job.ArgTemplate]
486+
) {
487+
// For simulator platforms, look into the corresponding device platform instance,
488+
// because they share compiler plugins.
489+
let platformPath: VirtualPath
490+
if let simulatorRange = origPlatformPath.basename.range(of: "Simulator.platform") {
491+
let devicePlatform = origPlatformPath.basename.replacingCharacters(in: simulatorRange, with: "OS.platform")
492+
platformPath = origPlatformPath.parentDirectory.appending(component: devicePlatform)
493+
} else {
494+
platformPath = origPlatformPath
481495
}
496+
497+
// Default paths for compiler plugins within the platform (accessed via that
498+
// platform's plugin server).
499+
let platformPathRoot = platformPath.appending(components: "Developer", "usr")
500+
commandLine.appendFlag(.externalPluginPath)
501+
commandLine.appendFlag("\(platformPathRoot.pluginPath.name)#\(platformPathRoot.pluginServerPath.name)")
502+
503+
commandLine.appendFlag(.externalPluginPath)
504+
commandLine.appendFlag("\(platformPathRoot.localPluginPath.name)#\(platformPathRoot.pluginServerPath.name)")
482505
}
483506
}
484507

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7749,7 +7749,12 @@ final class SwiftDriverTests: XCTestCase {
77497749
func pluginPathTest(platform: String, sdk: String, searchPlatform: String) throws {
77507750
let sdkRoot = try testInputsPath.appending(
77517751
components: ["Platform Checks", "\(platform).platform", "Developer", "SDKs", "\(sdk).sdk"])
7752-
var driver = try Driver(args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-plugin-path", "PluginA", "-external-plugin-path", "Plugin~B#Bexe", "-load-plugin-library", "PluginB2", "-plugin-path", "PluginC", "-working-directory", "/tmp"])
7752+
var env = ProcessEnv.vars
7753+
env["PLATFORM_DIR"] = "/tmp/PlatformDir/\(platform).platform"
7754+
var driver = try Driver(
7755+
args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-plugin-path", "PluginA", "-external-plugin-path", "Plugin~B#Bexe", "-load-plugin-library", "PluginB2", "-plugin-path", "PluginC", "-working-directory", "/tmp"],
7756+
env: env
7757+
)
77537758
guard driver.isFrontendArgSupported(.pluginPath) && driver.isFrontendArgSupported(.externalPluginPath) else {
77547759
return
77557760
}
@@ -7791,6 +7796,18 @@ final class SwiftDriverTests: XCTestCase {
77917796
XCTAssertNotNil(platformLocalPluginPathIndex)
77927797
XCTAssertLessThan(platformPluginPathIndex!, platformLocalPluginPathIndex!)
77937798

7799+
// Plugin paths that come from the PLATFORM_DIR environment variable.
7800+
let envOrigPlatformPath = try AbsolutePath(validating: "/tmp/PlatformDir/\(searchPlatform).platform")
7801+
let envPlatformPath = envOrigPlatformPath.appending(components: "Developer", "usr")
7802+
let envPlatformServerPath = envPlatformPath.appending(components: "bin", "swift-plugin-server").pathString
7803+
let envPlatformPluginPath = envPlatformPath.appending(components: "lib", "swift", "host", "plugins")
7804+
let envPlatformPluginPathIndex = job.commandLine.firstIndex(of: .flag("\(envPlatformPluginPath)#\(envPlatformServerPath)"))
7805+
XCTAssertNotNil(envPlatformPluginPathIndex)
7806+
7807+
if let platformPluginPathIndex, let envPlatformPluginPathIndex {
7808+
XCTAssertLessThan(platformPluginPathIndex, envPlatformPluginPathIndex)
7809+
}
7810+
77947811
let toolchainPluginPathIndex = job.commandLine.firstIndex(of: .path(.absolute(try driver.toolchain.executableDir.parentDirectory.appending(components: "lib", "swift", "host", "plugins"))))
77957812
XCTAssertNotNil(toolchainPluginPathIndex)
77967813

0 commit comments

Comments
 (0)