@@ -29,7 +29,7 @@ impl Version {
2929 }
3030
3131 pub fn parse ( s : & str ) -> Option < Self > {
32- let re = Regex :: new ( r"^(1)\.(8|10|12|13|14)\.(\d\d?)(_\d+)?(- (patch)?\d+)?$" ) . ok ( ) ?;
32+ let re = Regex :: new ( r"^(1)\.(8|10|12|13|14)\.(\d\d?)(_\d+)?((-|.) (patch)?\d+)?$" ) . ok ( ) ?;
3333 let captures = re. captures ( s) ?;
3434 Some ( Self {
3535 major : captures. get ( 1 ) . and_then ( |c| c. as_str ( ) . parse :: < u8 > ( ) . ok ( ) ) ?,
@@ -73,6 +73,13 @@ fn is_root_dir<P: AsRef<Path>>(path: P) -> bool {
7373 is_inc_dir ( path. as_ref ( ) . join ( "include" ) )
7474}
7575
76+ #[ allow( dead_code) ]
77+ fn is_msvc ( ) -> bool {
78+ // `cfg!(target_env = "msvc")` will report wrong value when using
79+ // MSVC toolchain targeting GNU.
80+ std:: env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) == "msvc"
81+ }
82+
7683#[ derive( Clone , Debug ) ]
7784struct RuntimeError ( String ) ;
7885
@@ -115,7 +122,7 @@ fn get_runtime_version_single<P: AsRef<Path>>(path: P) -> Result<Version, Box<dy
115122
116123fn validate_runtime_version ( config : & Config ) {
117124 println ! ( "Looking for HDF5 library binary..." ) ;
118- let libfiles = & [ "libhdf5.dylib" , "libhdf5.so" , "hdf5.dll" ] ;
125+ let libfiles = & [ "libhdf5.dylib" , "libhdf5.so" , "hdf5.dll" , "libhdf5-0.dll" , "libhdf5-310.dll" ] ;
119126 let mut link_paths = config. link_paths . clone ( ) ;
120127 if cfg ! ( all( unix, not( target_os = "macos" ) ) ) {
121128 if let Some ( ldv) = run_command ( "ld" , & [ "--verbose" ] ) {
@@ -233,16 +240,24 @@ pub struct LibrarySearcher {
233240 pub inc_dir : Option < PathBuf > ,
234241 pub link_paths : Vec < PathBuf > ,
235242 pub user_provided_dir : bool ,
243+ pub pkg_conf_found : bool ,
236244}
237245
238- #[ cfg( all( unix, not( target_os = "macos" ) ) ) ]
239- mod unix {
246+ #[ cfg( any ( all( unix, not( target_os = "macos" ) ) , windows ) ) ]
247+ mod pkgconf {
240248 use super :: { is_inc_dir, LibrarySearcher } ;
241249
242250 pub fn find_hdf5_via_pkg_config ( config : & mut LibrarySearcher ) {
243251 if config. inc_dir . is_some ( ) {
244252 return ;
245253 }
254+
255+ // If we're going to windows-gnu we can use pkg-config, but only so long as
256+ // we're coming from a windows host.
257+ if cfg ! ( windows) {
258+ std:: env:: set_var ( "PKG_CONFIG_ALLOW_CROSS" , "1" ) ;
259+ }
260+
246261 // Try pkg-config. Note that HDF5 only ships pkg-config metadata
247262 // in CMake builds (which is not what homebrew uses, for example).
248263 // Still, this would work sometimes on Linux.
@@ -272,8 +287,16 @@ mod unix {
272287 } else {
273288 println ! ( "Unable to locate HDF5 headers from pkg-config info." ) ;
274289 }
290+
291+ config. pkg_conf_found = true ;
275292 }
276293 }
294+ }
295+
296+ #[ cfg( all( unix, not( target_os = "macos" ) ) ) ]
297+ mod unix {
298+ pub use super :: pkgconf:: find_hdf5_via_pkg_config;
299+ use super :: { is_inc_dir, LibrarySearcher } ;
277300
278301 pub fn find_hdf5_in_default_location ( config : & mut LibrarySearcher ) {
279302 if config. inc_dir . is_some ( ) {
@@ -373,6 +396,7 @@ mod macos {
373396
374397#[ cfg( windows) ]
375398mod windows {
399+ pub use super :: pkgconf:: find_hdf5_via_pkg_config;
376400 use super :: * ;
377401
378402 use std:: io;
@@ -461,7 +485,7 @@ mod windows {
461485
462486 pub fn find_hdf5_via_winreg ( config : & mut LibrarySearcher ) {
463487 // Official HDF5 binaries on Windows are built for MSVC toolchain only.
464- if config. inc_dir . is_some ( ) || !cfg ! ( target_env = "msvc" ) {
488+ if config. inc_dir . is_some ( ) || !is_msvc ( ) {
465489 return ;
466490 }
467491 // Check the list of installed programs, see if there's HDF5 anywhere;
@@ -476,11 +500,13 @@ mod windows {
476500 pub fn validate_env_path ( config : & LibrarySearcher ) {
477501 if let Some ( ref inc_dir) = config. inc_dir {
478502 let var_path = env:: var ( "PATH" ) . unwrap_or_else ( |_| Default :: default ( ) ) ;
479- let bin_dir = inc_dir. parent ( ) . unwrap ( ) . join ( "bin" ) ;
503+ let bin_dir = inc_dir. parent ( ) . unwrap ( ) . join ( "bin" ) . canonicalize ( ) . unwrap ( ) ;
480504 for path in env:: split_paths ( & var_path) {
481- if path == bin_dir {
482- println ! ( "Found in PATH: {:?}" , path) ;
483- return ;
505+ if let Ok ( path) = path. canonicalize ( ) {
506+ if path == bin_dir {
507+ println ! ( "Found in PATH: {:?}" , path) ;
508+ return ;
509+ }
484510 }
485511 }
486512 panic ! ( "{:?} not found in PATH." , bin_dir) ;
@@ -502,7 +528,7 @@ impl LibrarySearcher {
502528 config. user_provided_dir = true ;
503529 config. inc_dir = Some ( root. join ( "include" ) ) ;
504530 }
505- if cfg ! ( target_env = "msvc" ) {
531+ if is_msvc ( ) {
506532 // in order to allow HDF5_DIR to be pointed to a conda environment, we have
507533 // to support MSVC as a special case (where the root is in $PREFIX/Library)
508534 if let Some ( ref inc_dir) = config. inc_dir {
@@ -541,6 +567,7 @@ impl LibrarySearcher {
541567 #[ cfg( windows) ]
542568 {
543569 self :: windows:: find_hdf5_via_winreg ( self ) ;
570+ self :: windows:: find_hdf5_via_pkg_config ( self ) ;
544571 // the check below is for dynamic linking only
545572 self :: windows:: validate_env_path ( self ) ;
546573 }
@@ -570,17 +597,20 @@ impl LibrarySearcher {
570597 if link_paths. is_empty ( ) {
571598 if let Some ( root_dir) = inc_dir. parent ( ) {
572599 link_paths. push ( root_dir. join ( "lib" ) ) ;
573- if cfg ! ( target_env = "msvc" ) {
574- link_paths. push ( root_dir. join ( "bin" ) ) ;
575- }
600+ link_paths. push ( root_dir. join ( "bin" ) ) ;
576601 }
577602 }
578603 let header = Header :: parse ( inc_dir) ;
579604 if let Some ( version) = self . version {
580605 assert_eq ! ( header. version, version, "HDF5 header version mismatch" , ) ;
581606 }
582607 let config = Config { inc_dir : inc_dir. clone ( ) , link_paths, header } ;
583- validate_runtime_version ( & config) ;
608+ // Don't check version if pkg-config finds the library and this is a windows target.
609+ // We trust the pkg-config provided path, to avoid updating dll names every time
610+ // the package updates.
611+ if !( self . pkg_conf_found && cfg ! ( windows) ) {
612+ validate_runtime_version ( & config) ;
613+ }
584614 config
585615 } else {
586616 panic ! ( "Unable to determine HDF5 location (set HDF5_DIR to specify it manually)." ) ;
@@ -604,7 +634,7 @@ impl Config {
604634 println ! ( "cargo:rerun-if-env-changed=HDF5_DIR" ) ;
605635 println ! ( "cargo:rerun-if-env-changed=HDF5_VERSION" ) ;
606636
607- if cfg ! ( target_env = "msvc" ) {
637+ if is_msvc ( ) {
608638 println ! ( "cargo:msvc_dll_indirection=1" ) ;
609639 }
610640 println ! ( "cargo:include={}" , self . inc_dir. to_str( ) . unwrap( ) ) ;
0 commit comments