//! Build script for coolprop-sys. //! //! Links the CoolProp C++ static library. Order of preference (prudent): //! 1. Prebuilt static library under `vendor/coolprop/install_root/` (Windows MSVC). //! 2. Compile from `vendor/coolprop` sources via CMake (slower; can fail on //! header generation / Python pickle issues on some corporate Windows images). //! 3. System library fallback. use std::env; use std::path::{Path, PathBuf}; fn coolprop_vendor_root() -> Option { let candidates = [ PathBuf::from("../../vendor/coolprop"), PathBuf::from("../../../vendor/coolprop"), PathBuf::from("vendor/coolprop"), ]; candidates.into_iter().find_map(|p| { p.canonicalize().ok().filter(|abs| abs.join("CMakeLists.txt").exists()) }) } /// Prefer a prebuilt CoolProp.lib so we do not re-run the fragile /// `generate_headers` CMake custom step on every clean build. fn find_prebuilt_static_lib(vendor: &Path) -> Option { let root = vendor.join("install_root").join("static_library"); if !root.is_dir() { return None; } // Walk shallow: Windows/64bit_MSVC_*/CoolProp.lib let mut matches = Vec::new(); if let Ok(os_dirs) = std::fs::read_dir(&root) { for os_entry in os_dirs.flatten() { let os_path = os_entry.path(); if !os_path.is_dir() { continue; } if let Ok(toolchain_dirs) = std::fs::read_dir(&os_path) { for tc in toolchain_dirs.flatten() { let lib = tc.path().join("CoolProp.lib"); if lib.is_file() { matches.push(lib); } // Also accept libCoolProp.a naming on non-MSVC trees let lib_a = tc.path().join("libCoolProp.a"); if lib_a.is_file() { matches.push(lib_a); } } } // Direct CoolProp.lib under OS folder let direct = os_path.join("CoolProp.lib"); if direct.is_file() { matches.push(direct); } } } // Prefer MSVC 64-bit paths when several exist matches.sort_by_key(|p| { let s = p.to_string_lossy().to_lowercase(); let score = if s.contains("64bit") || s.contains("x64") { 0 } else { 1 }; (score, s) }); matches.into_iter().next() } fn link_system_libs(target_os: &str) { match target_os { "macos" => { println!("cargo:rustc-link-lib=dylib=c++"); } "linux" | "freebsd" | "openbsd" | "netbsd" => { println!("cargo:rustc-link-lib=dylib=stdc++"); } "windows" => { // MSVC links the C++ runtime automatically. } _ => { println!("cargo:rustc-link-lib=dylib=stdc++"); } } if target_os != "windows" { println!("cargo:rustc-link-lib=dylib=m"); } } fn main() { let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-env-changed=COOLPROP_PYTHON_EXECUTABLE"); println!("cargo:rerun-if-env-changed=ENTROPYK_FORCE_COOLPROP_SOURCE_BUILD"); let force_source = env::var("ENTROPYK_FORCE_COOLPROP_SOURCE_BUILD") .map(|v| v == "1" || v.eq_ignore_ascii_case("true")) .unwrap_or(false); if let Some(vendor) = coolprop_vendor_root() { println!("cargo:rerun-if-changed={}", vendor.display()); if !force_source { if let Some(prebuilt) = find_prebuilt_static_lib(&vendor) { let dir = prebuilt.parent().expect("CoolProp.lib has a parent dir"); println!( "cargo:warning=coolprop-sys: linking prebuilt static library at {}", prebuilt.display() ); println!("cargo:rustc-link-search=native={}", dir.display()); println!("cargo:rustc-link-lib=static=CoolProp"); link_system_libs(&target_os); if target_os == "macos" { println!( "cargo:rustc-link-arg=-Wl,-force_load,{}", prebuilt.display() ); } return; } } // Source build via CMake (Release CRT matches Rust on Windows). let mut config = cmake::Config::new(&vendor); if let Ok(py) = env::var("COOLPROP_PYTHON_EXECUTABLE") { config.define("Python_EXECUTABLE", &py); } config .define("COOLPROP_SHARED_LIBRARY", "OFF") .define("COOLPROP_STATIC_LIBRARY", "ON") .define("COOLPROP_CATCH_TEST", "OFF") .define("COOLPROP_C_LIBRARY", "ON") .define("COOLPROP_MY_IFCO3_WRAPPER", "OFF") .profile("Release"); let dst = config.build(); println!("cargo:rustc-link-search=native={}/build", dst.display()); println!( "cargo:rustc-link-search=native={}/build/Debug", dst.display() ); println!( "cargo:rustc-link-search=native={}/build/Release", dst.display() ); println!("cargo:rustc-link-search=native={}/lib", dst.display()); println!( "cargo:rustc-link-search=native={}/build", vendor.display() ); println!("cargo:rustc-link-lib=static=CoolProp"); if target_os == "macos" { println!( "cargo:rustc-link-arg=-Wl,-force_load,{}/build/libCoolProp.a", dst.display() ); } } else { println!( "cargo:warning=CoolProp source not found in vendor/. \ For full static build, run: \ git clone https://github.com/CoolProp/CoolProp.git vendor/coolprop" ); if target_os == "windows" { println!("cargo:rustc-link-lib=CoolProp"); } else { println!("cargo:rustc-link-lib=static=CoolProp"); } } link_system_libs(&target_os); if target_os == "macos" { println!("cargo:rustc-link-arg=-Wl,-all_load"); } }