Skip to content

Commit 42fcece

Browse files
authored
BuildPlan: infer -lc++ based on run-time triple (#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 0d43a5e commit 42fcece

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
@@ -632,9 +632,9 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
632632
// Note: This will come from build settings in future.
633633
for target in dependencies.staticTargets {
634634
if case let target as ClangTarget = target.underlyingTarget, target.isCXX {
635-
if buildParameters.hostTriple.isDarwin() {
635+
if buildParameters.triple.isDarwin() {
636636
buildProduct.additionalFlags += ["-lc++"]
637-
} else if buildParameters.hostTriple.isWindows() {
637+
} else if buildParameters.triple.isWindows() {
638638
// Don't link any C++ library.
639639
} else {
640640
buildProduct.additionalFlags += ["-lstdc++"]

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,21 +2174,34 @@ final class BuildPlanTests: XCTestCase {
21742174
)
21752175
XCTAssertNoDiagnostics(observability.diagnostics)
21762176

2177-
let result = try BuildPlanResult(plan: BuildPlan(
2177+
var result = try BuildPlanResult(plan: BuildPlan(
21782178
buildParameters: mockBuildParameters(),
21792179
graph: graph,
21802180
fileSystem: fs,
21812181
observabilityScope: observability.topScope
21822182
))
21832183
result.checkProductsCount(1)
21842184
result.checkTargetsCount(2)
2185-
let linkArgs = try result.buildProduct(for: "exe").linkArguments()
2185+
var linkArgs = try result.buildProduct(for: "exe").linkArguments()
21862186

21872187
#if os(macOS)
21882188
XCTAssertMatch(linkArgs, ["-lc++"])
21892189
#elseif !os(Windows)
21902190
XCTAssertMatch(linkArgs, ["-lstdc++"])
21912191
#endif
2192+
2193+
// Verify that `-lstdc++` is passed instead of `-lc++` when cross-compiling to Linux.
2194+
result = try BuildPlanResult(plan: BuildPlan(
2195+
buildParameters: mockBuildParameters(destinationTriple: .arm64Linux),
2196+
graph: graph,
2197+
fileSystem: fs,
2198+
observabilityScope: observability.topScope
2199+
))
2200+
result.checkProductsCount(1)
2201+
result.checkTargetsCount(2)
2202+
linkArgs = try result.buildProduct(for: "exe").linkArguments()
2203+
2204+
XCTAssertMatch(linkArgs, ["-lstdc++"])
21922205
}
21932206

21942207
func testDynamicProducts() throws {

Tests/BuildTests/MockBuildTestHelper.swift

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

4646

4747
extension Basics.Triple {
48+
static let x86_64MacOS = try! Self("x86_64-apple-macosx")
4849
static let x86_64Linux = try! Self("x86_64-unknown-linux-gnu")
4950
static let arm64Linux = try! Self("aarch64-unknown-linux-gnu")
5051
static let arm64Android = try! Self("aarch64-unknown-linux-android")

0 commit comments

Comments
 (0)