diff --git a/build.rs b/build.rs index da1f778..e06e459 100644 --- a/build.rs +++ b/build.rs @@ -3,9 +3,7 @@ use std::{ path::{Path, PathBuf}, }; -fn find_package(name: &str) -> Vec { - let vcpkg_root = std::env::var("VCPKG_ROOT").unwrap(); - let mut path: PathBuf = vcpkg_root.into(); +fn link_vcpkg(mut path: PathBuf, name: &str) -> PathBuf { let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); let mut target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); if target_arch == "x86_64" { @@ -28,7 +26,10 @@ fn find_package(name: &str) -> Vec { path.push(target); println!( "{}", - format!("cargo:rustc-link-lib=static={}", name.trim_start_matches("lib")) + format!( + "cargo:rustc-link-lib=static={}", + name.trim_start_matches("lib") + ) ); println!( "{}", @@ -39,7 +40,66 @@ fn find_package(name: &str) -> Vec { ); let include = path.join("include"); println!("{}", format!("cargo:include={}", include.to_str().unwrap())); - vec![include] + include +} + +fn link_homebrew_m1(name: &str) -> PathBuf { + let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + if target_os != "macos" || target_arch != "aarch64" { + panic!("Couldn't find VCPKG_ROOT, also can't fallback to homebrew because it's only for macos aarch64."); + } + let mut path = PathBuf::from("/opt/homebrew/Cellar"); + path.push(name); + let entries = if let Ok(dir) = std::fs::read_dir(&path) { + dir + } else { + panic!("Could not find package in {}. Make sure your homebrew and package {} are all installed.", path.to_str().unwrap(),&name); + }; + let mut directories = entries + .into_iter() + .filter(|x| x.is_ok()) + .map(|x| x.unwrap().path()) + .filter(|x| x.is_dir()) + .collect::>(); + // Find the newest version. + directories.sort_unstable(); + if directories.is_empty() { + panic!( + "There's no installed version of {} in /opt/homebrew/Cellar", + name + ); + } + path.push(directories.pop().unwrap()); + // Link the library. + println!( + "{}", + format!( + "cargo:rustc-link-lib=static={}", + name.trim_start_matches("lib") + ) + ); + // Add the library path. + println!( + "{}", + format!( + "cargo:rustc-link-search={}", + path.join("lib").to_str().unwrap() + ) + ); + // Add the include path. + let include = path.join("include"); + println!("{}", format!("cargo:include={}", include.to_str().unwrap())); + include +} + +fn find_package(name: &str) -> Vec { + if let Ok(vcpkg_root) = std::env::var("VCPKG_ROOT") { + vec![link_vcpkg(vcpkg_root.into(), name)] + } else { + // Try using homebrew + vec![link_homebrew_m1(name)] + } } fn generate_bindings(ffi_header: &Path, include_paths: &[PathBuf], ffi_rs: &Path) {