build(xbuild): output Rust binding file even if no bindings were specified
What changed, and why it matters
This is a build-system maintenance change. It ensures an empty Rust bindings file is created even when no bindings are requested, and refactors how generated files are compared and written. There is no user-facing or security-relevant behavior change.
No security action needed. Treat as routine build tooling refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit modifies core/embed/xbuild/src/clibrary/rust_bindings.rs. Previously, if self.builder was None, no output file was produced. Now an empty Vec is written to OUT_DIR/
Changed components
core/embed/xbuild/src/clibrary/rust_bindings.rsInspect captured patch +24 / −26
diff --git a/core/embed/xbuild/src/clibrary/rust_bindings.rs b/core/embed/xbuild/src/clibrary/rust_bindings.rs
index ed992bd0..288d1b0c 100644
--- a/core/embed/xbuild/src/clibrary/rust_bindings.rs
+++ b/core/embed/xbuild/src/clibrary/rust_bindings.rs
@@ -21,7 +21,8 @@ impl CLibrary {
/// Generates rust bininding (a .rs file) from the configured builder and
/// writes it to the OUT_DIR.
pub(crate) fn generate_rust_bindings(&mut self, use_cc_includes: bool) -> Result<()> {
- if let Some(builder) = self.builder.take() {
+ let out_file = path_from_env("OUT_DIR")?.join(links_name()? + ".rs");
+ let content = if let Some(builder) = self.builder.take() {
let mut attrs = self.get_merged_attrs();
if use_cc_includes {
@@ -35,9 +36,7 @@ impl CLibrary {
attrs.remove_flag("-mcmse");
attrs.remove_flag("-fsingle-precision-constant");
- let out_file = path_from_env("OUT_DIR")?.join(links_name()? + ".rs");
- let tmp_out_file = out_file.with_extension("rs.tmp");
-
+ let mut content = Vec::<u8>::new();
builder
.clang_args(attrs.to_compiler_args())
// Customize the standard types.
@@ -52,35 +51,34 @@ impl CLibrary {
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.context("Unable to generate bindings")?
- .write_to_file(&tmp_out_file)
- .context(format!(
- "Unable to write bindings to {}",
- tmp_out_file.display()
- ))?;
+ .write(Box::new(&mut content))
+ .context("Unable to write bindings to a buffer")?;
+
+ content
+ } else {
+ // just empty file
+ Vec::<u8>::new()
+ };
- // Bindgen writes the output file even if the content is unchanged,
- // which causes unnecessary recompilations. To avoid this, we
- // compare the generated file with the existing one and only replace
- // it if there are changes.
- replace_if_different(&tmp_out_file, &out_file)?;
- }
+ // Bindgen writes the output file even if the content is unchanged,
+ // which causes unnecessary recompilations. To avoid this, we
+ // compare the generated file with the existing one and only replace
+ // it if there are changes.
+ maybe_replace(content, &out_file)?;
Ok(())
}
}
-fn replace_if_different(src: &std::path::Path, dst: &std::path::Path) -> Result<()> {
- if dst.exists() {
- let src_content = std::fs::read(src).context("Failed to read temporary bindings file")?;
+fn maybe_replace(src_content: Vec<u8>, dst: &std::path::Path) -> Result<()> {
+ let should_write = if !dst.exists() {
+ true
+ } else {
let dst_content = std::fs::read(dst).context("Failed to read existing bindings file")?;
+ src_content != dst_content
+ };
- if src_content == dst_content {
- // Files are identical, no need to replace
- // Clean up the temporary file
- std::fs::remove_file(src).context("Failed to remove temporary bindings file")?;
- return Ok(());
- }
+ if should_write {
+ std::fs::write(dst, src_content).context("Failed to write empty bindings file")?;
}
-
- std::fs::rename(src, dst).context("Failed to replace bindings file")?;
Ok(())
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.