Skip to content

Commit e858647

Browse files
Fix build of host&target destination products with --static-swift-stdlib (#7695)
### Motivation: Given the following conditions: - `--static-swift-stdlib` is enabled (it only affects "target" destination products, "host" destination products are always dynamic) - the building subset contains both "host" and "target" destination products derived from the same product. - the product imports `Foundation` (that has private dependency libs) then the build randomly failed due to the race condition of the Objects.LinkFileList creation. Reproducible project https://github.com/kateinoigakukun/swift-autolink-issue-repro ### Modifications: This commit fixes the issue by distinguishing the temporary link file list response file name by the `-tool` suffix. I think it would be better to add assertions in `LLBuildManifest` to avoid such unintentional target overwrites later. ### Result: Fix the build for the above case.
1 parent b86d22e commit e858647

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

Diff for: Sources/Build/BuildDescription/ProductBuildDescription.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
6666

6767
/// Path to the temporary directory for this product.
6868
var tempsPath: AbsolutePath {
69-
self.buildParameters.buildPath.appending(component: self.product.name + ".product")
69+
let suffix = buildParameters.suffix
70+
return self.buildParameters.buildPath.appending(component: "\(self.product.name)\(suffix).product")
7071
}
7172

7273
/// Path to the link filelist file.

Diff for: Tests/BuildTests/LLBuildManifestBuilderTests.swift

+2
Original file line numberDiff line numberDiff line change
@@ -218,5 +218,7 @@ final class LLBuildManifestBuilderTests: XCTestCase {
218218
let manifest = try builder.generateManifest(at: "/manifest")
219219

220220
XCTAssertNotNil(manifest.commands["C.SwiftSyntax-aarch64-unknown-linux-gnu-debug-tool.module"])
221+
// Ensure that Objects.LinkFileList is -tool suffixed.
222+
XCTAssertNotNil(manifest.commands["/path/to/build/aarch64-unknown-linux-gnu/debug/MMIOMacros-tool.product/Objects.LinkFileList"])
221223
}
222224
}

Diff for: Tests/CommandsTests/PackageCommandTests.swift

+26-1
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,30 @@ final class PackageCommandTests: CommandsTestCase {
15741574
}
15751575

15761576
func testBuildToolPlugin() async throws {
1577+
try await testBuildToolPlugin(staticStdlib: false)
1578+
}
1579+
1580+
func testBuildToolPluginWithStaticStdlib() async throws {
1581+
// Skip if the toolchain cannot compile a simple program with static stdlib.
1582+
do {
1583+
let args = try [
1584+
UserToolchain.default.swiftCompilerPath.pathString,
1585+
"-static-stdlib", "-emit-executable", "-o", "/dev/null", "-"
1586+
]
1587+
let process = AsyncProcess(arguments: args)
1588+
let stdin = try process.launch()
1589+
stdin.write(sequence: "".utf8)
1590+
try stdin.close()
1591+
let result = try await process.waitUntilExit()
1592+
try XCTSkipIf(
1593+
result.exitStatus != .terminated(code: 0),
1594+
"skipping because static stdlib is not supported by the toolchain"
1595+
)
1596+
}
1597+
try await testBuildToolPlugin(staticStdlib: true)
1598+
}
1599+
1600+
func testBuildToolPlugin(staticStdlib: Bool) async throws {
15771601
// Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require).
15781602
try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency")
15791603

@@ -1647,7 +1671,8 @@ final class PackageCommandTests: CommandsTestCase {
16471671
)
16481672

16491673
// Invoke it, and check the results.
1650-
let (stdout, stderr) = try await SwiftPM.Build.execute(packagePath: packageDir)
1674+
let args = staticStdlib ? ["--static-swift-stdlib"] : []
1675+
let (stdout, stderr) = try await SwiftPM.Build.execute(args, packagePath: packageDir)
16511676
XCTAssert(stdout.contains("Build complete!"))
16521677

16531678
// We expect a warning about `library.bar` but not about `library.foo`.

0 commit comments

Comments
 (0)