use std::env; use std::path::PathBuf; const PDFIUM_VERSION: &str = "chromium%2F7725"; fn pdfium_url(os: &str, arch: &str) -> String { let platform = match (os, arch) { ("linux", "x86_64") => "linux-x64", ("linux", "aarch64") => "linux-arm64", ("macos", "x86_64") => "mac-x64", ("macos", "aarch64") => "mac-arm64", _ => panic!("unsupported platform: {os}-{arch}"), }; format!( "https://github.com/bblanchon/pdfium-binaries/releases/download/{PDFIUM_VERSION}/pdfium-{platform}.tgz" ) } fn lib_name(os: &str) -> &'static str { match os { "macos" => "libpdfium.dylib", _ => "libpdfium.so", } } fn rpath_flag(os: &str) -> &'static str { match os { "macos" => "-Wl,-rpath,@loader_path", _ => "-Wl,-rpath,$ORIGIN", } } #[expect(clippy::expect_used)] #[expect(clippy::unwrap_used)] #[expect(clippy::print_stderr)] fn main() { println!("cargo:rerun-if-changed=build.rs"); if env::var("CARGO_FEATURE_PDFIUM").is_err() { return; } let os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); // OUT_DIR is target//build/-/out // Go up 3 levels to reach target// let profile_dir = out_dir .ancestors() .nth(3) .expect("unexpected OUT_DIR structure") .to_path_buf(); // If PDFIUM_LIB_DIR is set (e.g. by Nix), use the pre-installed library directly. if let Ok(lib_dir) = env::var("PDFIUM_LIB_DIR") { println!("cargo:rustc-link-search=native={lib_dir}"); println!("cargo:rustc-link-lib=dylib=pdfium"); return; } let lib_file = lib_name(&os); let lib_path = profile_dir.join(lib_file); if !lib_path.exists() { let url = pdfium_url(&os, &arch); let tgz_path = out_dir.join("pdfium.tgz"); eprintln!("cargo:warning=Downloading PDFium from {url}"); let status = std::process::Command::new("curl") .args(["-L", "--fail", "-o", tgz_path.to_str().unwrap(), &url]) .status() .expect("failed to run curl"); assert!(status.success(), "curl failed to download PDFium"); let status = std::process::Command::new("tar") .args([ "-xzf", tgz_path.to_str().unwrap(), "-C", out_dir.to_str().unwrap(), ]) .status() .expect("failed to run tar"); assert!(status.success(), "tar failed to extract PDFium"); std::fs::copy(out_dir.join("lib").join(lib_file), &lib_path) .expect("failed to copy pdfium library"); } println!("cargo:rustc-link-search=native={}", profile_dir.display()); println!("cargo:rustc-link-lib=dylib=pdfium"); println!("cargo:rustc-link-arg={}", rpath_flag(&os)); }