Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid modifying source files in tests/standalone if they have not changed #3072

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/libs/bindgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ description = "Windows metadata compiler"
repository = "https://github.com/microsoft/windows-rs"
readme = "readme.md"

[lib]
crate-type = ["rlib", "dylib"]
sivadeilra marked this conversation as resolved.
Show resolved Hide resolved

[lints]
workspace = true

Expand Down
8 changes: 8 additions & 0 deletions crates/tests/standalone/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ version = "0.0.0"
edition = "2021"
publish = false

[lib]
doc = false
doctest = false
kennykerr marked this conversation as resolved.
Show resolved Hide resolved

[dependencies.windows-core]
path = "../../libs/core"

[dependencies.windows-targets]
path = "../../libs/targets"

[build-dependencies.windows-bindgen]
path = "../../libs/bindgen"
default-features = false
98 changes: 68 additions & 30 deletions crates/tests/standalone/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::PathBuf;

fn main() {
write_sys(
"src/b_none.rs",
Expand Down Expand Up @@ -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<String> = 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!();
}