use std::env::var; use std::process::Command; use std::path::PathBuf; use std::fs::{ read_dir, copy }; fn get_build_dir () -> Option { let out_dir = PathBuf::from(var("OUT_DIR").ok()?); Some(out_dir.parent()?.parent()?.parent()?.to_owned()) } fn main () { let tgt = var("TARGET").unwrap(); if tgt.contains("windows") { assert!(tgt.contains("msvc"), "Only msvc target is supported on windows"); let vcpkg = Command::new("where").arg("vcpkg").output().expect("Failed to execute where.exe"); assert!(vcpkg.status.code().expect("Did not receive an exit code from where.exe") == 0, "Where.exe failed to find vcpkg"); let vcpkg_dir = [ PathBuf::from(String::from_utf8_lossy(&vcpkg.stdout).into_owned()).parent().expect("Failed to get directory for vcpkg").to_str().unwrap(), "installed", "x64-windows", ].iter().collect::(); let bin = [ vcpkg_dir.to_str().unwrap(), "bin" ].iter().collect::(); let lib = [ vcpkg_dir.to_str().unwrap(), "lib" ].iter().collect::(); assert!(lib.exists(), "Expected lib directory [{}] does not exist", lib.display()); println!("cargo:rustc-link-search=all={}", lib.display()); let build_dir = get_build_dir().expect("Failed to get build directory").to_str().unwrap().to_owned(); // TODO: Don't copy all dll's indescriminately // If the user has other libs through vcpkg this would suck for entry in read_dir(bin).expect("Can't read bin dir") { let entry_path = entry.unwrap().path(); if let Some(entry_name) = entry_path.file_name() { let entry_name = entry_name.to_str().unwrap(); if entry_name.ends_with(".dll") { let new_path = [ &build_dir, entry_name ].iter().collect::(); copy(&entry_path, new_path.as_path()).expect("Can't copy DLL to build directory"); } } } } else { panic!("Build script is not implemented for this OS"); } }