Skip to content

Commit 7170a21

Browse files
kateinoigakukunMaxDesiatov
authored andcommitted
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. (cherry picked from commit e858647)
1 parent 757c1c2 commit 7170a21

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

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.

Tests/BuildTests/LLBuildManifestBuilderTests.swift

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

217217
XCTAssertNotNil(manifest.commands["C.SwiftSyntax-aarch64-unknown-linux-gnu-debug-tool.module"])
218+
// Ensure that Objects.LinkFileList is -tool suffixed.
219+
XCTAssertNotNil(manifest.commands["/path/to/build/aarch64-unknown-linux-gnu/debug/MMIOMacros-tool.product/Objects.LinkFileList"])
218220
}
219221
}

Tests/CommandsTests/PackageCommandTests.swift

+26-1
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,30 @@ final class PackageCommandTests: CommandsTestCase {
15711571
}
15721572

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

@@ -1644,7 +1668,8 @@ final class PackageCommandTests: CommandsTestCase {
16441668
)
16451669

16461670
// Invoke it, and check the results.
1647-
let (stdout, stderr) = try await SwiftPM.Build.execute(packagePath: packageDir)
1671+
let args = staticStdlib ? ["--static-swift-stdlib"] : []
1672+
let (stdout, stderr) = try await SwiftPM.Build.execute(args, packagePath: packageDir)
16481673
XCTAssert(stdout.contains("Build complete!"))
16491674

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

0 commit comments

Comments
 (0)