fn main() -> Result<()> { webview2_link::update_rustc_flags(webview2_link::output_libs( webview2_path::get_manifest_dir()?, webview2_path::get_out_dir()?, )?) } #[derive(Debug, Error)] pub enum Error { #[error(transparent)] Io(#[from] std::io::Error), #[error(transparent)] Var(#[from] std::env::VarError), } pub type Result = std::result::Result; #[macro_use] extern crate thiserror; mod webview2_path { use std::{convert::From, env, path::PathBuf}; pub fn get_out_dir() -> super::Result { Ok(PathBuf::from(env::var("OUT_DIR")?)) } pub fn get_manifest_dir() -> super::Result { Ok(PathBuf::from(env::var("CARGO_MANIFEST_DIR")?)) } } mod webview2_link { use std::{env, path::PathBuf}; pub fn output_libs(manifest_dir: PathBuf, out_dir: PathBuf) -> super::Result { const WEBVIEW2_LIBS: &[&str] = &[ "WebView2Loader.dll", "WebView2Loader.dll.lib", "WebView2LoaderStatic.lib", ]; const WEBVIEW2_TARGETS: &[&str] = &["arm64", "x64", "x86"]; for target in WEBVIEW2_TARGETS { for lib in WEBVIEW2_LIBS { use std::fs; let mut lib_src = manifest_dir.clone(); lib_src.push(target); lib_src.push(lib); let mut lib_dest = out_dir.clone(); lib_dest.push(target); if !lib_dest.is_dir() { fs::create_dir(lib_dest.as_path())?; } lib_dest.push(lib); eprintln!("Copy from {:?} -> {:?}", lib_src, lib_dest); fs::copy(lib_src.as_path(), lib_dest.as_path())?; } } Ok(out_dir) } pub fn update_rustc_flags(lib_path: PathBuf) -> super::Result<()> { let target_arch = match env::var("CARGO_CFG_TARGET_ARCH")?.as_str() { "x86_64" => "x64", "x86" => "x86", "arm" => "arm", "aarch64" => "arm64", unimplemented => unimplemented!( "`{}` architecture set by `CARGO_CFG_TARGET_ARCH`", unimplemented ), }; let mut lib_path = lib_path; lib_path.push(target_arch); match lib_path.to_str() { Some(path) if lib_path.exists() => println!("cargo:rustc-link-search=native={path}"), _ => unimplemented!("`{}` is not supported by WebView2", target_arch), }; Ok(()) } }