Skip to content

Commit 4891b69

Browse files
committed
Merge remote-tracking branch 'origin/main' into release/5.10
2 parents 4600f05 + 855b129 commit 4891b69

File tree

12 files changed

+592
-117
lines changed

12 files changed

+592
-117
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ Swift Next
77

88
In packages that specify resources using a future tools version, the generated resource bundle accessor will import `Foundation.Bundle` for its own implementation only. _Clients_ of such packages therefore no longer silently import `Foundation`, preventing inadvertent use of Foundation extensions to standard library APIs, which helps to avoid unexpected code size increases.
99

10+
* [#7010]
11+
12+
On macOS, `swift build` and `swift run` now produce binaries that allow backtraces in debug builds. Pass `SWIFT_BACKTRACE=enable=yes` environment variable to enable backtraces on such binaries when running them.
1013

1114
Swift 5.9
1215
-----------

Sources/Build/BuildDescription/ProductBuildDescription.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
367367

368368
return flags
369369
}
370+
371+
func codeSigningArguments(plistPath: AbsolutePath, binaryPath: AbsolutePath) -> [String] {
372+
["codesign", "--force", "--sign", "-", "--entitlements", plistPath.pathString, binaryPath.pathString]
373+
}
370374
}
371375

372376
extension SortedArray where Element == AbsolutePath {

Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,19 @@ extension LLBuildManifestBuilder {
3333
testInputs = []
3434
}
3535

36+
// Create a phony node to represent the entire target.
37+
let targetName = try buildProduct.product.getLLBuildTargetName(config: self.buildConfig)
38+
let output: Node = .virtual(targetName)
39+
40+
let finalProductNode: Node
3641
switch buildProduct.product.type {
3742
case .library(.static):
43+
finalProductNode = try .file(buildProduct.binaryPath)
3844
try self.manifest.addShellCmd(
3945
name: cmdName,
4046
description: "Archiving \(buildProduct.binaryPath.prettyPath())",
4147
inputs: (buildProduct.objects + [buildProduct.linkFileListPath]).map(Node.file),
42-
outputs: [.file(buildProduct.binaryPath)],
48+
outputs: [finalProductNode],
4349
arguments: try buildProduct.archiveArguments()
4450
)
4551

@@ -49,23 +55,55 @@ extension LLBuildManifestBuilder {
4955
+ [buildProduct.linkFileListPath]
5056
+ testInputs
5157

58+
let shouldCodeSign: Bool
59+
let linkedBinaryNode: Node
60+
let linkedBinaryPath = try buildProduct.binaryPath
61+
if case .executable = buildProduct.product.type,
62+
buildParameters.targetTriple.isMacOSX,
63+
buildParameters.debuggingParameters.shouldEnableDebuggingEntitlement {
64+
shouldCodeSign = true
65+
linkedBinaryNode = try .file(buildProduct.binaryPath, isMutated: true)
66+
} else {
67+
shouldCodeSign = false
68+
linkedBinaryNode = try .file(buildProduct.binaryPath)
69+
}
70+
5271
try self.manifest.addShellCmd(
5372
name: cmdName,
5473
description: "Linking \(buildProduct.binaryPath.prettyPath())",
5574
inputs: inputs.map(Node.file),
56-
outputs: [.file(buildProduct.binaryPath)],
75+
outputs: [linkedBinaryNode],
5776
arguments: try buildProduct.linkArguments()
5877
)
59-
}
6078

61-
// Create a phony node to represent the entire target.
62-
let targetName = try buildProduct.product.getLLBuildTargetName(config: self.buildConfig)
63-
let output: Node = .virtual(targetName)
79+
if shouldCodeSign {
80+
let basename = try buildProduct.binaryPath.basename
81+
let plistPath = try buildProduct.binaryPath.parentDirectory
82+
.appending(component: "\(basename)-entitlement.plist")
83+
self.manifest.addEntitlementPlistCommand(
84+
entitlement: "com.apple.security.get-task-allow",
85+
outputPath: plistPath
86+
)
87+
88+
let cmdName = try buildProduct.product.getCommandName(config: self.buildConfig)
89+
let codeSigningOutput = Node.virtual(targetName + "-CodeSigning")
90+
try self.manifest.addShellCmd(
91+
name: "\(cmdName)-entitlements",
92+
description: "Applying debug entitlements to \(buildProduct.binaryPath.prettyPath())",
93+
inputs: [linkedBinaryNode, .file(plistPath)],
94+
outputs: [codeSigningOutput],
95+
arguments: buildProduct.codeSigningArguments(plistPath: plistPath, binaryPath: linkedBinaryPath)
96+
)
97+
finalProductNode = codeSigningOutput
98+
} else {
99+
finalProductNode = linkedBinaryNode
100+
}
101+
}
64102

65103
self.manifest.addNode(output, toTarget: targetName)
66-
try self.manifest.addPhonyCmd(
104+
self.manifest.addPhonyCmd(
67105
name: output.name,
68-
inputs: [.file(buildProduct.binaryPath)],
106+
inputs: [finalProductNode],
69107
outputs: [output]
70108
)
71109

Sources/Build/BuildManifest/LLBuildManifestBuilder.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import struct TSCBasic.ByteString
2222
import enum TSCBasic.ProcessEnv
2323
import func TSCBasic.topologicalSort
2424

25+
/// High-level interface to ``LLBuildManifest`` and ``LLBuildManifestWriter``.
2526
public class LLBuildManifestBuilder {
2627
public enum TargetKind {
2728
case main
@@ -42,7 +43,7 @@ public class LLBuildManifestBuilder {
4243
public let disableSandboxForPluginCommands: Bool
4344

4445
/// File system reference.
45-
let fileSystem: FileSystem
46+
let fileSystem: any FileSystem
4647

4748
/// ObservabilityScope with which to emit diagnostics
4849
public let observabilityScope: ObservabilityScope
@@ -60,7 +61,7 @@ public class LLBuildManifestBuilder {
6061
public init(
6162
_ plan: BuildPlan,
6263
disableSandboxForPluginCommands: Bool = false,
63-
fileSystem: FileSystem,
64+
fileSystem: any FileSystem,
6465
observabilityScope: ObservabilityScope
6566
) {
6667
self.plan = plan

Sources/CoreCommands/Options.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,12 @@ public struct BuildOptions: ParsableArguments {
477477
)
478478
public var linkTimeOptimizationMode: LinkTimeOptimizationMode?
479479

480+
@Flag(help: .hidden)
481+
public var enableGetTaskAllowEntitlement: Bool = false
482+
483+
@Flag(help: .hidden)
484+
public var disableGetTaskAllowEntitlement: Bool = false
485+
480486
// @Flag works best when there is a default value present
481487
// if true, false aren't enough and a third state is needed
482488
// nil should not be the goto. Instead create an enum

Sources/CoreCommands/SwiftTool.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,11 @@ public final class SwiftTool {
664664
return buildSystem
665665
}
666666

667+
static let entitlementsMacOSWarning = """
668+
`--disable-get-task-allow-entitlement` and `--disable-get-task-allow-entitlement` only have an effect \
669+
when building on macOS.
670+
"""
671+
667672
private func _buildParams(toolchain: UserToolchain) throws -> BuildParameters {
668673
let hostTriple = try self.getHostToolchain().targetTriple
669674
let targetTriple = toolchain.targetTriple
@@ -672,6 +677,12 @@ public final class SwiftTool {
672677
component: targetTriple.platformBuildPathComponent(buildSystem: options.build.buildSystem)
673678
)
674679

680+
if !targetTriple.isMacOSX && (
681+
options.build.disableGetTaskAllowEntitlement || options.build.enableGetTaskAllowEntitlement
682+
) {
683+
observabilityScope.emit(warning: Self.entitlementsMacOSWarning)
684+
}
685+
675686
return try BuildParameters(
676687
dataPath: dataPath,
677688
configuration: options.build.configuration,
@@ -685,7 +696,13 @@ public final class SwiftTool {
685696
sanitizers: options.build.enabledSanitizers,
686697
indexStoreMode: options.build.indexStoreMode.buildParameter,
687698
isXcodeBuildSystemEnabled: options.build.buildSystem == .xcode,
688-
debugInfoFormat: options.build.debugInfoFormat.buildParameter,
699+
debuggingParameters: .init(
700+
debugInfoFormat: options.build.debugInfoFormat.buildParameter,
701+
targetTriple: targetTriple,
702+
shouldEnableDebuggingEntitlement:
703+
(options.build.configuration == .debug && !options.build.disableGetTaskAllowEntitlement) ||
704+
(options.build.enableGetTaskAllowEntitlement && !options.build.disableGetTaskAllowEntitlement)
705+
),
689706
driverParameters: .init(
690707
canRenameEntrypointFunctionName: driverSupport.checkSupportedFrontendFlags(
691708
flags: ["entry-point-function-name"],
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2020-2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import struct Basics.Triple
14+
import enum PackageModel.BuildConfiguration
15+
16+
extension BuildParameters {
17+
public struct Debugging: Encodable {
18+
public init(
19+
debugInfoFormat: DebugInfoFormat = .dwarf,
20+
targetTriple: Triple,
21+
shouldEnableDebuggingEntitlement: Bool
22+
) {
23+
self.debugInfoFormat = debugInfoFormat
24+
25+
// Per rdar://112065568 for backtraces to work on macOS a special entitlement needs to be granted on the final
26+
// executable.
27+
self.shouldEnableDebuggingEntitlement = targetTriple.isMacOSX && shouldEnableDebuggingEntitlement
28+
}
29+
30+
public var debugInfoFormat: DebugInfoFormat
31+
32+
/// Whether the produced executable should be codesigned with the debugging entitlement, enabling enhanced
33+
/// backtraces on macOS.
34+
public var shouldEnableDebuggingEntitlement: Bool
35+
}
36+
37+
/// Represents the debugging strategy.
38+
///
39+
/// Swift binaries requires the swiftmodule files in order for lldb to work.
40+
/// On Darwin, linker can directly take the swiftmodule file path using the
41+
/// -add_ast_path flag. On other platforms, we convert the swiftmodule into
42+
/// an object file using Swift's modulewrap tool.
43+
public enum DebuggingStrategy {
44+
case swiftAST
45+
case modulewrap
46+
}
47+
48+
/// The debugging strategy according to the current build parameters.
49+
public var debuggingStrategy: DebuggingStrategy? {
50+
guard configuration == .debug else {
51+
return nil
52+
}
53+
54+
if targetTriple.isApple() {
55+
return .swiftAST
56+
}
57+
return .modulewrap
58+
}
59+
60+
/// Represents the debug information format.
61+
///
62+
/// The debug information format controls the format of the debug information
63+
/// that the compiler generates. Some platforms support debug information
64+
// formats other than DWARF.
65+
public enum DebugInfoFormat: String, Encodable {
66+
/// DWARF debug information format, the default format used by Swift.
67+
case dwarf
68+
/// CodeView debug information format, used on Windows.
69+
case codeview
70+
/// No debug information to be emitted.
71+
case none
72+
}
73+
74+
}

Sources/SPMBuildCore/BuildParameters/BuildParameters.swift

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,6 @@ public struct BuildParameters: Encodable {
2626
case auto
2727
}
2828

29-
/// Represents the debug information format.
30-
///
31-
/// The debug information format controls the format of the debug information
32-
/// that the compiler generates. Some platforms support debug information
33-
// formats other than DWARF.
34-
public enum DebugInfoFormat: String, Encodable {
35-
/// DWARF debug information format, the default format used by Swift.
36-
case dwarf
37-
/// CodeView debug information format, used on Windows.
38-
case codeview
39-
/// No debug information to be emitted.
40-
case none
41-
}
42-
43-
/// Represents the debugging strategy.
44-
///
45-
/// Swift binaries requires the swiftmodule files in order for lldb to work.
46-
/// On Darwin, linker can directly take the swiftmodule file path using the
47-
/// -add_ast_path flag. On other platforms, we convert the swiftmodule into
48-
/// an object file using Swift's modulewrap tool.
49-
public enum DebuggingStrategy {
50-
case swiftAST
51-
case modulewrap
52-
}
53-
5429
/// The path to the data directory.
5530
public var dataPath: AbsolutePath
5631

@@ -125,10 +100,11 @@ public struct BuildParameters: Encodable {
125100
/// Whether the Xcode build system is used.
126101
public var isXcodeBuildSystemEnabled: Bool
127102

128-
public var debugInfoFormat: DebugInfoFormat
129-
130103
public var shouldSkipBuilding: Bool
131104

105+
/// Build parameters related to debugging.
106+
public var debuggingParameters: Debugging
107+
132108
/// Build parameters related to Swift Driver.
133109
public var driverParameters: Driver
134110

@@ -155,21 +131,25 @@ public struct BuildParameters: Encodable {
155131
sanitizers: EnabledSanitizers = EnabledSanitizers(),
156132
indexStoreMode: IndexStoreMode = .auto,
157133
isXcodeBuildSystemEnabled: Bool = false,
158-
debugInfoFormat: DebugInfoFormat = .dwarf,
159134
shouldSkipBuilding: Bool = false,
135+
debuggingParameters: Debugging? = nil,
160136
driverParameters: Driver = .init(),
161137
linkingParameters: Linking = .init(),
162138
outputParameters: Output = .init(),
163139
testingParameters: Testing? = nil
164140
) throws {
165141
let targetTriple = try targetTriple ?? .getHostTriple(usingSwiftCompiler: toolchain.swiftCompilerPath)
142+
self.debuggingParameters = debuggingParameters ?? .init(
143+
targetTriple: targetTriple,
144+
shouldEnableDebuggingEntitlement: configuration == .debug
145+
)
166146

167147
self.dataPath = dataPath
168148
self.configuration = configuration
169149
self._toolchain = _Toolchain(toolchain: toolchain)
170150
self.hostTriple = try hostTriple ?? .getHostTriple(usingSwiftCompiler: toolchain.swiftCompilerPath)
171151
self.targetTriple = targetTriple
172-
switch debugInfoFormat {
152+
switch self.debuggingParameters.debugInfoFormat {
173153
case .dwarf:
174154
var flags = flags
175155
// DWARF requires lld as link.exe expects CodeView debug info.
@@ -205,13 +185,11 @@ public struct BuildParameters: Encodable {
205185
self.sanitizers = sanitizers
206186
self.indexStoreMode = indexStoreMode
207187
self.isXcodeBuildSystemEnabled = isXcodeBuildSystemEnabled
208-
self.debugInfoFormat = debugInfoFormat
209188
self.shouldSkipBuilding = shouldSkipBuilding
210189
self.driverParameters = driverParameters
211190
self.linkingParameters = linkingParameters
212191
self.outputParameters = outputParameters
213192
self.testingParameters = testingParameters ?? .init(configuration: configuration, targetTriple: targetTriple)
214-
215193
}
216194

217195
public func forTriple(_ targetTriple: Triple) throws -> BuildParameters {
@@ -280,19 +258,6 @@ public struct BuildParameters: Encodable {
280258
public var testOutputPath: AbsolutePath {
281259
return buildPath.appending(component: "testOutput.txt")
282260
}
283-
284-
/// The debugging strategy according to the current build parameters.
285-
public var debuggingStrategy: DebuggingStrategy? {
286-
guard configuration == .debug else {
287-
return nil
288-
}
289-
290-
if targetTriple.isApple() {
291-
return .swiftAST
292-
}
293-
return .modulewrap
294-
}
295-
296261
/// Returns the path to the binary of a product for the current build parameters.
297262
public func binaryPath(for product: ResolvedProduct) throws -> AbsolutePath {
298263
return try buildPath.appending(binaryRelativePath(for: product))

Sources/SPMBuildCore/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
add_library(SPMBuildCore
1010
BinaryTarget+Extensions.swift
1111
BuildParameters/BuildParameters.swift
12+
BuildParameters/BuildParameters+Debugging.swift
1213
BuildParameters/BuildParameters+Driver.swift
1314
BuildParameters/BuildParameters+Linking.swift
1415
BuildParameters/BuildParameters+Output.swift

0 commit comments

Comments
 (0)