Skip to content

Commit e1b4410

Browse files
committed
[cxx-interop] Make test discovery compatible with C++ interop
If a Swift module is built with C++ interop enabled, all of its dependencies must also be built with C++ interop enabled. Swift packages that use test discovery get a synthesized "PackageDiscoveredTests" target which is built by SwiftPM when someone runs `swift test` command. This module is currently always built without C++ interop, which is causing issues for projects that rely on it. This patch makes sure that the `-cxx-interoperability-mode=` command line flag gets propagated to the test discovery target. rdar://117078320 / resolves #6990
1 parent e9fa373 commit e1b4410

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,22 @@ public final class SwiftTargetBuildDescription {
535535
args += ["-color-diagnostics"]
536536
}
537537

538+
// If this is a generated test discovery target, it might import a test
539+
// target that is built with C++ interop enabled. In that case, the test
540+
// discovery target must enable C++ interop as well
541+
switch testTargetRole {
542+
case .discovery:
543+
for dependency in try self.target.recursiveTargetDependencies() {
544+
let dependencyScope = self.buildParameters.createScope(for: dependency)
545+
let dependencySwiftFlags = dependencyScope.evaluate(.OTHER_SWIFT_FLAGS)
546+
if let interopModeFlag = dependencySwiftFlags.first(where: { $0.hasPrefix("-cxx-interoperability-mode=") }) {
547+
args += [interopModeFlag]
548+
break
549+
}
550+
}
551+
default: break
552+
}
553+
538554
// Add arguments from declared build settings.
539555
args += try self.buildSettingsFlags()
540556

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3433,6 +3433,7 @@ final class BuildPlanTests: XCTestCase {
34333433
"/A/Sources/cbar/barcpp.cpp",
34343434
"/A/Sources/cbar/bar.c",
34353435
"/A/Sources/cbar/include/bar.h",
3436+
"/A/Tests/MySwiftTests/test.swift",
34363437

34373438
"/B/Sources/t1/dep.swift",
34383439
"/B/Sources/t2/dep.swift",
@@ -3483,6 +3484,12 @@ final class BuildPlanTests: XCTestCase {
34833484
.init(tool: .linker, kind: .unsafeFlags(["-Ilfoo", "-L", "lbar"])),
34843485
]
34853486
),
3487+
try TargetDescription(
3488+
name: "MySwiftTests", type: .test,
3489+
settings: [
3490+
.init(tool: .swift, kind: .interoperabilityMode(.Cxx)),
3491+
]
3492+
),
34863493
]
34873494
)
34883495

@@ -3543,6 +3550,9 @@ final class BuildPlanTests: XCTestCase {
35433550

35443551
let linkExe = try result.buildProduct(for: "exe").linkArguments()
35453552
XCTAssertMatch(linkExe, [.anySequence, "-lsqlite3", "-llibz", "-Ilfoo", "-L", "lbar", "-g", .end])
3553+
3554+
let testDiscovery = try result.target(for: "APackageDiscoveredTests").swiftTarget().compileArguments()
3555+
XCTAssertMatch(testDiscovery, [.anySequence, "-cxx-interoperability-mode=default"])
35463556
}
35473557

35483558
// omit frame pointers explicitly set to true

0 commit comments

Comments
 (0)