From 0cf79b2fbd6688f9e04da9ba2c8c0bc005a8e92b Mon Sep 17 00:00:00 2001 From: cyqsimon <28627918+cyqsimon@users.noreply.github.com> Date: Thu, 31 Aug 2023 20:07:16 +0800 Subject: Cache npcap SDK when building on Windows (#281) * Cache npcap SDK on Windows * Call build function correctly * Log when local cache of SDK is found * Fix clippy warnings * Log to STDERR --- build.rs | 78 +++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 25 deletions(-) (limited to 'build.rs') diff --git a/build.rs b/build.rs index f306021..d20e5b5 100644 --- a/build.rs +++ b/build.rs @@ -1,50 +1,78 @@ fn main() { #[cfg(target_os = "windows")] - download_windows_pcap_sdk() + download_windows_npcap_sdk().unwrap(); } #[cfg(target_os = "windows")] -fn download_windows_pcap_sdk() { +fn download_windows_npcap_sdk() -> anyhow::Result<()> { use std::{ env, fs, io::{self, Write}, + path::PathBuf, }; + use anyhow::anyhow; use http_req::request; use zip::ZipArchive; println!("cargo:rerun-if-changed=build.rs"); - let out_dir = env::var("OUT_DIR").unwrap(); + // get npcap SDK + const NPCAP_SDK: &str = "npcap-sdk-1.13.zip"; - let mut pcap_zip = Vec::new(); - let res = request::get("https://npcap.com/dist/npcap-sdk-1.13.zip", &mut pcap_zip).unwrap(); - eprintln!("{res:?}"); + let npcap_sdk_download_url = format!("https://npcap.com/dist/{NPCAP_SDK}"); + let cache_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?).join("target"); + let npcap_sdk_cache_path = cache_dir.join(NPCAP_SDK); - let lib_dir = if cfg!(target_arch = "aarch64") { - "Lib/ARM64" + let npcap_zip = match fs::read(&npcap_sdk_cache_path) { + // use cached + Ok(zip_data) => { + eprintln!("Found cached npcap SDK"); + zip_data + } + // download SDK + Err(_) => { + eprintln!("Downloading npcap SDK"); + + // download + let mut zip_data = vec![]; + let _res = request::get(npcap_sdk_download_url, &mut zip_data)?; + + // write cache + fs::create_dir_all(cache_dir)?; + let mut cache = fs::File::create(npcap_sdk_cache_path)?; + cache.write_all(&zip_data)?; + + zip_data + } + }; + + // extract DLL + let lib_path = if cfg!(target_arch = "aarch64") { + "Lib/ARM64/Packet.lib" } else if cfg!(target_arch = "x86_64") { - "Lib/x64" + "Lib/x64/Packet.lib" } else if cfg!(target_arch = "x86") { - "Lib" + "Lib/Packet.lib" } else { panic!("Unsupported target!") }; - let lib_name = "Packet.lib"; - let lib_path = format!("{lib_dir}/{lib_name}"); - - let mut archive = ZipArchive::new(io::Cursor::new(pcap_zip)).unwrap(); - let mut pcap_lib = match archive.by_name(&lib_path) { - Ok(lib) => lib, - Err(err) => { - panic!("{err}"); - } - }; + let mut archive = ZipArchive::new(io::Cursor::new(npcap_zip))?; + let mut npcap_lib = archive.by_name(lib_path)?; + + // write DLL + let lib_dir = PathBuf::from(env::var("OUT_DIR")?).join("npcap_sdk"); + let lib_path = lib_dir.join("Packet.lib"); + fs::create_dir_all(&lib_dir)?; + let mut lib_file = fs::File::create(lib_path)?; + io::copy(&mut npcap_lib, &mut lib_file)?; - fs::create_dir_all(format!("{out_dir}/{lib_dir}")).unwrap(); - let mut pcap_lib_file = fs::File::create(format!("{out_dir}/{lib_path}")).unwrap(); - io::copy(&mut pcap_lib, &mut pcap_lib_file).unwrap(); - pcap_lib_file.flush().unwrap(); + println!( + "cargo:rustc-link-search=native={}", + lib_dir + .to_str() + .ok_or(anyhow!("{lib_dir:?} is not valid UTF-8"))? + ); - println!("cargo:rustc-link-search=native={out_dir}/{lib_dir}"); + Ok(()) } -- cgit v1.2.3