Skip to content

Commit 99d316a

Browse files
authored
Merge pull request #1377 from DougGregor/executable-plugin-paths
Add SDK and platform paths to plugin executables
2 parents 9e78be1 + b67a70c commit 99d316a

File tree

3 files changed

+112
-17
lines changed

3 files changed

+112
-17
lines changed

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

+16-15
Original file line numberDiff line numberDiff line change
@@ -261,22 +261,11 @@ extension Driver {
261261
try commandLine.appendLast(.emitMacroExpansionFiles, from: &parsedOptions)
262262
}
263263

264-
if isFrontendArgSupported(.pluginPath) {
265-
try commandLine.appendAll(.pluginPath, from: &parsedOptions)
266-
267-
let defaultPluginPath = try toolchain.executableDir.parentDirectory
268-
.appending(components: "lib", "swift", "host", "plugins")
269-
commandLine.appendFlag(.pluginPath)
270-
commandLine.appendPath(defaultPluginPath)
271-
272-
let localPluginPath = try toolchain.executableDir.parentDirectory
273-
.appending(components: "local", "lib", "swift", "host", "plugins")
274-
commandLine.appendFlag(.pluginPath)
275-
commandLine.appendPath(localPluginPath)
276-
}
277-
264+
// Emit user-provided plugin paths, in order.
278265
if isFrontendArgSupported(.externalPluginPath) {
279-
try commandLine.appendAll(.externalPluginPath, from: &parsedOptions)
266+
try commandLine.appendAll(.pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPluginExecutable, from: &parsedOptions)
267+
} else if isFrontendArgSupported(.pluginPath) {
268+
try commandLine.appendAll(.pluginPath, .loadPluginLibrary, from: &parsedOptions)
280269
}
281270

282271
if isFrontendArgSupported(.blockListFile) {
@@ -394,6 +383,18 @@ extension Driver {
394383
inputs: &inputs,
395384
frontendTargetInfo: frontendTargetInfo,
396385
driver: &self)
386+
387+
// Platform-agnostic options that need to happen after platform-specific ones.
388+
if isFrontendArgSupported(.pluginPath) {
389+
// Default paths for compiler plugins found within the toolchain
390+
// (loaded as shared libraries).
391+
let pluginPathRoot = VirtualPath.absolute(try toolchain.executableDir.parentDirectory)
392+
commandLine.appendFlag(.pluginPath)
393+
commandLine.appendPath(pluginPathRoot.pluginPath)
394+
395+
commandLine.appendFlag(.pluginPath)
396+
commandLine.appendPath(pluginPathRoot.localPluginPath)
397+
}
397398
}
398399

399400
mutating func addFrontendSupplementaryOutputArguments(commandLine: inout [Job.ArgTemplate],

Sources/SwiftDriver/Toolchains/DarwinToolchain.swift

+44
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,30 @@ public final class DarwinToolchain: Toolchain {
421421
commandLine.appendFlag(.clangTarget)
422422
commandLine.appendFlag(clangTargetTriple)
423423
}
424+
425+
if driver.isFrontendArgSupported(.externalPluginPath) {
426+
// Default paths for compiler plugins found within an SDK (accessed via
427+
// that SDK's plugin server).
428+
let sdkPathRoot = VirtualPath.lookup(sdkPath).appending(components: "usr")
429+
commandLine.appendFlag(.externalPluginPath)
430+
commandLine.appendFlag("\(sdkPathRoot.pluginPath.name)#\(sdkPathRoot.pluginServerPath.name.spm_shellEscaped())")
431+
432+
commandLine.appendFlag(.externalPluginPath)
433+
commandLine.appendFlag("\(sdkPathRoot.localPluginPath.name)#\(sdkPathRoot.pluginServerPath.name.spm_shellEscaped())")
434+
435+
// Default paths for compiler plugins within the platform (accessed via that
436+
// platform's plugin server).
437+
let platformPathRoot = VirtualPath.lookup(sdkPath)
438+
.parentDirectory
439+
.parentDirectory
440+
.parentDirectory
441+
.appending(components: "Developer", "usr")
442+
commandLine.appendFlag(.externalPluginPath)
443+
commandLine.appendFlag("\(platformPathRoot.pluginPath.name)#\(platformPathRoot.pluginServerPath.name.spm_shellEscaped())")
444+
445+
commandLine.appendFlag(.externalPluginPath)
446+
commandLine.appendFlag("\(platformPathRoot.localPluginPath.name)#\(platformPathRoot.pluginServerPath.name.spm_shellEscaped())")
447+
}
424448
}
425449
}
426450

@@ -441,3 +465,23 @@ private extension Version {
441465
return self.description
442466
}
443467
}
468+
469+
extension VirtualPath {
470+
// Given a virtual path pointing into a toolchain/SDK/platform, produce the
471+
// path to `swift-plugin-server`.
472+
fileprivate var pluginServerPath: VirtualPath {
473+
self.appending(components: "bin", "swift-plugin-server")
474+
}
475+
476+
// Given a virtual path pointing into a toolchain/SDK/platform, produce the
477+
// path to the plugins.
478+
var pluginPath: VirtualPath {
479+
self.appending(components: "lib", "swift", "host", "plugins")
480+
}
481+
482+
// Given a virtual path pointing into a toolchain/SDK/platform, produce the
483+
// path to the plugins.
484+
var localPluginPath: VirtualPath {
485+
self.appending(component: "local").pluginPath
486+
}
487+
}

Tests/SwiftDriverTests/SwiftDriverTests.swift

