diff --git a/crates/gen/build.rs b/crates/gen/build.rs deleted file mode 100644 index 45e9c8be5a..0000000000 --- a/crates/gen/build.rs +++ /dev/null @@ -1,36 +0,0 @@ -#[cfg(windows)] -fn main() { - let mut source: ::std::path::PathBuf = ::std::env::var("CARGO_MANIFEST_DIR") - .expect("No `CARGO_MANIFEST_DIR` env var") - .into(); - - source.push(".windows"); - source.push("winmd"); - - let destination = std::env::var("PATH").expect("No `PATH` env variable set"); - let end = destination.find(';').expect("Path not ending in `;`"); - let mut destination: std::path::PathBuf = destination[..end].into(); - destination.pop(); - destination.pop(); - destination.push(".windows"); - destination.push("winmd"); - - if let ::std::result::Result::Ok(files) = ::std::fs::read_dir(source) { - for file in files.filter_map(|file| file.ok()) { - if let ::std::result::Result::Ok(file_type) = file.file_type() { - if file_type.is_file() { - let path = file.path(); - if let ::std::option::Option::Some(filename) = path.file_name() { - let _ = std::fs::create_dir_all(&destination); - destination.push(filename); - let _ = ::std::fs::copy(path, &destination); - destination.pop(); - } - } - } - } - } -} - -#[cfg(not(windows))] -fn main() {} diff --git a/crates/gen/src/workspace.rs b/crates/gen/src/workspace.rs index ca1f36fc2a..d94e7b256e 100644 --- a/crates/gen/src/workspace.rs +++ b/crates/gen/src/workspace.rs @@ -80,8 +80,8 @@ fn get_crate_winmds() -> Vec { if let Ok(file_type) = file.file_type() { if file_type.is_file() { let path = file.path(); - if let Some("winmd") = - path.extension().and_then(|extension| extension.to_str()) + if path.extension().and_then(|extension| extension.to_str()) + == Some("winmd") { result.push(File::new(path)); } @@ -93,26 +93,27 @@ fn get_crate_winmds() -> Vec { let mut result = vec![]; + // Manifest directory of the crate calling `build!` if let Ok(dir) = std::env::var("CARGO_MANIFEST_DIR") { - let mut dir: std::path::PathBuf = dir.into(); - dir.push(".windows"); - dir.push("winmd"); - push_dir(&mut result, &dir); + push_dir( + &mut result, + &std::path::Path::new(&dir).join(".windows/winmd"), + ); } - let dir = std::env::var("PATH").expect("No `PATH` env variable set"); - let end = dir.find(';').expect("Path not ending in `;`"); - let mut dir: std::path::PathBuf = dir[..end].into(); - dir.pop(); - dir.pop(); - dir.push(".windows"); - dir.push("winmd"); - push_dir(&mut result, &dir); - - let mut dir: std::path::PathBuf = target_dir().into(); - dir.push(".windows"); - dir.push("winmd"); - push_dir(&mut result, &dir); + // Default manifests provided by windows_gen + // TODO: include_bytes is very slow - it takes an extra 60ms compared with memory mapped files. + // https://github.com/rust-lang/rust/issues/65818 + if !result.iter().any(|file| file.name.starts_with("Windows.")) { + result.push(File::from_bytes( + "Windows.Win32.winmd".to_string(), + include_bytes!("../.windows/winmd/Windows.Win32.winmd").to_vec(), + )); + result.push(File::from_bytes( + "Windows.WinRT.winmd".to_string(), + include_bytes!("../.windows/winmd/Windows.WinRT.winmd").to_vec(), + )); + } result } diff --git a/crates/macros/src/lib.rs b/crates/macros/src/lib.rs index f0ef699829..bf77d0eeb1 100644 --- a/crates/macros/src/lib.rs +++ b/crates/macros/src/lib.rs @@ -44,9 +44,6 @@ impl ToTokens for RawString { pub fn build(stream: proc_macro::TokenStream) -> proc_macro::TokenStream { let build = parse_macro_input!(stream as BuildMacro); let tokens = RawString(build.to_tokens_string()); - let target_dir = std::env::var("PATH").expect("No `PATH` env variable set"); - let end = target_dir.find(';').expect("Path not ending in `;`"); - let target_dir = RawString(target_dir[..end].to_string()); let tokens = quote! { { @@ -59,6 +56,8 @@ pub fn build(stream: proc_macro::TokenStream) -> proc_macro::TokenStream { ); path.push("windows.rs"); + println!("cargo:rerun-if-changed={}", path.to_str().expect("`OUT_DIR` not a UTF-8 string")); + ::std::fs::write(&path, #tokens).expect("Could not write generated code to windows.rs"); let mut cmd = ::std::process::Command::new("rustfmt"); @@ -68,38 +67,17 @@ pub fn build(stream: proc_macro::TokenStream) -> proc_macro::TokenStream { fn copy(source: &::std::path::Path, destination: &mut ::std::path::PathBuf) { if let ::std::result::Result::Ok(entries) = ::std::fs::read_dir(source) { for entry in entries.filter_map(|entry| entry.ok()) { - if let ::std::result::Result::Ok(entry_type) = entry.file_type() { - let path = entry.path(); - if let ::std::option::Option::Some(last_path_component) = path.file_name() { - let _ = ::std::fs::create_dir_all(&destination); - destination.push(last_path_component); - if entry_type.is_file() { - let _ = ::std::fs::copy(path, &destination); - } else if entry_type.is_dir() { - let _ = ::std::fs::create_dir(&destination); - copy(&path, destination); - } - destination.pop(); - } - } - } - } - } - - fn copy_to_profile(source: &::std::path::Path, destination: &::std::path::Path, profile: &str) { - if let ::std::result::Result::Ok(files) = ::std::fs::read_dir(destination) { - for file in files.filter_map(|file| file.ok()) { - if let ::std::result::Result::Ok(file_type) = file.file_type() { - if file_type.is_dir() { - let mut path = file.path(); - if let ::std::option::Option::Some(filename) = path.file_name() { - if filename == profile { - copy(source, &mut path); - } else { - copy_to_profile(source, &path, profile); - } - } + let path = entry.path(); + if let ::std::option::Option::Some(last_path_component) = path.file_name() { + let _ = ::std::fs::create_dir_all(&destination); + destination.push(last_path_component); + if path.is_file() { + let _ = ::std::fs::copy(path, &destination); + } else if path.is_dir() { + let _ = ::std::fs::create_dir(&destination); + copy(&path, destination); } + destination.pop(); } } } @@ -107,10 +85,9 @@ pub fn build(stream: proc_macro::TokenStream) -> proc_macro::TokenStream { let mut source : ::std::path::PathBuf = ::std::env::var("CARGO_MANIFEST_DIR").expect("No `CARGO_MANIFEST_DIR` env variable set").into(); source.push(".windows"); + println!("cargo:rerun-if-changed={}", source.to_str().expect("`CARGO_MANIFEST_DIR` not a UTF-8 string")); if source.exists() { - println!("cargo:rerun-if-changed={}", source.to_str().expect("`CARGO_MANIFEST_DIR` not a valid path")); - // The `target_arch` cfg is not set for build scripts so we need to sniff it out from the environment variable. source.push(match ::std::env::var("CARGO_CFG_TARGET_ARCH").expect("No `CARGO_CFG_TARGET_ARCH` env variable set").as_str() { "x86_64" => "x64", @@ -124,17 +101,12 @@ pub fn build(stream: proc_macro::TokenStream) -> proc_macro::TokenStream { println!("cargo:rustc-link-search=native={}", source.to_str().expect("`CARGO_MANIFEST_DIR` not a valid path")); } - let mut destination : ::std::path::PathBuf = #target_dir.into(); + let mut destination: ::std::path::PathBuf = ::std::env::var("OUT_DIR").expect("No `OUT_DIR` env variable set").into(); + // Of `target//build//out`, pop the last 3 folders + destination.pop(); destination.pop(); destination.pop(); - let profile = ::std::env::var("PROFILE").expect("No `PROFILE` env variable set"); - copy_to_profile(&source, &destination, &profile); - - destination.push(".windows"); - destination.push("winmd"); - source.pop(); - source.push("winmd"); copy(&source, &mut destination); } }