Skip to content

Commit d2eb0ca

Browse files
authored
[cxx-interop] Make test discovery compatible with C++ interop (#7165)
### Motivation: 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. ### Modifications: This patch makes sure that the `-cxx-interoperability-mode=` command line flag gets propagated to the test discovery target. ### Result: Packages that use both C++ interop and test discovery can now be built successfully by SwiftPM. rdar://117078320 / resolves #6990
1 parent d457fa4 commit d2eb0ca

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,25 @@ public final class SwiftTargetBuildDescription {
555555
args += ["-color-diagnostics"]
556556
}
557557

558+
// If this is a generated test discovery target, it might import a test
559+
// target that is built with C++ interop enabled. In that case, the test
560+
// discovery target must enable C++ interop as well
561+
switch testTargetRole {
562+
case .discovery:
563+
for dependency in try self.target.recursiveTargetDependencies() {
564+
let dependencyScope = self.buildParameters.createScope(for: dependency)
565+
let dependencySwiftFlags = dependencyScope.evaluate(.OTHER_SWIFT_FLAGS)
566+
if let interopModeFlag = dependencySwiftFlags.first(where: { $0.hasPrefix("-cxx-interoperability-mode=") }) {
567+
args += [interopModeFlag]
568+
break
569+
}
570+
}
571+
if let cxxStandard = self.package.manifest.cxxLanguageStandard {
572+
args += ["-Xcc", "-std=\(cxxStandard)"]
573+
}
574+
default: break
575+
}
576+
558577
// Add arguments from declared build settings.
559578
args += try self.buildSettingsFlags()
560579

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3556,6 +3556,7 @@ final class BuildPlanTests: XCTestCase {
35563556
"/A/Sources/cbar/barcpp.cpp",
35573557
"/A/Sources/cbar/bar.c",
35583558
"/A/Sources/cbar/include/bar.h",
3559+
"/A/Tests/MySwiftTests/test.swift",
35593560

35603561
"/B/Sources/t1/dep.swift",
35613562
"/B/Sources/t2/dep.swift",
@@ -3566,6 +3567,7 @@ final class BuildPlanTests: XCTestCase {
35663567
displayName: "A",
35673568
path: "/A",
35683569
toolsVersion: .v5,
3570+
cxxLanguageStandard: "c++17",
35693571
dependencies: [
35703572
.localSourceControl(path: "/B", requirement: .upToNextMajor(from: "1.0.0")),
35713573
],
@@ -3606,6 +3608,12 @@ final class BuildPlanTests: XCTestCase {
36063608
.init(tool: .linker, kind: .unsafeFlags(["-Ilfoo", "-L", "lbar"])),
36073609
]
36083610
),
3611+
try TargetDescription(
3612+
name: "MySwiftTests", type: .test,
3613+
settings: [
3614+
.init(tool: .swift, kind: .interoperabilityMode(.Cxx)),
3615+
]
3616+
),
36093617
]
36103618
)
36113619

@@ -3682,6 +3690,7 @@ final class BuildPlanTests: XCTestCase {
36823690
"-Isfoo",
36833691
"-L", "sbar",
36843692
"-cxx-interoperability-mode=default",
3693+
"-Xcc", "-std=c++17",
36853694
"-enable-upcoming-feature", "BestFeature",
36863695
"-g",
36873696
"-Xcc", "-g",
@@ -3695,6 +3704,9 @@ final class BuildPlanTests: XCTestCase {
36953704

36963705
let linkExe = try result.buildProduct(for: "exe").linkArguments()
36973706
XCTAssertMatch(linkExe, [.anySequence, "-lsqlite3", "-llibz", "-Ilfoo", "-L", "lbar", "-g", .end])
3707+
3708+
let testDiscovery = try result.target(for: "APackageDiscoveredTests").swiftTarget().compileArguments()
3709+
XCTAssertMatch(testDiscovery, [.anySequence, "-cxx-interoperability-mode=default", "-Xcc", "-std=c++17"])
36983710
}
36993711

37003712
// omit frame pointers explicitly set to true
@@ -3739,6 +3751,7 @@ final class BuildPlanTests: XCTestCase {
37393751
"-Isfoo",
37403752
"-L", "sbar",
37413753
"-cxx-interoperability-mode=default",
3754+
"-Xcc", "-std=c++17",
37423755
"-enable-upcoming-feature",
37433756
"BestFeature",
37443757
"-g",
@@ -3794,6 +3807,7 @@ final class BuildPlanTests: XCTestCase {
37943807
"-Isfoo",
37953808
"-L", "sbar",
37963809
"-cxx-interoperability-mode=default",
3810+
"-Xcc", "-std=c++17",
37973811
"-enable-upcoming-feature",
37983812
"BestFeature",
37993813
"-g",
@@ -3836,6 +3850,7 @@ final class BuildPlanTests: XCTestCase {
38363850
"-Isfoo",
38373851
"-L", "sbar",
38383852
"-cxx-interoperability-mode=default",
3853+
"-Xcc", "-std=c++17",
38393854
"-enable-upcoming-feature", "BestFeature",
38403855
"-enable-upcoming-feature", "WorstFeature",
38413856
"-g",
@@ -3845,7 +3860,7 @@ final class BuildPlanTests: XCTestCase {
38453860
)
38463861

38473862
let exe = try result.target(for: "exe").swiftTarget().compileArguments()
3848-
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-cxx-interoperability-mode=default", "-g", "-Xcc", "-g", .end])
3863+
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-cxx-interoperability-mode=default", "-Xcc", "-std=c++17", "-g", "-Xcc", "-g", .end])
38493864

38503865
let linkExe = try result.buildProduct(for: "exe").linkArguments()
38513866
XCTAssertMatch(

0 commit comments

Comments
 (0)