Skip to content

Commit

Permalink
Allow passing extra arguments to plugin compilation.
Browse files Browse the repository at this point in the history
For most case, compiling against the host toolchain does not need extra
arguments, but in some complicated setups, the host toolchain might need
extra arguments for search paths and such. In the case of the manifest,
the option of using `-Xmanifest` arguments to customize the manifest
compilation has existed for a while, but in the case of plugins, the
same option was not available and made consuming packages with plugins
very complicated.

The changes in this commit modify the former `-Xmanifest` to understand
an alias `-Xhost` and apply the provided arguments to both the manifest
and the plugin compilation, allowing complicated setups to provide their
values and compile and use plugins.

Includes modifications in one of the plugin tests to show that the
`-Xhost` parameters are passed to the plugin compilation (I could not
find a similar test for `-Xmanifest`).
  • Loading branch information
drodriguez committed Dec 20, 2022
1 parent f9f8d85 commit e013a62
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Note: This is in reverse chronological order, so newer entries are added to the
Swift 5.8
-----------

* [#5966]

Plugin compilation can be influenced by using `-Xhost` arguments in the `swift build` command line. This is similar to the existing mechanism for influencing the manifest compilation using `-Xmanifest` arguments. Both `-Xhost` and `-Xmanifest` are aliases of each other and will influence both the manifest and plugin compilation.

* [#5949]

New `--pkg-config-path` option on `build`, `test`, and `run` commands has been
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import PackagePlugin

@main
struct MyPlugin: BuildToolPlugin {
#if RETICULATE
let verb = "Reticulating"
#else
let verb = "Generating"
#endif

func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
print("Hello from the Build Tool Plugin!")
Expand All @@ -12,7 +17,7 @@ struct MyPlugin: BuildToolPlugin {
let outputPath = context.pluginWorkDirectory.appending(outputName)
return .buildCommand(
displayName:
"Generating \(outputName) from \($0.lastComponent)",
"\(verb) \(outputName) from \($0.lastComponent)",
executable:
try context.tool(named: "MySourceGenBuildTool").path,
arguments: [
Expand Down
7 changes: 4 additions & 3 deletions Sources/CoreCommands/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,12 @@ public struct BuildOptions: ParsableArguments {
shouldDisplay: false))
public var xcbuildFlags: [String] = []

@Option(name: .customLong("Xmanifest", withSingleDash: true),
@Option(name: [.customLong("Xmanifest", withSingleDash: true),
.customLong("Xhost", withSingleDash: true)],
parsing: .unconditionalSingleValue,
help: ArgumentHelp("Pass flag to the manifest build invocation",
help: ArgumentHelp("Pass flag to build invocation targetting the host (manifest and plugins)",
shouldDisplay: false))
public var manifestFlags: [String] = []
public var hostFlags: [String] = []

public var buildFlags: BuildFlags {
BuildFlags(
Expand Down
3 changes: 2 additions & 1 deletion Sources/CoreCommands/SwiftTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ public final class SwiftTool {
fileSystem: self.fileSystem,
cacheDir: cacheDir,
toolchain: self.getHostToolchain(),
extraHostFlags: self.options.build.hostFlags,
enableSandbox: !self.options.security.shouldDisableSandbox,
verboseOutput: self.logLevel <= .info
)
Expand Down Expand Up @@ -690,7 +691,7 @@ public final class SwiftTool {
cachePath = self.sharedCacheDirectory.map{ Workspace.DefaultLocations.manifestsDirectory(at: $0) }
}

var extraManifestFlags = self.options.build.manifestFlags
var extraManifestFlags = self.options.build.hostFlags
// Disable the implicit concurrency import if the compiler in use supports it to avoid warnings if we are building against an older SDK that does not contain a Concurrency module.
if DriverSupport.checkSupportedFrontendFlags(flags: ["disable-implicit-concurrency-module-import"], fileSystem: self.fileSystem) {
extraManifestFlags += ["-Xfrontend", "-disable-implicit-concurrency-module-import"]
Expand Down
7 changes: 6 additions & 1 deletion Sources/Workspace/DefaultPluginScriptRunner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ public struct DefaultPluginScriptRunner: PluginScriptRunner, Cancellable {
private let fileSystem: FileSystem
private let cacheDir: AbsolutePath
private let toolchain: UserToolchain
private let extraHostFlags: [String]
private let enableSandbox: Bool
private let cancellator: Cancellator
private let verboseOutput: Bool

private let sdkRootCache = ThreadSafeBox<AbsolutePath>()

public init(fileSystem: FileSystem, cacheDir: AbsolutePath, toolchain: UserToolchain, enableSandbox: Bool = true, verboseOutput: Bool = false) {
public init(fileSystem: FileSystem, cacheDir: AbsolutePath, toolchain: UserToolchain, extraHostFlags: [String] = [], enableSandbox: Bool = true, verboseOutput: Bool = false) {
self.fileSystem = fileSystem
self.cacheDir = cacheDir
self.toolchain = toolchain
self.extraHostFlags = extraHostFlags
self.enableSandbox = enableSandbox
self.cancellator = Cancellator(observabilityScope: .none)
self.verboseOutput = verboseOutput
Expand Down Expand Up @@ -208,6 +210,9 @@ public struct DefaultPluginScriptRunner: PluginScriptRunner, Cancellable {
// Finally add the output path of the compiled executable.
commandLine += ["-o", execFilePath.pathString]

// Add any extra flags passed for the host in the command line
commandLine += self.extraHostFlags

if (verboseOutput) {
commandLine.append("-v")
}
Expand Down
13 changes: 13 additions & 0 deletions Tests/FunctionalTests/PluginTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1003,4 +1003,17 @@ class PluginTests: XCTestCase {
XCTAssert(stdout.contains("Build complete!"), "stdout:\n\(stdout)")
}
}

func testPluginCanBeAffectedByXhostParameters() throws {
// Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require).
try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency")

try fixture(name: "Miscellaneous/Plugins") { fixturePath in
let (stdout, _) = try executeSwiftBuild(fixturePath.appending(component: "MySourceGenPlugin"), configuration: .Debug, extraArgs: ["--product", "MyLocalTool", "-Xhost", "-DRETICULATE"])
XCTAssert(stdout.contains("Linking MySourceGenBuildTool"), "stdout:\n\(stdout)")
XCTAssert(stdout.contains("Reticulating foo.swift from foo.dat"), "stdout:\n\(stdout)")
XCTAssert(stdout.contains("Linking MyLocalTool"), "stdout:\n\(stdout)")
XCTAssert(stdout.contains("Build complete!"), "stdout:\n\(stdout)")
}
}
}

0 comments on commit e013a62

Please sign in to comment.