Skip to content

Commit 76629d6

Browse files
authored
BuildPlan: infer -lc++ based on run-time triple (#6582)
Cherry-pick of #6581 Currently, when cross-compiling from Darwin to platforms that don't expect `-lc++` by default (e.g. most Linux distributions), the build will fail because `-lc++` is always passed. When should check the destination triple and not the host triple in the build plan code paths. This leads to confusing build errors when cross-compiling more complex projects like Vapor. rdar://107487090
1 parent 1ce786d commit 76629d6

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

Sources/Build/BuildPlan.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,9 +629,9 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
629629
// Note: This will come from build settings in future.
630630
for target in dependencies.staticTargets {
631631
if case let target as ClangTarget = target.underlyingTarget, target.isCXX {
632-
if buildParameters.hostTriple.isDarwin() {
632+
if buildParameters.triple.isDarwin() {
633633
buildProduct.additionalFlags += ["-lc++"]
634-
} else if buildParameters.hostTriple.isWindows() {
634+
} else if buildParameters.triple.isWindows() {
635635
// Don't link any C++ library.
636636
} else {
637637
buildProduct.additionalFlags += ["-lstdc++"]

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,21 +2165,34 @@ final class BuildPlanTests: XCTestCase {
21652165
)
21662166
XCTAssertNoDiagnostics(observability.diagnostics)
21672167

2168-
let result = try BuildPlanResult(plan: BuildPlan(
2168+
var result = try BuildPlanResult(plan: BuildPlan(
21692169
buildParameters: mockBuildParameters(),
21702170
graph: graph,
21712171
fileSystem: fs,
21722172
observabilityScope: observability.topScope
21732173
))
21742174
result.checkProductsCount(1)
21752175
result.checkTargetsCount(2)
2176-
let linkArgs = try result.buildProduct(for: "exe").linkArguments()
2176+
var linkArgs = try result.buildProduct(for: "exe").linkArguments()
21772177

21782178
#if os(macOS)
21792179
XCTAssertMatch(linkArgs, ["-lc++"])
21802180
#elseif !os(Windows)
21812181
XCTAssertMatch(linkArgs, ["-lstdc++"])
21822182
#endif
2183+
2184+
// Verify that `-lstdc++` is passed instead of `-lc++` when cross-compiling to Linux.
2185+
result = try BuildPlanResult(plan: BuildPlan(
2186+
buildParameters: mockBuildParameters(destinationTriple: .arm64Linux),
2187+
graph: graph,
2188+
fileSystem: fs,
2189+
observabilityScope: observability.topScope
2190+
))
2191+
result.checkProductsCount(1)
2192+
result.checkTargetsCount(2)
2193+
linkArgs = try result.buildProduct(for: "exe").linkArguments()
2194+
2195+
XCTAssertMatch(linkArgs, ["-lstdc++"])
21832196
}
21842197

21852198
func testDynamicProducts() throws {

Tests/BuildTests/MockBuildTestHelper.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct MockToolchain: PackageModel.Toolchain {
5050

5151

5252
extension Basics.Triple {
53+
static let x86_64MacOS = try! Self("x86_64-apple-macosx")
5354
static let x86_64Linux = try! Self("x86_64-unknown-linux-gnu")
5455
static let arm64Linux = try! Self("aarch64-unknown-linux-gnu")
5556
static let arm64Android = try! Self("aarch64-unknown-linux-android")

0 commit comments

Comments
 (0)