mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
fix parallel build race condition with content-hashed shim files
The platform shim generation was writing to fixed filenames (platform_shim.bc and platform_shim.o) in the shared cache directory, causing race conditions when multiple builds ran in parallel. Fix: Include a CRC32 hash of the serialized module content in the shim filenames. Each unique module content now gets its own shim files, allowing parallel builds to proceed without interfering with each other. Also: - Remove obsolete wasm-elem test platform from build.zig - Update CLI tests to run in parallel instead of sequentially 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
cd6a5900c6
commit
e9ecd840c5
2 changed files with 27 additions and 25 deletions
32
build.zig
32
build.zig
|
|
@ -1443,22 +1443,6 @@ fn setupTestPlatforms(
|
|||
clear_cache_step.dependOn(©_step.step);
|
||||
}
|
||||
|
||||
// Build the wasm-elem test platform host for wasm32-freestanding (tests parameterized opaque types with requires clause)
|
||||
{
|
||||
const wasm_target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding, .abi = .none });
|
||||
const copy_step = buildAndCopyTestPlatformHostLib(
|
||||
b,
|
||||
"wasm-elem",
|
||||
wasm_target,
|
||||
"wasm32",
|
||||
optimize,
|
||||
roc_modules,
|
||||
strip,
|
||||
omit_frame_pointer,
|
||||
);
|
||||
clear_cache_step.dependOn(©_step.step);
|
||||
}
|
||||
|
||||
b.getInstallStep().dependOn(clear_cache_step);
|
||||
test_platforms_step.dependOn(clear_cache_step);
|
||||
}
|
||||
|
|
@ -1680,8 +1664,7 @@ pub fn build(b: *std.Build) void {
|
|||
b.installArtifact(test_runner_exe);
|
||||
|
||||
// CLI integration tests - run actual roc programs like CI does
|
||||
// NOTE: These tests must run sequentially to avoid race conditions on the Roc cache
|
||||
// Order: test_runner int -> test_runner str -> roc_subcommands_test
|
||||
// These tests can run in parallel since each build uses content-hashed shim files
|
||||
if (!no_bin) {
|
||||
const install = b.addInstallArtifact(roc_exe, .{});
|
||||
const install_runner = b.addInstallArtifact(test_runner_exe, .{});
|
||||
|
|
@ -1694,16 +1677,19 @@ pub fn build(b: *std.Build) void {
|
|||
run_int_tests.step.dependOn(&install.step);
|
||||
run_int_tests.step.dependOn(&install_runner.step);
|
||||
run_int_tests.step.dependOn(test_platforms_step);
|
||||
test_cli_step.dependOn(&run_int_tests.step);
|
||||
|
||||
// Test str platform (native mode only for now)
|
||||
// Run after int tests to avoid cache race conditions
|
||||
const run_str_tests = b.addRunArtifact(test_runner_exe);
|
||||
run_str_tests.addArg("zig-out/bin/roc");
|
||||
run_str_tests.addArg("str");
|
||||
run_str_tests.addArg("--mode=native");
|
||||
run_str_tests.step.dependOn(&run_int_tests.step);
|
||||
run_str_tests.step.dependOn(&install.step);
|
||||
run_str_tests.step.dependOn(&install_runner.step);
|
||||
run_str_tests.step.dependOn(test_platforms_step);
|
||||
test_cli_step.dependOn(&run_str_tests.step);
|
||||
|
||||
// Roc subcommands integration test - runs after test_runner tests
|
||||
// Roc subcommands integration test
|
||||
const roc_subcommands_test = b.addTest(.{
|
||||
.name = "roc_subcommands_test",
|
||||
.root_module = b.createModule(.{
|
||||
|
|
@ -1718,8 +1704,8 @@ pub fn build(b: *std.Build) void {
|
|||
if (run_args.len != 0) {
|
||||
run_roc_subcommands_test.addArgs(run_args);
|
||||
}
|
||||
run_roc_subcommands_test.step.dependOn(&run_str_tests.step); // Run after test_runner
|
||||
|
||||
run_roc_subcommands_test.step.dependOn(&install.step);
|
||||
run_roc_subcommands_test.step.dependOn(test_platforms_step);
|
||||
test_cli_step.dependOn(&run_roc_subcommands_test.step);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -827,12 +827,28 @@ fn generatePlatformHostShim(allocs: *Allocators, cache_dir: []const u8, entrypoi
|
|||
};
|
||||
|
||||
// Generate paths for temporary files
|
||||
const bitcode_path = std.fs.path.join(allocs.arena, &.{ cache_dir, "platform_shim.bc" }) catch |err| {
|
||||
// Use a hash of the serialized module content to avoid race conditions when multiple
|
||||
// builds run in parallel. Each unique module content gets its own shim files.
|
||||
const content_hash = if (serialized_module) |module_bytes|
|
||||
std.hash.Crc32.hash(module_bytes)
|
||||
else
|
||||
0; // For IPC mode (roc run), use a fixed name since there's no embedded data
|
||||
|
||||
const bitcode_filename = std.fmt.allocPrint(allocs.arena, "platform_shim_{x}.bc", .{content_hash}) catch |err| {
|
||||
std.log.err("Failed to create bitcode filename: {}", .{err});
|
||||
return err;
|
||||
};
|
||||
const object_filename = std.fmt.allocPrint(allocs.arena, "platform_shim_{x}.o", .{content_hash}) catch |err| {
|
||||
std.log.err("Failed to create object filename: {}", .{err});
|
||||
return err;
|
||||
};
|
||||
|
||||
const bitcode_path = std.fs.path.join(allocs.arena, &.{ cache_dir, bitcode_filename }) catch |err| {
|
||||
std.log.err("Failed to create bitcode path: {}", .{err});
|
||||
return err;
|
||||
};
|
||||
|
||||
const object_path = std.fs.path.join(allocs.arena, &.{ cache_dir, "platform_shim.o" }) catch |err| {
|
||||
const object_path = std.fs.path.join(allocs.arena, &.{ cache_dir, object_filename }) catch |err| {
|
||||
std.log.err("Failed to create object path: {}", .{err});
|
||||
return err;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue