From 2ba5e8961d736a20bd1c803c99209cbf2c94cbe4 Mon Sep 17 00:00:00 2001 From: Magnus Ulimoen Date: Tue, 10 Jun 2025 17:37:00 +0200 Subject: [PATCH] Rework nc detection --- netcdf-sys/build.rs | 82 +++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/netcdf-sys/build.rs b/netcdf-sys/build.rs index dc9db7f..d139e7a 100644 --- a/netcdf-sys/build.rs +++ b/netcdf-sys/build.rs @@ -172,13 +172,18 @@ fn from_utf8_to_trimmed_string(bytes: &[u8]) -> String { } impl NcInfo { - fn from_path(path: &Path) -> Self { - Self { + fn from_path(path: &Path) -> Option { + let includedir = path.join("include"); + if !includedir.exists() { + return None; + } + + Some(Self { version: None, includedir: path.join("include"), libdir: path.join("lib"), libname: "netcdf".to_owned(), - } + }) } fn gather_from_ncconfig(search_path: Option<&Path>) -> Option { let path = if let Some(search_path) = search_path { @@ -229,6 +234,40 @@ fn _check_consistent_version_linked() { todo!() } +fn determine_ncinfo() -> NcInfo { + let nc_dir = std::env::var_os("NETCDF_DIR") + .or_else(|| std::env::var_os("NetCDF_DIR")) + .map(PathBuf::from); + + if let Some(nc_dir) = nc_dir.as_ref() { + #[allow(unused_mut)] + if let Some(info) = NcInfo::gather_from_ncconfig(Some(nc_dir)) { + return info; + } + if let Some(info) = NcInfo::from_path(nc_dir) { + return info; + } + #[cfg(windows)] + { + // Conda requires Library prefix + let nc_dir = nc_dir.join("Library"); + if let Some(info) = NcInfo::gather_from_ncconfig(Some(&nc_dir)) { + return info; + } + if let Some(info) = NcInfo::from_path(&nc_dir) { + return info; + } + } + } + + if let Some(info) = NcInfo::gather_from_ncconfig(None) { + return info; + } + + panic!("A system version of libnetcdf could not be found. Consider installing to some default location, use the environment variable NETCDF_DIR (remember to restart the shell), or prefer building the static version of libnetcdf by enabling the `static` feature on `netcdf-sys` or `netcdf`" + ); +} + fn main() { println!("cargo::rerun-if-changed=build.rs"); @@ -237,42 +276,19 @@ fn main() { let netcdf_lib = std::env::var("DEP_NETCDFSRC_LIB").unwrap(); let netcdf_path = PathBuf::from(std::env::var_os("DEP_NETCDFSRC_SEARCH").unwrap()); - info = NcInfo::gather_from_ncconfig(Some(&netcdf_path.join(".."))) - .unwrap_or_else(|| NcInfo::from_path(&netcdf_path.join(".."))); + let mut linfo = NcInfo::gather_from_ncconfig(Some(&netcdf_path.join(".."))); + if linfo.is_none() { + linfo = NcInfo::from_path(&netcdf_path.join("..")) + } + + info = linfo.expect("The library path should be determined by this point"); println!("cargo::rustc-link-search=native={}", netcdf_path.display()); println!("cargo::rustc-link-lib=static={netcdf_lib}"); } else { println!("cargo::rerun-if-env-changed=NETCDF_DIR"); - let nc_dir = std::env::var_os("NETCDF_DIR") - .or_else(|| std::env::var_os("NetCDF_DIR")) - .map(PathBuf::from); - - #[cfg(windows)] - let nc_dir = nc_dir.map(|d| d.join("Library")); - - info = if let Some(nc_dir) = nc_dir.as_ref() { - #[allow(unused_mut)] - let mut info = NcInfo::gather_from_ncconfig(Some(nc_dir)) - .unwrap_or_else(|| NcInfo::from_path(nc_dir)); - #[cfg(windows)] - { - // Conda requires Library prefix - if info.is_none() { - let nc_dir = nc_dir.map(|d| d.join("Library")).unwrap(); - - info = NcInfo::gather_from_ncconfig(Some(nc_dir)) - .unwrap_or_else(|| NcInfo::from_path(nc_dir)); - } - } - - info - } else { - NcInfo::gather_from_ncconfig(None).unwrap_or_else(|| - panic!("A system version of libnetcdf could not be found. Consider installing to some default location, use the environment variable NETCDF_DIR (remember to restart the shell), or prefer building the static version of libnetcdf by enabling the `static` feature on `netcdf-sys` or `netcdf`") - ) - }; + info = determine_ncinfo(); println!("cargo::rustc-link-search={}", info.libdir.display()); println!("cargo::rustc-link-lib={}", &info.libname);