Remove use of global node.lib cache

This commit is contained in:
adumbidiot 2020-10-30 20:58:28 -07:00
parent e25ef3a3d8
commit cab8fcc3a6

View file

@ -1,5 +1,7 @@
use crate::*; use crate::*;
use std::fs::{create_dir, metadata, write}; use std::collections::hash_map::DefaultHasher;
use std::fs::{metadata, write};
use std::hash::{Hash, Hasher};
use std::io::Read; use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
@ -33,8 +35,11 @@ fn download_node_lib(dist_url: &str, version: &str, arch: &str) -> Vec<u8> {
} }
pub fn setup() { pub fn setup() {
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR is not set");
// Assume nodejs if not specified. // Assume nodejs if not specified.
let dist_url = std::env::var("NPM_CONFIG_DISTURL").unwrap_or("https://nodejs.org/dist".into()); let dist_url =
std::env::var("NPM_CONFIG_DISTURL").unwrap_or_else(|_| "https://nodejs.org/dist".to_string());
// Try to get local nodejs version if not specified. // Try to get local nodejs version if not specified.
let node_version = std::env::var("NPM_CONFIG_TARGET") let node_version = std::env::var("NPM_CONFIG_TARGET")
@ -62,55 +67,45 @@ pub fn setup() {
println!("cargo:rerun-if-env-changed=NPM_CONFIG_DISTURL"); println!("cargo:rerun-if-env-changed=NPM_CONFIG_DISTURL");
println!("cargo:rerun-if-env-changed=NPM_CONFIG_TARGET"); println!("cargo:rerun-if-env-changed=NPM_CONFIG_TARGET");
let mut node_lib_file_dir = PathBuf::from( let mut node_lib_file_path = PathBuf::from(out_dir);
String::from_utf8( let link_search_dir = node_lib_file_path.clone();
Command::new("node")
.arg("-e") // Hash the dist_url and store it in the node lib file name.
.arg("console.log(require('os').homedir())") let dist_url_hash = {
.output() let mut hasher = DefaultHasher::new();
.unwrap() dist_url.hash(&mut hasher);
.stdout, hasher.finish()
) };
.unwrap()
.trim_end() // Encode version, arch, and dist_url to detect and reaquire node.lib when these 3 change.
.to_owned(), let node_lib_file_name = format!(
"node-{version}-{arch}-{dist_url_hash}.lib",
version = node_version,
arch = arch,
dist_url_hash = dist_url_hash
); );
node_lib_file_path.push(&node_lib_file_name);
node_lib_file_dir.push(".napi-rs"); // If file does not exist, download it.
if metadata(&node_lib_file_path).is_err() {
match create_dir(&node_lib_file_dir) {
Ok(_) => {}
Err(err) => {
if err.kind() != std::io::ErrorKind::AlreadyExists {
panic!(
"create {} folder failed: {}",
node_lib_file_dir.to_str().unwrap(),
err
)
}
}
}
let link_search_dir = node_lib_file_dir.clone();
node_lib_file_dir.push(format!("node-{}.lib", node_version));
if let Err(_) = metadata(&node_lib_file_dir) {
let node_lib = download_node_lib(&dist_url, &node_version, &arch); let node_lib = download_node_lib(&dist_url, &node_version, &arch);
write(&node_lib_file_dir, &node_lib).expect(&format!(
write(&node_lib_file_path, &node_lib).expect(&format!(
"Could not save file to {}", "Could not save file to {}",
node_lib_file_dir.to_str().unwrap() node_lib_file_path.to_str().unwrap()
)); ));
} }
println!( println!(
"cargo:rustc-link-lib={}", "cargo:rustc-link-lib={}",
&node_lib_file_dir.file_stem().unwrap().to_str().unwrap() node_lib_file_path.file_stem().unwrap().to_str().unwrap()
); );
println!( println!(
"cargo:rustc-link-search=native={}", "cargo:rustc-link-search=native={}",
link_search_dir.to_str().unwrap() link_search_dir.display()
); );
println!("cargo:rustc-cdylib-link-arg=delayimp.lib"); println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe"); println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
setup_napi_feature(); setup_napi_feature();
} }