Skip to content

Rewrite build system, fix hbool_t, remove libhdf5-lib crate #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Feb 1, 2019

Conversation

aldanor
Copy link
Owner

@aldanor aldanor commented Jan 29, 2019

  • The build script has been completely rewritten; below are the major points.
  • The env vars the build script reacts to are now HDF5_DIR and HDF5_VERSION.
  • The build script now locates and parses H5pubconf.h (autogenerated header) via bindgen, extracting the library version and several preprocessor definitions out of it to be used later.
  • This allows us to fix hbool_t on Windows and accessing HDF5 config header #28 (hbool_t is now defined conditionally).
  • h5_have_parallel, h5_have_threadsafe and h5_have_direct are exposed for downstream use.
  • The build script now loads the HDF5 library via libloading and verifies its version (we would probably still have to do this even if linking is static).
  • libhdf5-lib crate is removed entirely, its contents are merged into libhdf5-sys.
  • pkg-config now only runs on Linux.
  • Added a few known Linux locations (when apt-installed on Ubuntu).
  • Run brew --prefix on macOS; this supports both @1.8 and @1.10 bottles.
  • On Windows, search the registry (via winreg) for official installations.
  • Dynamic linking vs conda hdf5 now works on all platforms and tested on CI.

Expand the CI test suite greatly (in particular, link against conda on all platforms along with other methods like apt, brew and official installers; build both HDF5 1.8 and HDF5 1.10 on all platforms):

Rust Linux macOS Windows (MSVC)
stable 1.10.4 (conda/xenial) 1.8.21 (brew) 1.8.21 (msi)
beta 1.8.16 (apt/xenial) 1.10.4 (brew) 1.10.0 (msi)
nightly 1.8.11 (apt/trusty) 1.8.9 (conda) 1.10.4 (conda)

- On Windows, look up HDF5 in Windows registry
- On macOS, check if HDF5 is installed in Homebrew
- Only run pkg-config on non-macos unix platforms
- Remove pkg-config build dependency on macOS
- HDF5_LIBDIR is no longer used
- HDF5_DIR can be pointed to HDF5 installation root
- HDF5_VERSION environment variable can be now specified
- HDF5_VERSION restricts pkg-config/winreg lookups
- On Windows, detect conda environments automatically
- Require that include/H5pubconf.h exists in HDF5 root
- Parse H5Ppubconf.h header and extract useful constants
@aldanor
Copy link
Owner Author

aldanor commented Jan 29, 2019

@pmarks @Enet4 if you have any chance to test this out - would be much appreciated; if I don't hear from anyone I'll merge it in since it seems like it works on all platforms it's being tested on

@Enet4
Copy link

Enet4 commented Jan 29, 2019

I just ran cargo test real quick on this branch, I'm afraid it did not build successfully:

error: failed to run custom build command for `libhdf5-sys v0.2.0 (/home/enet4/hdf5-rs/libhdf5-sys)`
process didn't exit successfully: `/home/enet4/hdf5-rs/target/debug/build/libhdf5-sys-6be31ede1e344f33/build-script-build` (exit code: 101)
--- stdout
Attempting to find HDF5 via pkg-config...
Found HDF5 headers at:
    "/usr/include"
Adding to link path:
    "/usr/lib/x86_64-linux-gnu"
Parsing HDF5 config from:
    "/usr/include/H5pubconf.h"

--- stderr
thread 'main' panicked at 'Unable to infer HDF5 library runtime version.', libhdf5-sys/build.rs:144:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

I'm on Manjaro Linux (Arch-based), with HDF5 installed via pacman:

pacman -Si hdf5
Repository      : community
Name            : hdf5
Version         : 1.10.4-1
Description     : General purpose library and file format for storing scientific data
Architecture    : x86_64
URL             : https://www.hdfgroup.org/hdf5
Licenses        : custom
Groups          : None
Provides        : hdf5-cpp-fortran
Depends On      : zlib  libaec  bash
Optional Deps   : None
Conflicts With  : None
Replaces        : hdf5-cpp-fortran
Download Size   : 3,48 MiB
Installed Size  : 19,11 MiB
Packager        : Bruno Pagani <[email protected]>
Build Date      : seg 22 out 2018 12:03:08 WEST
Validated By    : MD5 Sum  SHA-256 Sum  Signature

@aldanor
Copy link
Owner Author

aldanor commented Jan 29, 2019

@Enet4 thanks for testing!

So, not everything is lost, the following did work:

  • pkg-config was called and its info parsed
  • headers were located
  • H5pubconf.h header was parsed successfully
  • library path was figured out

What didn’t work: loading the library .so via libloading to figure out its version. It’s hard to tell why it failed without debugging locally, options are:

  • libhdf5.so wasn’t there at the link path (could you check? Is there anything arch/pacman special?)
  • libloading couldn’t open the .so for some reason
  • the .so was opened but H5get_libversion() failed (highly unlikely)

