diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 3ee94eb4b6e..9c69183a546 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -238,6 +238,9 @@ public final class SwiftTargetBuildDescription { /// Whether or not to generate code for test observation. private let shouldGenerateTestObservation: Bool + /// Whether to disable sandboxing (e.g. for macros). + private let disableSandbox: Bool + /// Create a new target description with target and build parameters. init( package: ResolvedPackage, @@ -250,6 +253,7 @@ public final class SwiftTargetBuildDescription { requiredMacroProducts: [ResolvedProduct] = [], testTargetRole: TestTargetRole? = nil, shouldGenerateTestObservation: Bool = false, + disableSandbox: Bool, fileSystem: FileSystem, observabilityScope: ObservabilityScope ) throws { @@ -276,6 +280,7 @@ public final class SwiftTargetBuildDescription { self.prebuildCommandResults = prebuildCommandResults self.requiredMacroProducts = requiredMacroProducts self.shouldGenerateTestObservation = shouldGenerateTestObservation + self.disableSandbox = disableSandbox self.fileSystem = fileSystem self.observabilityScope = observabilityScope @@ -453,6 +458,18 @@ public final class SwiftTargetBuildDescription { args += ["-Xfrontend", "-external-plugin-path", "-Xfrontend", "\(localPluginPath)#\(pluginServer.pathString)"] } + if self.disableSandbox { + let toolchainSupportsDisablingSandbox = DriverSupport.checkSupportedFrontendFlags(flags: ["-disable-sandbox"], toolchain: self.buildParameters.toolchain, fileSystem: fileSystem) + if toolchainSupportsDisablingSandbox { + args += ["-disable-sandbox"] + } else { + // If there's at least one macro being used, we warn about our inability to disable sandboxing. + if !self.requiredMacroProducts.isEmpty { + observabilityScope.emit(warning: "cannot disable sandboxing for Swift compilation because the selected toolchain does not support it") + } + } + } + return args } diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index 7c9116d6285..2e7d973cf3f 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -545,6 +545,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS additionalFileRules: additionalFileRules, buildToolPluginInvocationResults: buildToolPluginInvocationResults, prebuildCommandResults: prebuildCommandResults, + disableSandbox: self.pluginConfiguration?.disableSandbox ?? false, fileSystem: self.fileSystem, observabilityScope: self.observabilityScope ) diff --git a/Sources/Build/BuildPlan/BuildPlan+Test.swift b/Sources/Build/BuildPlan/BuildPlan+Test.swift index 0b5427d134f..b0027c69487 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Test.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Test.swift @@ -28,6 +28,7 @@ extension BuildPlan { static func makeDerivedTestTargets( _ buildParameters: BuildParameters, _ graph: PackageGraph, + _ disableSandbox: Bool, _ fileSystem: FileSystem, _ observabilityScope: ObservabilityScope ) throws -> [(product: ResolvedProduct, discoveryTargetBuildDescription: SwiftTargetBuildDescription?, entryPointTargetBuildDescription: SwiftTargetBuildDescription)] { @@ -95,6 +96,7 @@ extension BuildPlan { toolsVersion: toolsVersion, buildParameters: buildParameters, testTargetRole: .discovery, + disableSandbox: disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -132,6 +134,7 @@ extension BuildPlan { toolsVersion: toolsVersion, buildParameters: buildParameters, testTargetRole: .entryPoint(isSynthesized: true), + disableSandbox: disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -174,6 +177,7 @@ extension BuildPlan { toolsVersion: toolsVersion, buildParameters: buildParameters, testTargetRole: .entryPoint(isSynthesized: false), + disableSandbox: disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -195,6 +199,7 @@ extension BuildPlan { toolsVersion: toolsVersion, buildParameters: buildParameters, testTargetRole: .entryPoint(isSynthesized: false), + disableSandbox: disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index 92c888ff178..fe748ba3ddb 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -235,6 +235,9 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// Cache for tools information. var externalExecutablesCache = [BinaryTarget: [ExecutableInfo]]() + /// Whether to disable sandboxing (e.g. for macros). + private let disableSandbox: Bool + /// The filesystem to operate on. let fileSystem: any FileSystem @@ -271,6 +274,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { additionalFileRules: [FileRuleDescription] = [], buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]] = [:], prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]] = [:], + disableSandbox: Bool = false, fileSystem: any FileSystem, observabilityScope: ObservabilityScope ) throws { @@ -279,6 +283,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { self.graph = graph self.buildToolPluginInvocationResults = buildToolPluginInvocationResults self.prebuildCommandResults = prebuildCommandResults + self.disableSandbox = disableSandbox self.fileSystem = fileSystem self.observabilityScope = observabilityScope.makeChildScope(description: "Build Plan") @@ -377,6 +382,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { prebuildCommandResults: prebuildCommandResults[target] ?? [], requiredMacroProducts: requiredMacroProducts, shouldGenerateTestObservation: generateTestObservation, + disableSandbox: self.disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope) ) @@ -423,6 +429,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { let derivedTestTargets = try Self.makeDerivedTestTargets( productsBuildParameters, graph, + self.disableSandbox, self.fileSystem, self.observabilityScope )