Skip to content

Commit ed5461c

Browse files
authored
🍒[cxx-interop] Make test discovery compatible with C++ interop (#7177)
### 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 Original PR: #7165 (cherry picked from commit d2eb0ca)
1 parent b31f19e commit ed5461c

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,25 @@ 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+
if let cxxStandard = self.package.manifest.cxxLanguageStandard {
552+
args += ["-Xcc", "-std=\(cxxStandard)"]
553+
}
554+
default: break
555+
}
556+
538557
// Add arguments from declared build settings.
539558
args += try self.buildSettingsFlags()
540559

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 16 additions & 5 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",
@@ -3443,6 +3444,7 @@ final class BuildPlanTests: XCTestCase {
34433444
displayName: "A",
34443445
path: "/A",
34453446
toolsVersion: .v5,
3447+
cxxLanguageStandard: "c++17",
34463448
dependencies: [
34473449
.localSourceControl(path: "/B", requirement: .upToNextMajor(from: "1.0.0")),
34483450
],
@@ -3483,6 +3485,12 @@ final class BuildPlanTests: XCTestCase {
34833485
.init(tool: .linker, kind: .unsafeFlags(["-Ilfoo", "-L", "lbar"])),
34843486
]
34853487
),
3488+
try TargetDescription(
3489+
name: "MySwiftTests", type: .test,
3490+
settings: [
3491+
.init(tool: .swift, kind: .interoperabilityMode(.Cxx)),
3492+
]
3493+
),
34863494
]
34873495
)
34883496

@@ -3536,13 +3544,16 @@ final class BuildPlanTests: XCTestCase {
35363544
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", "-fno-omit-frame-pointer", .end])
35373545

35383546
let bar = try result.target(for: "bar").swiftTarget().compileArguments()
3539-
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end])
3547+
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-Xcc", "-std=c++17", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end])
35403548

35413549
let exe = try result.target(for: "exe").swiftTarget().compileArguments()
35423550
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end])
35433551

35443552
let linkExe = try result.buildProduct(for: "exe").linkArguments()
35453553
XCTAssertMatch(linkExe, [.anySequence, "-lsqlite3", "-llibz", "-Ilfoo", "-L", "lbar", "-g", .end])
3554+
3555+
let testDiscovery = try result.target(for: "APackageDiscoveredTests").swiftTarget().compileArguments()
3556+
XCTAssertMatch(testDiscovery, [.anySequence, "-cxx-interoperability-mode=default", "-Xcc", "-std=c++17"])
35463557
}
35473558

35483559
// omit frame pointers explicitly set to true
@@ -3564,7 +3575,7 @@ final class BuildPlanTests: XCTestCase {
35643575
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", "-fomit-frame-pointer", .end])
35653576

35663577
let bar = try result.target(for: "bar").swiftTarget().compileArguments()
3567-
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fomit-frame-pointer", .end])
3578+
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-Xcc", "-std=c++17", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fomit-frame-pointer", .end])
35683579

35693580
let exe = try result.target(for: "exe").swiftTarget().compileArguments()
35703581
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-g", "-Xcc", "-g", "-Xcc", "-fomit-frame-pointer", .end])
@@ -3589,7 +3600,7 @@ final class BuildPlanTests: XCTestCase {
35893600
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", "-fno-omit-frame-pointer", .end])
35903601

35913602
let bar = try result.target(for: "bar").swiftTarget().compileArguments()
3592-
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end])
3603+
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-Xcc", "-std=c++17", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end])
35933604

35943605
let exe = try result.target(for: "exe").swiftTarget().compileArguments()
35953606
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end])
@@ -3602,10 +3613,10 @@ final class BuildPlanTests: XCTestCase {
36023613
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", .end])
36033614

36043615
let bar = try result.target(for: "bar").swiftTarget().compileArguments()
3605-
XCTAssertMatch(bar, [.anySequence, "-DDMACOS", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-enable-upcoming-feature", "WorstFeature", "-g", "-Xcc", "-g", .end])
3616+
XCTAssertMatch(bar, [.anySequence, "-DDMACOS", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-Xcc", "-std=c++17", "-enable-upcoming-feature", "BestFeature", "-enable-upcoming-feature", "WorstFeature", "-g", "-Xcc", "-g", .end])
36063617

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

36103621
let linkExe = try result.buildProduct(for: "exe").linkArguments()
36113622
XCTAssertMatch(linkExe, [.anySequence, "-lsqlite3", "-llibz", "-framework", "CoreData", "-framework", "best", "-Ilfoo", "-L", "lbar", .anySequence])

0 commit comments

Comments
 (0)