Note: if you run cargo build/test -vv, you can observe all of the output of the build script.

@aldanor
Copy link
Owner Author

aldanor commented Jan 29, 2019

By the way, I think we can try and replace one of the xenial/apt Travis environments with Arch/pacman - I’ll take a look a bit later.

@Enet4
Copy link

Enet4 commented Jan 29, 2019

All right, another set of quick commands:

whereis libhdf5:

libhdf5: /usr/lib/libhdf5.a /usr/lib/libhdf5.settings /usr/lib/libhdf5.so

cargo test -vv

[libhdf5-sys 0.2.0] Attempting to find HDF5 via pkg-config...
[libhdf5-sys 0.2.0] Found HDF5 headers at:
[libhdf5-sys 0.2.0]     "/usr/include"
[libhdf5-sys 0.2.0] Adding to link path:
[libhdf5-sys 0.2.0]     "/usr/lib/x86_64-linux-gnu"
[libhdf5-sys 0.2.0] Parsing HDF5 config from:
[libhdf5-sys 0.2.0]     "/usr/include/H5pubconf.h"
[libhdf5-sys 0.2.0] thread 'main' panicked at 'Unable to infer HDF5 library runtime version.', libhdf5-sys/build.rs:144:5
[libhdf5-sys 0.2.0] note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: failed to run custom build command for `libhdf5-sys v0.2.0 (/home/enet4/hdf5-rs/libhdf5-sys)`
...

I'm afraid that I am not in a good position to go deep into this right now, I'm on an important deadline until Thursday.

@aldanor
Copy link
Owner Author

aldanor commented Jan 29, 2019

No problems, thanks for helping.

I see the problem, ok - libhdf5.so is in /usr/lib, whereas link path apparently reported by pkgconfig is /usr/lib/x86_64-linux-gnu. The build script tries to find .so in the latter and obviously fails.

The question is, how can it figure out about /usr/lib in a clean way? Hmm....

@pmarks
Copy link
Contributor

pmarks commented Jan 29, 2019

@aldanor very cool! I tested it against my current macOS install (brew), and followed the conda directions in our linux environment. Both worked smoothly! This is great for our near-term use cases.

@aldanor
Copy link
Owner Author

aldanor commented Jan 30, 2019

@Enet4 Could you please run the following on your machine and post the results back here?

ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012

@Enet4
Copy link

Enet4 commented Jan 30, 2019

Right now I am on a different Manjaro Linux machine, but it seems to reproduce the problem all the same. Allow me to run everything again from here:

Building with cargo -vv:

[libhdf5-sys 0.2.0] Attempting to find HDF5 via pkg-config...
[libhdf5-sys 0.2.0] Found HDF5 headers at:
[libhdf5-sys 0.2.0]     "/usr/include"
[libhdf5-sys 0.2.0] Adding to link path:
[libhdf5-sys 0.2.0]     "/usr/lib/x86_64-linux-gnu"
[libhdf5-sys 0.2.0] Parsing HDF5 config from:
[libhdf5-sys 0.2.0]     "/usr/include/H5pubconf.h"
[libhdf5-sys 0.2.0] thread 'main' panicked at 'Unable to infer HDF5 library runtime version.', libhdf5-sys/build.rs:144:5
[libhdf5-sys 0.2.0] note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: failed to run custom build command for `libhdf5-sys v0.2.0 (/home/enet4/misc/hdf5-rs/libhdf5-sys)`
process didn't exit successfully: `/home/enet4/misc/hdf5-rs/target/debug/build/libhdf5-sys-17b7a3d8adc43b30/build-script-build` (exit code: 101)
--- stdout
Attempting to find HDF5 via pkg-config...
Found HDF5 headers at:
    "/usr/include"
Adding to link path:
    "/usr/lib/x86_64-linux-gnu"
Parsing HDF5 config from:
    "/usr/include/H5pubconf.h"

--- stderr
thread 'main' panicked at 'Unable to infer HDF5 library runtime version.', libhdf5-sys/build.rs:144:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

whereis hdf5:

libhdf5: /usr/lib/libhdf5.settings /usr/lib/libhdf5.so /usr/lib/libhdf5.a

And ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012:

SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")

@aldanor
Copy link
Owner Author

aldanor commented Jan 30, 2019

@Enet4 Great, thanks. I think the proper course of action on Linux would be then to search for libhdf5.so in all paths reported by ld --verbose in that order until it's found. It would resolve cases like yours where the link path reported by pkgconfig doesn't actually contain the library binaries (which is different from how it works on debian/ubuntu). I hope to fix it later tonight, will ping back when it's done.

@aldanor aldanor force-pushed the feature/bindgen-pubconf branch from 19b40fe to f8dd24c Compare January 30, 2019 21:05
@aldanor
Copy link
Owner Author

