From 60c0953da85066d41735023175552f52b3e846c2 Mon Sep 17 00:00:00 2001 From: Arlie Davis Date: Wed, 5 Jun 2024 16:26:41 -0700 Subject: [PATCH] Directly run bindgen instead of recursively running Cargo --- crates/libs/bindgen/Cargo.toml | 3 + crates/tests/standalone/Cargo.toml | 8 +++ crates/tests/standalone/build.rs | 98 +++++++++++++++++++++--------- 3 files changed, 79 insertions(+), 30 deletions(-) diff --git a/crates/libs/bindgen/Cargo.toml b/crates/libs/bindgen/Cargo.toml index fd890cde975..5766c2e4b5d 100644 --- a/crates/libs/bindgen/Cargo.toml +++ b/crates/libs/bindgen/Cargo.toml @@ -9,6 +9,9 @@ description = "Windows metadata compiler" repository = "https://github.com/microsoft/windows-rs" readme = "readme.md" +[lib] +crate-type = ["dylib"] + [lints] workspace = true diff --git a/crates/tests/standalone/Cargo.toml b/crates/tests/standalone/Cargo.toml index cd634055499..8d21fccc7e1 100644 --- a/crates/tests/standalone/Cargo.toml +++ b/crates/tests/standalone/Cargo.toml @@ -4,8 +4,16 @@ version = "0.0.0" edition = "2021" publish = false +[lib] +doc = false +doctest = false + [dependencies.windows-core] path = "../../libs/core" [dependencies.windows-targets] path = "../../libs/targets" + +[build-dependencies.windows-bindgen] +path = "../../libs/bindgen" +default-features = false diff --git a/crates/tests/standalone/build.rs b/crates/tests/standalone/build.rs index bdc1ed0a3bf..bf30b180145 100644 --- a/crates/tests/standalone/build.rs +++ b/crates/tests/standalone/build.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + fn main() { write_sys( "src/b_none.rs", @@ -202,36 +204,72 @@ fn write_vtbl(output: &str, filter: &[&str]) { } fn riddle(output: &str, filter: &[&str], config: &[&str]) { - // Rust-analyzer may re-run build scripts whenever a source file is deleted - // which causes an endless loop if the file is deleted from a build script. - // To workaround this, we truncate the file instead of deleting it. - // See https://github.com/microsoft/windows-rs/issues/2777 - _ = std::fs::File::options() - .truncate(true) - .write(true) - .open(output); - - let mut command = std::process::Command::new("cargo"); - - command.args([ - "run", - "-p", - "riddle", - "--target-dir", - "../../../target/test_standalone", // TODO: workaround for https://github.com/rust-lang/cargo/issues/6412 - "--", - "--in", - "../../libs/bindgen/default", - "--out", - output, - "--filter", - ]); - - command.args(filter); - command.args(["--config", "no-bindgen-comment"]); - command.args(config); + println!("----- {output:?} -----"); - if !command.status().unwrap().success() { - panic!("Failed to run riddle"); + let out_dir = PathBuf::from( + std::env::var("OUT_DIR") + .unwrap_or_else(|_| panic!("Expected OUT_DIR environment variable to be set.")), + ); + let temp_filename = output.replace('/', "_"); + let temp_output = out_dir.join(&temp_filename); + + let mut args: Vec = vec![ + "--in".to_owned(), + "../../libs/bindgen/default".to_owned(), + "--out".to_owned(), + temp_output.as_os_str().to_string_lossy().into_owned(), + ]; + + args.push("--filter".to_owned()); + args.extend(filter.iter().map(|&s| s.to_owned())); + + args.push("--config".to_owned()); + args.push("no-bindgen-comment".to_owned()); + + args.extend(config.iter().map(|&s| s.to_owned())); + + // Show args for debugging. You can see output with "cargo build -vv". + let args_flat = args.join(" "); + println!("riddle.exe {args_flat}"); + + windows_bindgen::bindgen(&args).unwrap_or_else(|e| { + panic!( + "Failed to run riddle.\n\ + File: {output}\n\ + Args: {args_flat}\n\ + Error: {e:?}" + ); + }); + + // Read the file that was just generated. + let new_contents = std::fs::read_to_string(&temp_output).unwrap_or_else(|e| { + panic!("Failed to read file: {}: {e:?}", temp_output.display()); + }); + + let needs_update = match std::fs::read_to_string(&output) { + Ok(old_contents) => { + if old_contents == new_contents { + println!("contents are same"); + } else { + println!( + "contents are different. old len = {}, new len = {}", + old_contents.len(), + new_contents.len() + ); + } + old_contents != new_contents + } + Err(e) => { + println!("failed to open old file: {e:?}"); + true + } + }; + + if needs_update { + println!("updating: {}", output); + std::fs::write(output, new_contents) + .unwrap_or_else(|e| panic!("Failed to update file {output:?} : {e:?}")); } + + println!(); }