Skip to content

[Build] Link static swift stdlib by default on macOS #1246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Sources/Build/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,23 @@ public struct BuildParameters {
/// The tools version to use.
public let toolsVersion: ToolsVersion

/// If should link the Swift stdlib statically.
public let shouldLinkStaticSwiftStdlib: Bool

public init(
dataPath: AbsolutePath,
configuration: Configuration,
toolchain: Toolchain,
flags: BuildFlags,
toolsVersion: ToolsVersion = ToolsVersion.currentToolsVersion
toolsVersion: ToolsVersion = ToolsVersion.currentToolsVersion,
shouldLinkStaticSwiftStdlib: Bool = false
) {
self.dataPath = dataPath
self.configuration = configuration
self.toolchain = toolchain
self.flags = flags
self.toolsVersion = toolsVersion
self.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib
}
}

Expand Down Expand Up @@ -390,6 +395,13 @@ public final class ProductBuildDescription {
case .library(.dynamic):
args += ["-emit-library"]
case .executable:
// Link the Swift stdlib statically if requested.
if buildParameters.shouldLinkStaticSwiftStdlib {
// FIXME: This does not work for linux yet (SR-648).
#if os(macOS)
args += ["-static-stdlib"]
#endif
}
args += ["-emit-executable"]
}
args += objects.map({ $0.asString })
Expand Down
3 changes: 3 additions & 0 deletions Sources/Commands/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,8 @@ public class ToolOptions {
/// Path to the compilation destination describing JSON file.
public var customCompileDestination: AbsolutePath?

/// If should link the Swift stdlib statically.
public var shouldLinkStaticSwiftStdlib = false

public required init() {}
}
14 changes: 13 additions & 1 deletion Sources/Commands/SwiftTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,16 @@ public class SwiftTool<Options: ToolOptions> {
usage: "Increase verbosity of informational output"),
to: { $0.verbosity = $1 ? 1 : 0 })

binder.bind(
option: parser.add(option: "--no-static-swift-stdlib", kind: Bool.self,
usage: "Do not link Swift stdlib statically"),
to: { $0.shouldLinkStaticSwiftStdlib = !$1 })

binder.bind(
option: parser.add(option: "--static-swift-stdlib", kind: Bool.self,
usage: "Link Swift stdlib statically"),
to: { $0.shouldLinkStaticSwiftStdlib = $1 })

// Let subclasses bind arguments.
type(of: self).defineArguments(parser: parser, binder: binder)

Expand Down Expand Up @@ -432,7 +442,9 @@ public class SwiftTool<Options: ToolOptions> {
dataPath: buildPath,
configuration: options.configuration,
toolchain: try getToolchain(),
flags: options.buildFlags),
flags: options.buildFlags,
shouldLinkStaticSwiftStdlib: options.shouldLinkStaticSwiftStdlib
),
graph: try loadPackageGraph(),
delegate: self)
}
Expand Down
27 changes: 20 additions & 7 deletions Tests/BuildTests/BuildPlanTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,17 @@ private struct MockToolchain: Toolchain {

final class BuildPlanTests: XCTestCase {

func mockBuildParameters(buildPath: AbsolutePath = AbsolutePath("/path/to/build"), config: Build.Configuration = .debug) -> BuildParameters {
func mockBuildParameters(
buildPath: AbsolutePath = AbsolutePath("/path/to/build"),
config: Build.Configuration = .debug,
shouldLinkStaticSwiftStdlib: Bool = false
) -> BuildParameters {
return BuildParameters(
dataPath: buildPath,
configuration: config,
toolchain: MockToolchain(),
flags: BuildFlags())
flags: BuildFlags(),
shouldLinkStaticSwiftStdlib: shouldLinkStaticSwiftStdlib)
}

func testBasicSwiftPackage() throws {
Expand All @@ -59,7 +64,10 @@ final class BuildPlanTests: XCTestCase {
)
let diagnostics = DiagnosticsEngine()
let graph = loadMockPackageGraph(["/Pkg": pkg], root: "/Pkg", diagnostics: diagnostics, in: fs)
let result = BuildPlanResult(plan: try BuildPlan(buildParameters: mockBuildParameters(), graph: graph))
let result = BuildPlanResult(plan: try BuildPlan(
buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true),
graph: graph)
)

result.checkProductsCount(1)
result.checkTargetsCount(2)
Expand All @@ -70,12 +78,17 @@ final class BuildPlanTests: XCTestCase {
let lib = try result.target(for: "lib").swiftTarget().compileArguments()
XCTAssertEqual(lib, ["-swift-version", "3", "-Onone", "-g", "-enable-testing", "-j8", "-DSWIFT_PACKAGE", "-module-cache-path", "/path/to/build/debug/ModuleCache"])

XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug",
"-o", "/path/to/build/debug/exe", "-module-name", "exe",
"-emit-executable",
var linkArguments = ["/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug",
"-o", "/path/to/build/debug/exe", "-module-name", "exe"]
#if os(macOS)
linkArguments += ["-static-stdlib"]
#endif
linkArguments += ["-emit-executable",
"/path/to/build/debug/exe.build/main.swift.o",
"/path/to/build/debug/lib.build/lib.swift.o",
])
]

XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), linkArguments)
}

func testBasicReleasePackage() throws {
Expand Down