aldanor commented Jan 30, 2019

@Enet4 the build script now looks for ld --verbose paths, could you give it a try?

@Enet4
Copy link

Enet4 commented Jan 30, 2019

I'm afraid that it did not quite do the trick yet:

[libhdf5-sys 0.2.0] Attempting to find HDF5 via pkg-config...
[libhdf5-sys 0.2.0] Found HDF5 headers at:
[libhdf5-sys 0.2.0]     "/usr/include"
[libhdf5-sys 0.2.0] Adding to link path:
[libhdf5-sys 0.2.0]     "/usr/lib/x86_64-linux-gnu"
[libhdf5-sys 0.2.0] Parsing HDF5 config from:
[libhdf5-sys 0.2.0]     "/usr/include/H5pubconf.h"
[libhdf5-sys 0.2.0] Looking for HDF5 library binary...
[libhdf5-sys 0.2.0] Adding extra link paths (ld)...
[libhdf5-sys 0.2.0] thread 'main' panicked at 'Unable to infer HDF5 library runtime version (can't find the binary).', libhdf5-sys/build.rs:158:5
[libhdf5-sys 0.2.0] note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: failed to run custom build command for `libhdf5-sys v0.2.0 (/home/enet4/hdf5-rs/libhdf5-sys)`
process didn't exit successfully: `/home/enet4/hdf5-rs/target/debug/build/libhdf5-sys-fc1258915cb468e0/build-script-build` (exit code: 101)
--- stdout
Attempting to find HDF5 via pkg-config...
Found HDF5 headers at:
    "/usr/include"
Adding to link path:
    "/usr/lib/x86_64-linux-gnu"
Parsing HDF5 config from:
    "/usr/include/H5pubconf.h"
Looking for HDF5 library binary...
Adding extra link paths (ld)...

--- stderr
thread 'main' panicked at 'Unable to infer HDF5 library runtime version (can't find the binary).', libhdf5-sys/build.rs:158:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

At this point it might be worth understanding why the hdf5 package is assuming a seemingly erroneous pkg-config link path. I'll dump a few more outputs in case it helps.

pkg-config --list-all | rg hdf:

pkg-config --list-all | rg hdf
hdf5_hl_cpp-1.10.4             hdf5_hl_cpp - HDF5 (Hierarchical Data Format 5) Software Library
hdf5-1.10.4                    hdf5 - HDF5 (Hierarchical Data Format 5) Software Library
hdf5_hl-1.10.4                 hdf5_hl - HDF5 (Hierarchical Data Format 5) Software Library
hdf5_cpp-1.10.4                hdf5_cpp - HDF5 (Hierarchical Data Format 5) Software Library

pkg-config --libs hdf5-1.10.4

-lhdf5

It seems that this package configuration does not specify any link paths. Not that it should be a problem, considering that the shared objects are installed in the default system's lib directory.

@aldanor
Copy link
Owner Author

aldanor commented Jan 30, 2019

The question is why no paths are added, seems like regex is not parsing anything successfully on your box from ld —verbose, extremely weird. You can check Travis logs for how it looks there - a bunch of paths like /usr/lib etc get added.

At this point I’d either need to install an arch virtual machine somewhere, or setup arch via docker on travis or something like that, either of which may take considerable time... so any help is greatly appreciated.

@aldanor
Copy link
Owner Author

aldanor commented Jan 30, 2019

Not that it should be a problem, considering that the shared objects are installed in the default system's lib directory.

Well, that’s exactly what we’re trying to do here with parsing ld —verbose, figure the system’s default lib directories...

@aldanor
Copy link
Owner Author

aldanor commented Jan 30, 2019

@Enet4 wonder if you could upload the output of your local ld --verbose somewhere? (or try passing it through the regex in the build script yourself)

@Enet4
Copy link

Enet4 commented Jan 30, 2019

@aldanor I dumped the full output into a gist.

@aldanor
Copy link
Owner Author

aldanor commented Jan 31, 2019

@Enet4 gotcha -- here's another attempt, maybe that would finally work?..

(why would ld report paths as "=/usr/lib" on debian and as "/usr/lib" on arch?... that's a different question altogether...)

@Enet4
Copy link

Enet4 commented Jan 31, 2019

Yes, this one built successfully now! All tests (except the ones from hdf5-derive) also pass.

@aldanor aldanor merged commit a64c141 into master Feb 1, 2019
@aldanor aldanor deleted the feature/bindgen-pubconf branch February 1, 2019 10:05
@aldanor aldanor mentioned this pull request Feb 1, 2019
9 tasks
magnusuMET added a commit to magnusuMET/hdf5-rust that referenced this pull request Oct 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

hbool_t on Windows and accessing HDF5 config header
3 participants