Skip to content

Commit 03d2d01

Browse files
committed
bazel/cranelift: make build scripts produce deterministic output
Patch cranelift-codegen and cranelift-assembler-x64 build scripts to emit relative paths in generated source files instead of absolute OUT_DIR paths. Without this, sandbox-specific absolute paths leak into compiled string literals, breaking byte-for-byte reproducibility. The cranelift-codegen issue is fixed upstream on main by 0694bba38 ("Strip prefixes in file names") but not in any released version yet.
1 parent cd4df2a commit 03d2d01

4 files changed

Lines changed: 104 additions & 6 deletions

File tree

MODULE.bazel

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,20 @@ crate.annotation(
380380
extra_aliased_targets = {"wasmtime_c": "wasmtime_c"},
381381
gen_build_script = "off",
382382
)
383+
384+
# CORE-16110: make cranelift build scripts produce deterministic output.
385+
# The cranelift-codegen patch can be removed after upgrading to a wasmtime
386+
# version that includes 0694bba38 ("Strip prefixes in file names").
387+
crate.annotation(
388+
crate = "cranelift-codegen",
389+
patch_args = ["-p1"],
390+
patches = ["//bazel/thirdparty:cranelift-codegen-reproducible.patch"],
391+
)
392+
crate.annotation(
393+
crate = "cranelift-assembler-x64",
394+
patch_args = ["-p1"],
395+
patches = ["//bazel/thirdparty:cranelift-assembler-x64-reproducible.patch"],
396+
)
383397
use_repo(crate, "crates")
384398

385399
# ====================================

MODULE.bazel.lock

Lines changed: 14 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--- a/build.rs 2026-04-15 18:44:30.930898497 -0400
2+
+++ b/build.rs 2026-04-15 18:44:46.447314373 -0400
3+
@@ -2,7 +2,33 @@
4+
use std::env;
5+
use std::fs::File;
6+
use std::io::Write;
7+
-use std::path::Path;
8+
+use std::path::{Path, PathBuf};
9+
+
10+
+/// Compute a relative path from the current directory to `p` so that
11+
+/// paths embedded in generated code are deterministic across sandbox
12+
+/// instances (e.g. in Bazel builds).
13+
+fn relative_from_cwd(p: &Path) -> PathBuf {
14+
+ let cwd = match std::env::current_dir().and_then(|d| d.canonicalize()) {
15+
+ Ok(d) => d,
16+
+ Err(_) => return p.to_path_buf(),
17+
+ };
18+
+ let abs_p = match p.canonicalize() {
19+
+ Ok(a) => a,
20+
+ Err(_) => return p.to_path_buf(),
21+
+ };
22+
+ let common = cwd.components()
23+
+ .zip(abs_p.components())
24+
+ .take_while(|(a, b)| a == b)
25+
+ .count();
26+
+ let mut rel = PathBuf::new();
27+
+ for _ in 0..(cwd.components().count() - common) {
28+
+ rel.push("..");
29+
+ }
30+
+ for comp in abs_p.components().skip(common) {
31+
+ rel.push(comp);
32+
+ }
33+
+ rel
34+
+}
35+
36+
fn main() {
37+
println!("cargo:rerun-if-changed=build.rs");
38+
@@ -16,7 +42,7 @@
39+
let mut vec_of_built_files = File::create(out_dir.join("generated-files.rs")).unwrap();
40+
writeln!(vec_of_built_files, "vec![").unwrap();
41+
for file in &built_files {
42+
- writeln!(vec_of_built_files, " {:?}.into(),", file.display()).unwrap();
43+
+ writeln!(vec_of_built_files, " {:?}.into(),", relative_from_cwd(file).display()).unwrap();
44+
}
45+
writeln!(vec_of_built_files, "]").unwrap();
46+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--- a/build.rs
2+
+++ b/build.rs
3+
@@ -144,6 +144,27 @@
4+
) -> std::path::PathBuf {
5+
if let Ok(suffix) = filename.strip_prefix(&cur_dir) {
6+
suffix.to_path_buf()
7+
+ } else if let (Ok(abs_cur), Ok(abs_file)) =
8+
+ (cur_dir.canonicalize(), filename.canonicalize())
9+
+ {
10+
+ // In sandboxed builds (e.g. Bazel), cur_dir and filename may not
11+
+ // share a direct prefix even though they share a common ancestor.
12+
+ // Compute a relative path via "../" to keep generated source
13+
+ // deterministic across different sandbox instances.
14+
+ let common = abs_cur
15+
+ .components()
16+
+ .zip(abs_file.components())
17+
+ .take_while(|(a, b)| a == b)
18+
+ .count();
19+
+ let ups = abs_cur.components().count() - common;
20+
+ let mut rel = std::path::PathBuf::new();
21+
+ for _ in 0..ups {
22+
+ rel.push("..");
23+
+ }
24+
+ for comp in abs_file.components().skip(common) {
25+
+ rel.push(comp);
26+
+ }
27+
+ rel
28+
} else {
29+
filename.to_path_buf()
30+
}

0 commit comments

Comments
 (0)