chore: sync project state and current artifacts
This commit is contained in:
@@ -12,6 +12,7 @@ libc = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
cmake = "0.1.57"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -9,7 +9,7 @@ fn coolprop_src_path() -> Option<PathBuf> {
|
||||
// Try to find CoolProp source in common locations
|
||||
let possible_paths = vec![
|
||||
// Vendor directory (recommended)
|
||||
PathBuf::from("vendor/coolprop"),
|
||||
PathBuf::from("../../vendor/coolprop").canonicalize().unwrap_or(PathBuf::from("../../../vendor/coolprop")),
|
||||
// External directory
|
||||
PathBuf::from("external/coolprop"),
|
||||
// System paths
|
||||
@@ -17,42 +17,64 @@ fn coolprop_src_path() -> Option<PathBuf> {
|
||||
PathBuf::from("/opt/CoolProp"),
|
||||
];
|
||||
|
||||
possible_paths.into_iter().find(|path| path.join("CMakeLists.txt").exists())
|
||||
possible_paths
|
||||
.into_iter()
|
||||
.find(|path| path.join("CMakeLists.txt").exists())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let static_linking = env::var("CARGO_FEATURE_STATIC").is_ok();
|
||||
let static_linking = env::var("CARGO_FEATURE_STATIC").is_ok() || true; // Force static linking for python wheels
|
||||
|
||||
// Check if CoolProp source is available
|
||||
if let Some(coolprop_path) = coolprop_src_path() {
|
||||
println!("cargo:rerun-if-changed={}", coolprop_path.display());
|
||||
|
||||
// Configure build for CoolProp
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}/build",
|
||||
coolprop_path.display()
|
||||
);
|
||||
}
|
||||
// Build CoolProp using CMake
|
||||
let dst = cmake::Config::new(&coolprop_path)
|
||||
.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")
|
||||
.build();
|
||||
|
||||
// Link against CoolProp
|
||||
if static_linking {
|
||||
// Static linking - find libCoolProp.a
|
||||
println!("cargo:rustc-link-search=native={}/build", dst.display());
|
||||
println!("cargo:rustc-link-search=native={}/lib", dst.display());
|
||||
println!("cargo:rustc-link-search=native={}/build", coolprop_path.display()); // Fallback
|
||||
|
||||
// Link against CoolProp statically
|
||||
println!("cargo:rustc-link-lib=static=CoolProp");
|
||||
|
||||
// On macOS, force load the static library so its symbols are exported in the final cdylib
|
||||
if cfg!(target_os = "macos") {
|
||||
println!("cargo:rustc-link-arg=-Wl,-force_load,{}/build/libCoolProp.a", dst.display());
|
||||
}
|
||||
} else {
|
||||
// Dynamic linking
|
||||
println!("cargo:rustc-link-lib=dylib=CoolProp");
|
||||
println!(
|
||||
"cargo:warning=CoolProp source not found in vendor/.
|
||||
For full static build, run:
|
||||
git clone https://github.com/CoolProp/CoolProp.git vendor/coolprop"
|
||||
);
|
||||
// Fallback for system library
|
||||
if static_linking {
|
||||
println!("cargo:rustc-link-lib=static=CoolProp");
|
||||
} else {
|
||||
println!("cargo:rustc-link-lib=dylib=CoolProp");
|
||||
}
|
||||
}
|
||||
|
||||
// Link required system libraries
|
||||
println!("cargo:rustc-link-lib=dylib=m");
|
||||
// Link required system libraries for C++ standard library
|
||||
#[cfg(target_os = "macos")]
|
||||
println!("cargo:rustc-link-lib=dylib=c++");
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
println!("cargo:rustc-link-lib=dylib=stdc++");
|
||||
|
||||
// Tell Cargo to rerun if build.rs changes
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rustc-link-lib=dylib=m");
|
||||
|
||||
println!(
|
||||
"cargo:warning=CoolProp source not found in vendor/.
|
||||
For full static build, run:
|
||||
git clone https://github.com/CoolProp/CoolProp.git vendor/coolprop"
|
||||
);
|
||||
// Tell Cargo to rerun if build.rs changes
|
||||
|
||||
// Force export symbols on macOS for static building into a dynamic python extension
|
||||
println!("cargo:rustc-link-arg=-Wl,-all_load");
|
||||
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
}
|
||||
|
||||
@@ -131,41 +131,48 @@ pub enum CoolPropInputPair {
|
||||
// CoolProp C functions
|
||||
extern "C" {
|
||||
/// Get a property value using pressure and temperature
|
||||
fn CoolProp_PropsSI(
|
||||
Output: c_char,
|
||||
Name1: c_char,
|
||||
/// Get a property value using pressure and temperature
|
||||
#[cfg_attr(target_os = "macos", link_name = "\x01__Z7PropsSIPKcS0_dS0_dS0_")]
|
||||
#[cfg_attr(not(target_os = "macos"), link_name = "_Z7PropsSIPKcS0_dS0_dS0_")]
|
||||
fn PropsSI(
|
||||
Output: *const c_char,
|
||||
Name1: *const c_char,
|
||||
Value1: c_double,
|
||||
Name2: c_char,
|
||||
Name2: *const c_char,
|
||||
Value2: c_double,
|
||||
Fluid: *const c_char,
|
||||
) -> c_double;
|
||||
|
||||
/// Get a property value using input pair
|
||||
fn CoolProp_Props1SI(Fluid: *const c_char, Output: c_char) -> c_double;
|
||||
#[cfg_attr(target_os = "macos", link_name = "\x01__Z8Props1SIPKcS0_")]
|
||||
#[cfg_attr(not(target_os = "macos"), link_name = "_Z8Props1SIPKcS0_")]
|
||||
fn Props1SI(Fluid: *const c_char, Output: *const c_char) -> c_double;
|
||||
|
||||
/// Get CoolProp version string
|
||||
fn CoolProp_get_global_param_string(
|
||||
#[cfg_attr(target_os = "macos", link_name = "\x01__Z23get_global_param_stringNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE")]
|
||||
#[cfg_attr(not(target_os = "macos"), link_name = "get_global_param_string")]
|
||||
fn get_global_param_string(
|
||||
Param: *const c_char,
|
||||
Output: *mut c_char,
|
||||
OutputLength: c_int,
|
||||
) -> c_int;
|
||||
|
||||
/// Get fluid info
|
||||
fn CoolProp_get_fluid_param_string(
|
||||
#[cfg_attr(target_os = "macos", link_name = "\x01__Z22get_fluid_param_stringNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES5_")]
|
||||
#[cfg_attr(not(target_os = "macos"), link_name = "get_fluid_param_string")]
|
||||
fn get_fluid_param_string(
|
||||
Fluid: *const c_char,
|
||||
Param: *const c_char,
|
||||
Output: *mut c_char,
|
||||
OutputLength: c_int,
|
||||
) -> c_int;
|
||||
|
||||
/// Check if fluid exists
|
||||
fn CoolProp_isfluid(Fluid: *const c_char) -> c_int;
|
||||
// Check if fluid exists
|
||||
// CoolProp doesn't have a direct C isfluid function. We usually just try to fetch a string or param or we can map it downstream
|
||||
// But let's see if we can just dummy it or use get_fluid_param_string
|
||||
|
||||
/// Get saturation temperature
|
||||
fn CoolProp_Saturation_T(Fluid: *const c_char, Par: c_char, Value: c_double) -> c_double;
|
||||
// There is no C CriticalPoint, it's just Props1SI("Tcrit", "Water")
|
||||
|
||||
/// Get critical point
|
||||
fn CoolProp_CriticalPoint(Fluid: *const c_char, Output: c_char) -> c_double;
|
||||
}
|
||||
|
||||
/// Get a thermodynamic property using pressure and temperature.
|
||||
@@ -181,10 +188,10 @@ extern "C" {
|
||||
/// This function calls the CoolProp C++ library and passes a CString pointer.
|
||||
/// The caller must ensure the fluid string is properly null-terminated if needed and valid.
|
||||
pub unsafe fn props_si_pt(property: &str, p: f64, t: f64, fluid: &str) -> f64 {
|
||||
let prop = property.as_bytes()[0] as c_char;
|
||||
let prop_c = std::ffi::CString::new(property).unwrap();
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
|
||||
CoolProp_PropsSI(prop, b'P' as c_char, p, b'T' as c_char, t, fluid_c.as_ptr())
|
||||
PropsSI(prop_c.as_ptr(), c"P".as_ptr(), p, c"T".as_ptr(), t, fluid_c.as_ptr())
|
||||
}
|
||||
|
||||
/// Get a thermodynamic property using pressure and enthalpy.
|
||||
@@ -200,10 +207,10 @@ pub unsafe fn props_si_pt(property: &str, p: f64, t: f64, fluid: &str) -> f64 {
|
||||
/// This function calls the CoolProp C++ library and passes a CString pointer.
|
||||
/// The caller must ensure the fluid string is valid.
|
||||
pub unsafe fn props_si_ph(property: &str, p: f64, h: f64, fluid: &str) -> f64 {
|
||||
let prop = property.as_bytes()[0] as c_char;
|
||||
let prop_c = std::ffi::CString::new(property).unwrap();
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
|
||||
CoolProp_PropsSI(prop, b'P' as c_char, p, b'H' as c_char, h, fluid_c.as_ptr())
|
||||
PropsSI(prop_c.as_ptr(), c"P".as_ptr(), p, c"H".as_ptr(), h, fluid_c.as_ptr())
|
||||
}
|
||||
|
||||
/// Get a thermodynamic property using temperature and quality (saturation).
|
||||
@@ -219,10 +226,10 @@ pub unsafe fn props_si_ph(property: &str, p: f64, h: f64, fluid: &str) -> f64 {
|
||||
/// This function calls the CoolProp C++ library and passes a CString pointer.
|
||||
/// The caller must ensure the fluid string is valid.
|
||||
pub unsafe fn props_si_tq(property: &str, t: f64, q: f64, fluid: &str) -> f64 {
|
||||
let prop = property.as_bytes()[0] as c_char;
|
||||
let prop_c = std::ffi::CString::new(property).unwrap();
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
|
||||
CoolProp_PropsSI(prop, b'T' as c_char, t, b'Q' as c_char, q, fluid_c.as_ptr())
|
||||
PropsSI(prop_c.as_ptr(), c"T".as_ptr(), t, c"Q".as_ptr(), q, fluid_c.as_ptr())
|
||||
}
|
||||
|
||||
/// Get a thermodynamic property using pressure and quality.
|
||||
@@ -238,14 +245,14 @@ pub unsafe fn props_si_tq(property: &str, t: f64, q: f64, fluid: &str) -> f64 {
|
||||
/// This function calls the CoolProp C++ library and passes a CString pointer.
|
||||
/// The caller must ensure the fluid string is valid.
|
||||
pub unsafe fn props_si_px(property: &str, p: f64, x: f64, fluid: &str) -> f64 {
|
||||
let prop = property.as_bytes()[0] as c_char;
|
||||
let prop_c = std::ffi::CString::new(property).unwrap();
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
|
||||
CoolProp_PropsSI(
|
||||
prop,
|
||||
b'P' as c_char,
|
||||
PropsSI(
|
||||
prop_c.as_ptr(),
|
||||
c"P".as_ptr(),
|
||||
p,
|
||||
b'Q' as c_char, // Q for quality
|
||||
c"Q".as_ptr(), // Q for quality
|
||||
x,
|
||||
fluid_c.as_ptr(),
|
||||
)
|
||||
@@ -262,7 +269,7 @@ pub unsafe fn props_si_px(property: &str, p: f64, x: f64, fluid: &str) -> f64 {
|
||||
/// The caller must ensure the fluid string is valid.
|
||||
pub unsafe fn critical_temperature(fluid: &str) -> f64 {
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
CoolProp_CriticalPoint(fluid_c.as_ptr(), b'T' as c_char)
|
||||
Props1SI(fluid_c.as_ptr(), c"Tcrit".as_ptr())
|
||||
}
|
||||
|
||||
/// Get critical point pressure for a fluid.
|
||||
@@ -276,7 +283,7 @@ pub unsafe fn critical_temperature(fluid: &str) -> f64 {
|
||||
/// The caller must ensure the fluid string is valid.
|
||||
pub unsafe fn critical_pressure(fluid: &str) -> f64 {
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
CoolProp_CriticalPoint(fluid_c.as_ptr(), b'P' as c_char)
|
||||
Props1SI(fluid_c.as_ptr(), c"pcrit".as_ptr())
|
||||
}
|
||||
|
||||
/// Get critical point density for a fluid.
|
||||
@@ -290,7 +297,7 @@ pub unsafe fn critical_pressure(fluid: &str) -> f64 {
|
||||
/// The caller must ensure the fluid string is valid.
|
||||
pub unsafe fn critical_density(fluid: &str) -> f64 {
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
CoolProp_CriticalPoint(fluid_c.as_ptr(), b'D' as c_char)
|
||||
Props1SI(fluid_c.as_ptr(), c"rhocrit".as_ptr())
|
||||
}
|
||||
|
||||
/// Check if a fluid is available in CoolProp.
|
||||
@@ -304,7 +311,9 @@ pub unsafe fn critical_density(fluid: &str) -> f64 {
|
||||
/// The caller must ensure the fluid string is valid.
|
||||
pub unsafe fn is_fluid_available(fluid: &str) -> bool {
|
||||
let fluid_c = CString::new(fluid).unwrap();
|
||||
CoolProp_isfluid(fluid_c.as_ptr()) != 0
|
||||
// CoolProp C API does not expose isfluid, so we try fetching a property
|
||||
let res = Props1SI(fluid_c.as_ptr(), c"Tcrit".as_ptr());
|
||||
if res.is_finite() && res != 0.0 { true } else { false }
|
||||
}
|
||||
|
||||
/// Get CoolProp version string.
|
||||
@@ -314,7 +323,7 @@ pub unsafe fn is_fluid_available(fluid: &str) -> bool {
|
||||
pub fn get_version() -> String {
|
||||
unsafe {
|
||||
let mut buffer = vec![0u8; 32];
|
||||
let result = CoolProp_get_global_param_string(
|
||||
let result = get_global_param_string(
|
||||
c"version".as_ptr(),
|
||||
buffer.as_mut_ptr() as *mut c_char,
|
||||
buffer.len() as c_int,
|
||||
|
||||
Reference in New Issue
Block a user