diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 67d1d5b2c9e..814f67e803e 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -235,6 +235,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, @@ -247,6 +250,7 @@ public final class SwiftTargetBuildDescription { requiredMacroProducts: [ResolvedProduct] = [], testTargetRole: TestTargetRole? = nil, shouldGenerateTestObservation: Bool = false, + disableSandbox: Bool, fileSystem: FileSystem, observabilityScope: ObservabilityScope ) throws { @@ -273,6 +277,7 @@ public final class SwiftTargetBuildDescription { self.prebuildCommandResults = prebuildCommandResults self.requiredMacroProducts = requiredMacroProducts self.shouldGenerateTestObservation = shouldGenerateTestObservation + self.disableSandbox = disableSandbox self.fileSystem = fileSystem self.observabilityScope = observabilityScope @@ -450,6 +455,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 94b8328502a..4c5c775ad2f 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -531,6 +531,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 0def8c0f985..49d98752bf6 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 ) @@ -128,6 +130,7 @@ extension BuildPlan { toolsVersion: toolsVersion, buildParameters: buildParameters, testTargetRole: .entryPoint(isSynthesized: true), + disableSandbox: disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -157,6 +160,7 @@ extension BuildPlan { toolsVersion: toolsVersion, buildParameters: buildParameters, testTargetRole: .entryPoint(isSynthesized: false), + disableSandbox: disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -175,6 +179,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 fadea472769..3c9e8064a2c 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -229,6 +229,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: FileSystem @@ -242,6 +245,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { additionalFileRules: [FileRuleDescription] = [], buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]] = [:], prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]] = [:], + disableSandbox: Bool = false, fileSystem: FileSystem, observabilityScope: ObservabilityScope ) throws { @@ -249,6 +253,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") @@ -331,6 +336,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { prebuildCommandResults: prebuildCommandResults[target] ?? [], requiredMacroProducts: requiredMacroProducts, shouldGenerateTestObservation: generateTestObservation, + disableSandbox: self.disableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope) ) @@ -377,6 +383,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { let derivedTestTargets = try Self.makeDerivedTestTargets( buildParameters, graph, + self.disableSandbox, self.fileSystem, self.observabilityScope )