Skip to content

Commit 22b41d0

Browse files
authored
[6.0][PackageModel] Toolchain: Split SwiftTesting flags between swift compiler and linker (#7907)
- Explanation: Fixes a bug where keeping them together broke Symbol Graph Extract tool because it cannot handle `-Xlinker` flags. - Main Branch PR: #7903 - Resolves: rdar://134406349 - Risk: Low (This is technically an NFC since it only re-arranging how to the flags are propagated but doesn't change them). - Reviewed By: @MaxDesiatov - Testing: New tests were added to the test suite.
1 parent 5b6542d commit 22b41d0

File tree

2 files changed

+129
-9
lines changed

2 files changed

+129
-9
lines changed

Sources/PackageModel/UserToolchain.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,11 @@ public final class UserToolchain: Toolchain {
410410
static func deriveMacOSSpecificSwiftTestingFlags(
411411
derivedSwiftCompiler: AbsolutePath,
412412
fileSystem: any FileSystem
413-
) -> [String] {
413+
) -> (swiftCFlags: [String], linkerFlags: [String]) {
414414
guard let toolchainLibDir = try? toolchainLibDir(
415415
swiftCompilerPath: derivedSwiftCompiler
416416
) else {
417-
return []
417+
return (swiftCFlags: [], linkerFlags: [])
418418
}
419419

420420
let testingLibDir = toolchainLibDir.appending(
@@ -426,15 +426,16 @@ public final class UserToolchain: Toolchain {
426426
)
427427

428428
guard fileSystem.exists(testingLibDir), fileSystem.exists(testingPluginsDir) else {
429-
return []
429+
return (swiftCFlags: [], linkerFlags: [])
430430
}
431431

432-
return [
432+
return (swiftCFlags: [
433433
"-I", testingLibDir.pathString,
434434
"-L", testingLibDir.pathString,
435-
"-plugin-path", testingPluginsDir.pathString,
436-
"-Xlinker", "-rpath", "-Xlinker", testingLibDir.pathString,
437-
]
435+
"-plugin-path", testingPluginsDir.pathString
436+
], linkerFlags: [
437+
"-rpath", testingLibDir.pathString
438+
])
438439
}
439440

440441
internal static func deriveSwiftCFlags(
@@ -657,11 +658,15 @@ public final class UserToolchain: Toolchain {
657658
self.targetTriple = triple
658659

659660
var swiftCompilerFlags: [String] = []
661+
var extraLinkerFlags: [String] = []
662+
660663
#if os(macOS)
661-
swiftCompilerFlags += Self.deriveMacOSSpecificSwiftTestingFlags(
664+
let (swiftCFlags, linkerFlags) = Self.deriveMacOSSpecificSwiftTestingFlags(
662665
derivedSwiftCompiler: swiftCompilers.compile,
663666
fileSystem: fileSystem
664667
)
668+
swiftCompilerFlags += swiftCFlags
669+
extraLinkerFlags += linkerFlags
665670
#endif
666671

667672
swiftCompilerFlags += try Self.deriveSwiftCFlags(
@@ -671,11 +676,13 @@ public final class UserToolchain: Toolchain {
671676
fileSystem: fileSystem
672677
)
673678

679+
extraLinkerFlags += swiftSDK.toolset.knownTools[.linker]?.extraCLIOptions ?? []
680+
674681
self.extraFlags = BuildFlags(
675682
cCompilerFlags: swiftSDK.toolset.knownTools[.cCompiler]?.extraCLIOptions ?? [],
676683
cxxCompilerFlags: swiftSDK.toolset.knownTools[.cxxCompiler]?.extraCLIOptions ?? [],
677684
swiftCompilerFlags: swiftCompilerFlags,
678-
linkerFlags: swiftSDK.toolset.knownTools[.linker]?.extraCLIOptions ?? [],
685+
linkerFlags: extraLinkerFlags,
679686
xcbuildFlags: swiftSDK.toolset.knownTools[.xcbuild]?.extraCLIOptions ?? [])
680687

681688
self.includeSearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? []

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4633,6 +4633,119 @@ final class BuildPlanTests: XCTestCase {
46334633
])
46344634
}
46354635

4636+
func testSwiftTestingFlagsOnMacOSWithCustomToolchain() throws {
4637+
#if !os(macOS)
4638+
// This is testing swift-testing in a toolchain which is macOS only feature.
4639+
try XCTSkipIf(true, "test is only supported on macOS")
4640+
#endif
4641+
4642+
let fs = InMemoryFileSystem(
4643+
emptyFiles:
4644+
"/fake/path/lib/swift/macosx/testing/Testing.swiftmodule",
4645+
"/fake/path/lib/swift/host/plugins/testing/libTesting.dylib",
4646+
"/Pkg/Sources/Lib/main.swift",
4647+
"/Pkg/Tests/LibTest/test.swift"
4648+
)
4649+
try fs.createMockToolchain()
4650+
4651+
let userSwiftSDK = SwiftSDK(
4652+
hostTriple: .x86_64MacOS,
4653+
targetTriple: .x86_64MacOS,
4654+
toolset: .init(
4655+
knownTools: [
4656+
.cCompiler: .init(extraCLIOptions: []),
4657+
.swiftCompiler: .init(extraCLIOptions: []),
4658+
],
4659+
rootPaths: ["/fake/path/to"]
4660+
),
4661+
pathsConfiguration: .init(
4662+
sdkRootPath: "/fake/sdk",
4663+
swiftResourcesPath: "/fake/lib/swift",
4664+
swiftStaticResourcesPath: "/fake/lib/swift_static"
4665+
)
4666+
)
4667+
let mockToolchain = try UserToolchain(
4668+
swiftSDK: userSwiftSDK,
4669+
environment: .mockEnvironment,
4670+
fileSystem: fs
4671+
)
4672+
4673+
XCTAssertEqual(
4674+
mockToolchain.extraFlags.swiftCompilerFlags,
4675+
[
4676+
"-I", "/fake/path/lib/swift/macosx/testing",
4677+
"-L", "/fake/path/lib/swift/macosx/testing",
4678+
"-plugin-path", "/fake/path/lib/swift/host/plugins/testing",
4679+
"-sdk", "/fake/sdk",
4680+
]
4681+
)
4682+
XCTAssertEqual(
4683+
mockToolchain.extraFlags.linkerFlags,
4684+
["-rpath", "/fake/path/lib/swift/macosx/testing"]
4685+
)
4686+
4687+
let observability = ObservabilitySystem.makeForTesting()
4688+
let graph = try loadModulesGraph(
4689+
fileSystem: fs,
4690+
manifests: [
4691+
Manifest.createRootManifest(
4692+
displayName: "Pkg",
4693+
path: "/Pkg",
4694+
targets: [
4695+
TargetDescription(name: "Lib", dependencies: []),
4696+
TargetDescription(
4697+
name: "LibTest",
4698+
dependencies: ["Lib"],
4699+
type: .test
4700+
),
4701+
]
4702+
),
4703+
],
4704+
observabilityScope: observability.topScope
4705+
)
4706+
XCTAssertNoDiagnostics(observability.diagnostics)
4707+
4708+
let result = try BuildPlanResult(plan: mockBuildPlan(
4709+
toolchain: mockToolchain,
4710+
graph: graph,
4711+
commonFlags: .init(),
4712+
fileSystem: fs,
4713+
observabilityScope: observability.topScope
4714+
))
4715+
result.checkProductsCount(2)
4716+
result.checkTargetsCount(3)
4717+
4718+
let testProductLinkArgs = try result.buildProduct(for: "Lib").linkArguments()
4719+
XCTAssertMatch(testProductLinkArgs, [
4720+
.anySequence,
4721+
"-I", "/fake/path/lib/swift/macosx/testing",
4722+
"-L", "/fake/path/lib/swift/macosx/testing",
4723+
.anySequence,
4724+
"-Xlinker", "-rpath",
4725+
"-Xlinker", "/fake/path/lib/swift/macosx/testing",
4726+
])
4727+
4728+
let libModuleArgs = try result.moduleBuildDescription(for: "Lib").swift().compileArguments()
4729+
XCTAssertMatch(libModuleArgs, [
4730+
.anySequence,
4731+
"-I", "/fake/path/lib/swift/macosx/testing",
4732+
"-L", "/fake/path/lib/swift/macosx/testing",
4733+
"-plugin-path", "/fake/path/lib/swift/host/plugins/testing",
4734+
.anySequence,
4735+
])
4736+
XCTAssertNoMatch(libModuleArgs, ["-Xlinker"])
4737+
4738+
let testModuleArgs = try result.moduleBuildDescription(for: "LibTest").swift().compileArguments()
4739+
XCTAssertMatch(testModuleArgs, [
4740+
.anySequence,
4741+
"-I", "/fake/path/lib/swift/macosx/testing",
4742+
"-L", "/fake/path/lib/swift/macosx/testing",
4743+
"-plugin-path", "/fake/path/lib/swift/host/plugins/testing",
4744+
.anySequence,
4745+
])
4746+
XCTAssertNoMatch(testModuleArgs, ["-Xlinker"])
4747+
}
4748+
46364749
func testUserToolchainWithToolsetCompileFlags() throws {
46374750
let fileSystem = InMemoryFileSystem(
46384751
emptyFiles:

0 commit comments

Comments
 (0)