Skip to content

Commit 1daaa1c

Browse files
authored
plugins: Build command plugin dependencies for the host, not the target (#6791)
When cross-compiling, SwiftPM plugins and their dependencies run on the host and so must be compiled for the host OS and architecture, not the cross-compiled target OS and architecture. SwiftPM will compile a command plugin for the host but if the plugin depends on an executable it will cross-compile the executable for the target, so the plugin will not be able to run it: error: Error Domain=NSPOSIXErrorDomain Code=8 "Exec format error" Command plugin dependencies are already handled specially in PluginCommand.run; this commit makes that special build step use the host toolchain instead of the target toolchain. #6060 handled the equivalent problem for build tool plugins.
1 parent c4396b3 commit 1daaa1c

File tree

3 files changed

+59
-39
lines changed

3 files changed

+59
-39
lines changed

Sources/Commands/PackageTools/PluginCommand.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,11 @@ struct PluginCommand: SwiftCommand {
250250
+ getEnvSearchPaths(pathString: ProcessEnv.path, currentWorkingDirectory: .none)
251251

252252
// Build or bring up-to-date any executable host-side tools on which this plugin depends. Add them and any binary dependencies to the tool-names-to-path map.
253-
let buildSystem = try swiftTool.createBuildSystem(explicitBuildSystem: .native, cacheBuildManifest: false)
253+
let buildSystem = try swiftTool.createBuildSystem(
254+
explicitBuildSystem: .native,
255+
cacheBuildManifest: false,
256+
customBuildParameters: swiftTool.hostBuildParameters()
257+
)
254258
let accessibleTools = try plugin.processAccessibleTools(
255259
packageGraph: packageGraph,
256260
fileSystem: swiftTool.fileSystem,

Sources/CoreCommands/SwiftTool.swift

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -664,51 +664,64 @@ public final class SwiftTool {
664664
return buildSystem
665665
}
666666

667+
private func _buildParams(toolchain: UserToolchain) throws -> BuildParameters {
668+
let targetTriple = toolchain.targetTriple
669+
670+
let dataPath = self.scratchDirectory.appending(
671+
component: targetTriple.platformBuildPathComponent(buildSystem: options.build.buildSystem)
672+
)
673+
674+
return try BuildParameters(
675+
dataPath: dataPath,
676+
configuration: options.build.configuration,
677+
toolchain: toolchain,
678+
targetTriple: targetTriple,
679+
flags: options.build.buildFlags,
680+
pkgConfigDirectories: options.locations.pkgConfigDirectories,
681+
architectures: options.build.architectures,
682+
workers: options.build.jobs ?? UInt32(ProcessInfo.processInfo.activeProcessorCount),
683+
shouldLinkStaticSwiftStdlib: options.linker.shouldLinkStaticSwiftStdlib,
684+
canRenameEntrypointFunctionName: driverSupport.checkSupportedFrontendFlags(
685+
flags: ["entry-point-function-name"],
686+
toolchain: toolchain,
687+
fileSystem: self.fileSystem
688+
),
689+
sanitizers: options.build.enabledSanitizers,
690+
enableCodeCoverage: false, // set by test commands when appropriate
691+
indexStoreMode: options.build.indexStoreMode.buildParameter,
692+
enableParseableModuleInterfaces: options.build.shouldEnableParseableModuleInterfaces,
693+
useIntegratedSwiftDriver: options.build.useIntegratedSwiftDriver,
694+
useExplicitModuleBuild: options.build.useExplicitModuleBuild,
695+
isXcodeBuildSystemEnabled: options.build.buildSystem == .xcode,
696+
forceTestDiscovery: options.build.enableTestDiscovery, // backwards compatibility, remove with --enable-test-discovery
697+
testEntryPointPath: options.build.testEntryPointPath,
698+
explicitTargetDependencyImportCheckingMode: options.build.explicitTargetDependencyImportCheck.modeParameter,
699+
linkerDeadStrip: options.linker.linkerDeadStrip,
700+
verboseOutput: self.logLevel <= .info,
701+
linkTimeOptimizationMode: options.build.linkTimeOptimizationMode?.buildParameter,
702+
debugInfoFormat: options.build.debugInfoFormat.buildParameter
703+
)
704+
}
705+
706+
/// Return the build parameters for the host toolchain.
707+
public func hostBuildParameters() throws -> BuildParameters {
708+
return try _hostBuildParameters.get()
709+
}
710+
711+
private lazy var _hostBuildParameters: Result<BuildParameters, Swift.Error> = {
712+
return Result(catching: {
713+
try _buildParams(toolchain: self.getHostToolchain())
714+
})
715+
}()
716+
667717
/// Return the build parameters.
668718
public func buildParameters() throws -> BuildParameters {
669719
return try _buildParameters.get()
670720
}
671721

672722
private lazy var _buildParameters: Result<BuildParameters, Swift.Error> = {
673723
return Result(catching: {
674-
let targetToolchain = try self.getTargetToolchain()
675-
let targetTriple = targetToolchain.targetTriple
676-
677-
// Use "apple" as the subdirectory because in theory Xcode build system
678-
// can be used to build for any Apple platform and it has it's own
679-
// conventions for build subpaths based on platforms.
680-
let dataPath = self.scratchDirectory.appending(
681-
component: targetTriple.platformBuildPathComponent(buildSystem: options.build.buildSystem)
682-
)
683-
684-
return try BuildParameters(
685-
dataPath: dataPath,
686-
configuration: options.build.configuration,
687-
toolchain: targetToolchain,
688-
targetTriple: targetTriple,
689-
flags: options.build.buildFlags,
690-
pkgConfigDirectories: options.locations.pkgConfigDirectories,
691-
architectures: options.build.architectures,
692-
workers: options.build.jobs ?? UInt32(ProcessInfo.processInfo.activeProcessorCount),
693-
shouldLinkStaticSwiftStdlib: options.linker.shouldLinkStaticSwiftStdlib,
694-
canRenameEntrypointFunctionName: driverSupport.checkSupportedFrontendFlags(
695-
flags: ["entry-point-function-name"], toolchain: targetToolchain, fileSystem: self.fileSystem
696-
),
697-
sanitizers: options.build.enabledSanitizers,
698-
enableCodeCoverage: false, // set by test commands when appropriate
699-
indexStoreMode: options.build.indexStoreMode.buildParameter,
700-
enableParseableModuleInterfaces: options.build.shouldEnableParseableModuleInterfaces,
701-
useIntegratedSwiftDriver: options.build.useIntegratedSwiftDriver,
702-
useExplicitModuleBuild: options.build.useExplicitModuleBuild,
703-
isXcodeBuildSystemEnabled: options.build.buildSystem == .xcode,
704-
forceTestDiscovery: options.build.enableTestDiscovery, // backwards compatibility, remove with --enable-test-discovery
705-
testEntryPointPath: options.build.testEntryPointPath,
706-
explicitTargetDependencyImportCheckingMode: options.build.explicitTargetDependencyImportCheck.modeParameter,
707-
linkerDeadStrip: options.linker.linkerDeadStrip,
708-
verboseOutput: self.logLevel <= .info,
709-
linkTimeOptimizationMode: options.build.linkTimeOptimizationMode?.buildParameter,
710-
debugInfoFormat: options.build.debugInfoFormat.buildParameter
711-
)
724+
try _buildParams(toolchain: self.getTargetToolchain())
712725
})
713726
}()
714727

Sources/SPMBuildCore/Triple+Extensions.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ extension Triple {
2424

2525
extension Triple {
2626
public func platformBuildPathComponent(buildSystem: BuildSystemProvider.Kind) -> String {
27+
// Use "apple" as the subdirectory because in theory Xcode build system
28+
// can be used to build for any Apple platform and it has its own
29+
// conventions for build subpaths based on platforms.
2730
buildSystem == .xcode ? "apple" : self.platformBuildPathComponent()
2831
}
2932
}

0 commit comments

Comments
 (0)