From 0791785553dfc35802310d26a05be8cb19a4b9a6 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Wed, 7 Jul 2021 11:40:24 -0700 Subject: [PATCH] target_dir --- crates/bindings/src/main.rs | 2 +- crates/fmt/src/main.rs | 2 +- crates/gen/src/workspace.rs | 74 +++++++++++++++++++++---------------- crates/macros/src/lib.rs | 17 +-------- 4 files changed, 46 insertions(+), 49 deletions(-) diff --git a/crates/bindings/src/main.rs b/crates/bindings/src/main.rs index 42175e216d..21dca68216 100644 --- a/crates/bindings/src/main.rs +++ b/crates/bindings/src/main.rs @@ -25,7 +25,7 @@ fn main() -> std::io::Result<()> { }, }; - let mut path = windows_gen::workspace_dir(); + let mut path: std::path::PathBuf = windows_gen::workspace_dir().into(); path.push("src"); path.push("bindings.rs"); diff --git a/crates/fmt/src/main.rs b/crates/fmt/src/main.rs index e3078bb0af..a224b3a742 100644 --- a/crates/fmt/src/main.rs +++ b/crates/fmt/src/main.rs @@ -74,7 +74,7 @@ fn walk_path(path: &Path) -> Result<()> { } fn main() -> Result<()> { - let dir = windows_gen::workspace_dir(); + let dir: std::path::PathBuf = windows_gen::workspace_dir().into(); walk_path(&dir)?; format_file( diff --git a/crates/gen/src/workspace.rs b/crates/gen/src/workspace.rs index 77a55bd8ce..6d04fed714 100644 --- a/crates/gen/src/workspace.rs +++ b/crates/gen/src/workspace.rs @@ -14,12 +14,10 @@ pub fn crate_winmds() -> &'static [File] { unsafe { &*VALUE.as_ptr() } } -pub fn workspace_dir() -> std::path::PathBuf { +fn cargo_metadata() -> &'static str { use std::{mem::MaybeUninit, sync::Once}; static ONCE: Once = Once::new(); - static mut VALUE: MaybeUninit = MaybeUninit::uninit(); - - // TODO: calling `cargo metadata` just to get the workspace dir takes about 40ms. + static mut VALUE: MaybeUninit = MaybeUninit::uninit(); ONCE.call_once(|| { let output = std::process::Command::new(env!("CARGO")) @@ -30,27 +28,49 @@ pub fn workspace_dir() -> std::path::PathBuf { .output() .expect("Failed to run `cargo metadata`"); - const JSON_KEY: &str = r#""workspace_root":"#; - let json = String::from_utf8(output.stdout).expect("Cargo metadata is not utf-8"); - let beginning_index = json - .rfind(JSON_KEY) - .expect("Cargo metadata did not contain `workspace_root` key.") - + JSON_KEY.len() - + 1; + unsafe { + VALUE = MaybeUninit::new( + String::from_utf8(output.stdout).expect("Cargo metadata is not utf-8"), + ) + } + }); + + // This is safe because `call_once` has already been called. + unsafe { &*VALUE.as_ptr() } +} - let ending_index = json[beginning_index..] - .find('"') - .expect("Cargo metadata ended before closing '\"' in `workspace_root` value"); +pub fn workspace_dir() -> String { + const JSON_KEY: &str = r#""workspace_root":"#; + let json = cargo_metadata(); - let workspace_root = - json[beginning_index..beginning_index + ending_index].replace("\\\\", "\\"); + let beginning_index = json + .rfind(JSON_KEY) + .expect("Cargo metadata did not contain `workspace_root` key.") + + JSON_KEY.len() + + 1; - // This is safe because `Once` provides thread-safe one-time initialization - unsafe { VALUE = MaybeUninit::new(workspace_root.into()) } - }); + let ending_index = json[beginning_index..] + .find('"') + .expect("Cargo metadata ended before closing '\"' in `workspace_root` value"); - // This is safe because `call_once` has already been called. - unsafe { (*VALUE.as_ptr()).clone() } + json[beginning_index..beginning_index + ending_index].replace("\\\\", "\\") +} + +pub fn target_dir() -> String { + const JSON_KEY: &str = r#""target_directory":"#; + let json = cargo_metadata(); + + let beginning_index = json + .rfind(JSON_KEY) + .expect("Cargo metadata did not contain `target_directory` key.") + + JSON_KEY.len() + + 1; + + let ending_index = json[beginning_index..] + .find('"') + .expect("Cargo metadata ended before closing '\"' in `target_directory` value"); + + json[beginning_index..beginning_index + ending_index].replace("\\\\", "\\") } fn get_crate_winmds() -> Vec { @@ -81,17 +101,7 @@ fn get_crate_winmds() -> Vec { dir.push("winmd"); push_dir(&mut result, &dir); - 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 = workspace_dir(); - dir.push("target"); + let mut dir: std::path::PathBuf = target_dir().into(); dir.push(".windows"); dir.push("winmd"); push_dir(&mut result, &dir); diff --git a/crates/macros/src/lib.rs b/crates/macros/src/lib.rs index af876f5aeb..70d072d72e 100644 --- a/crates/macros/src/lib.rs +++ b/crates/macros/src/lib.rs @@ -44,6 +44,7 @@ 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.into_tokens_string()); + let target_dir = RawString(gen::target_dir()); let tokens = quote! { { @@ -118,22 +119,8 @@ 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 = ::std::env::var("OUT_DIR").expect("No `OUT_DIR` env variable set").into(); - - loop { - destination.pop(); - destination.push("Cargo.toml"); - - if destination.exists() { - break; - } - - destination.pop(); - } - - destination.pop(); - destination.push("target"); + let mut destination : ::std::path::PathBuf = #target_dir.into(); let profile = ::std::env::var("PROFILE").expect("No `PROFILE` env variable set"); copy_to_profile(&source, &destination, &profile);