+52-2
Original file line numberDiff line numberDiff line change
@@ -6798,14 +6798,64 @@ final class SwiftDriverTests: XCTestCase {
67986798
}
67996799

68006800
func testPluginPaths() throws {
6801-
var driver = try Driver(args: ["swiftc", "-typecheck", "foo.swift"])
6802-
guard driver.isFrontendArgSupported(.pluginPath) else {
6801+
let sdkRoot = testInputsPath.appending(component: "SDKChecks").appending(component: "iPhoneOS.sdk")
6802+
var driver = try Driver(args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-plugin-path", "PluginA", "-external-plugin-path", "PluginB#Bexe", "-load-plugin-library", "PluginB2", "-plugin-path", "PluginC"])
6803+
guard driver.isFrontendArgSupported(.pluginPath) && driver.isFrontendArgSupported(.externalPluginPath) else {
68036804
return
68046805
}
68056806

68066807
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
68076808
XCTAssertEqual(jobs.count, 1)
68086809
let job = jobs.first!
6810+
6811+
// Check that the we have the plugin paths we expect, in the order we expect.
6812+
let pluginAIndex = job.commandLine.firstIndex(of: .path(VirtualPath.relative(.init("PluginA"))))
6813+
XCTAssertNotNil(pluginAIndex)
6814+
6815+
let pluginBIndex = job.commandLine.firstIndex(of: .path(VirtualPath.relative(.init("PluginB#Bexe"))))
6816+
XCTAssertNotNil(pluginBIndex)
6817+
XCTAssertLessThan(pluginAIndex!, pluginBIndex!)
6818+
6819+
let pluginB2Index = job.commandLine.firstIndex(of: .path(VirtualPath.relative(.init("PluginB2"))))
6820+
XCTAssertNotNil(pluginB2Index)
6821+
XCTAssertLessThan(pluginBIndex!, pluginB2Index!)
6822+
6823+
let pluginCIndex = job.commandLine.firstIndex(of: .path(VirtualPath.relative(.init("PluginC"))))
6824+
XCTAssertNotNil(pluginCIndex)
6825+
XCTAssertLessThan(pluginB2Index!, pluginCIndex!)
6826+
6827+
#if os(macOS)
6828+
XCTAssertTrue(job.commandLine.contains(.flag("-external-plugin-path")))
6829+
let sdkServerPath = sdkRoot.appending(components: "usr", "bin", "swift-plugin-server").pathString
6830+
let sdkPluginPath = sdkRoot.appending(components: "usr", "lib", "swift", "host", "plugins").pathString
6831+
6832+
let sdkPluginPathIndex = job.commandLine.firstIndex(of: .flag("\(sdkPluginPath)#\(sdkServerPath)"))
6833+
XCTAssertNotNil(sdkPluginPathIndex)
6834+
XCTAssertLessThan(pluginCIndex!, sdkPluginPathIndex!)
6835+
6836+
let sdkLocalPluginPath = sdkRoot.appending(components: "usr", "local", "lib", "swift", "host", "plugins").pathString
6837+
let sdkLocalPluginPathIndex = job.commandLine.firstIndex(of: .flag("\(sdkLocalPluginPath)#\(sdkServerPath)"))
6838+
XCTAssertNotNil(sdkLocalPluginPathIndex)
6839+
XCTAssertLessThan(sdkPluginPathIndex!, sdkLocalPluginPathIndex!)
6840+
6841+
let platformPath = sdkRoot.parentDirectory.parentDirectory.parentDirectory.appending(components: "Developer", "usr")
6842+
let platformServerPath = platformPath.appending(components: "bin", "swift-plugin-server").pathString
6843+
6844+
let platformPluginPath = platformPath.appending(components: "lib", "swift", "host", "plugins")
6845+
let platformPluginPathIndex = job.commandLine.firstIndex(of: .flag("\(platformPluginPath)#\(platformServerPath)"))
6846+
XCTAssertNotNil(platformPluginPathIndex)
6847+
XCTAssertLessThan(sdkLocalPluginPathIndex!, platformPluginPathIndex!)
6848+
6849+
let platformLocalPluginPath = platformPath.appending(components: "local", "lib", "swift", "host", "plugins")
6850+
let platformLocalPluginPathIndex = job.commandLine.firstIndex(of: .flag("\(platformLocalPluginPath)#\(platformServerPath)"))
6851+
XCTAssertNotNil(platformLocalPluginPathIndex)
6852+
XCTAssertLessThan(platformPluginPathIndex!, platformLocalPluginPathIndex!)
6853+
6854+
let toolchainPluginPathIndex = job.commandLine.firstIndex(of: .path(.absolute(try driver.toolchain.executableDir.parentDirectory.appending(components: "lib", "swift", "host", "plugins"))))
6855+
XCTAssertNotNil(toolchainPluginPathIndex)
6856+
XCTAssertLessThan(platformLocalPluginPathIndex!, toolchainPluginPathIndex!)
6857+
#endif
6858+
68096859
XCTAssertTrue(job.commandLine.contains(.flag("-plugin-path")))
68106860
XCTAssertTrue(job.commandLine.contains(.path(.absolute(try driver.toolchain.executableDir.parentDirectory.appending(components: "lib", "swift", "host", "plugins")))))
68116861
XCTAssertTrue(job.commandLine.contains(.path(.absolute(try driver.toolchain.executableDir.parentDirectory.appending(components: "local", "lib", "swift", "host", "plugins")))))

0 commit comments

Comments
 (0)