Skip to content

Commit b175e94

Browse files
committed
Add -dead_strip / --gc-sections for release builds
In the past it was unsafe to pass -dead_strip because there was some swift metadata that could be stripped. It seems that at this point all of those cases are either fixed or marked as @llvm.used, so passing these flags should safely reduce binary size in some cases. If there are other cases where this isn't safe we should likely annotate them as @llvm.used anyways. Related: https://bugs.swift.org/browse/SR-521 #215
1 parent 3cb4c9a commit b175e94

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

Sources/Build/BuildPlan.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,21 @@ public final class ProductBuildDescription {
12001200
return args.filter({ !invalidArguments.contains($0) })
12011201
}
12021202

1203+
private var deadStripArguments: [String] {
1204+
switch buildParameters.configuration {
1205+
case .debug:
1206+
return []
1207+
case .release:
1208+
if buildParameters.triple.isDarwin() {
1209+
return ["-Xlinker", "-dead_strip"]
1210+
} else if buildParameters.triple.isWindows() {
1211+
return ["-Xlinker", "/OPT:REF"]
1212+
} else {
1213+
return ["-Xlinker", "--gc-sections"]
1214+
}
1215+
}
1216+
}
1217+
12031218
/// The arguments to link and create this product.
12041219
public func linkArguments() throws -> [String] {
12051220
var args = [buildParameters.toolchain.swiftCompiler.pathString]
@@ -1246,12 +1261,14 @@ public final class ProductBuildDescription {
12461261
case .manifest:
12471262
args += ["-emit-executable"]
12481263
}
1264+
args += deadStripArguments
12491265
case .library(.dynamic):
12501266
args += ["-emit-library"]
12511267
if buildParameters.triple.isDarwin() {
12521268
let relativePath = "@rpath/\(buildParameters.binaryRelativePath(for: product).pathString)"
12531269
args += ["-Xlinker", "-install_name", "-Xlinker", relativePath]
12541270
}
1271+
args += deadStripArguments
12551272
case .executable, .snippet:
12561273
// Link the Swift stdlib statically, if requested.
12571274
if buildParameters.shouldLinkStaticSwiftStdlib {
@@ -1262,6 +1279,7 @@ public final class ProductBuildDescription {
12621279
}
12631280
}
12641281
args += ["-emit-executable"]
1282+
args += deadStripArguments
12651283

12661284
// If we're linking an executable whose main module is implemented in Swift,
12671285
// we rename the `_<modulename>_main` entry point symbol to `_main` again.

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ final class BuildPlanTests: XCTestCase {
466466
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
467467
"/fake/path/to/swiftc", "-g", "-L", "/path/to/build/release",
468468
"-o", "/path/to/build/release/exe", "-module-name", "exe", "-emit-executable",
469-
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
469+
"-Xlinker", "-dead_strip", "-Xlinker", "-rpath", "-Xlinker", "@loader_path",
470470
"@/path/to/build/release/exe.product/Objects.LinkFileList",
471471
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
472472
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx",
@@ -1029,7 +1029,7 @@ final class BuildPlanTests: XCTestCase {
10291029
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
10301030
"/fake/path/to/swiftc", "-g", "-L", "/path/to/build/release",
10311031
"-o", "/path/to/build/release/exe", "-module-name", "exe", "-emit-executable",
1032-
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
1032+
"-Xlinker", "-dead_strip", "-Xlinker", "-rpath", "-Xlinker", "@loader_path",
10331033
"@/path/to/build/release/exe.product/Objects.LinkFileList",
10341034
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
10351035
"-target", hostTriple.tripleString(forPlatformVersion: "12.0"),

0 commit comments

Comments
 (0)