Skip to content

Commit

Permalink
Introduce static build of hdf5
Browse files Browse the repository at this point in the history
  • Loading branch information
magnusuMET committed Jul 14, 2020
1 parent 15ec644 commit ade1e18
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 63 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "hdf5"]
path = hdf5-src/ext/hdf5
url = https://github.com/HDFGroup/hdf5.git
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ script:
fi
- cargo clean
- cargo build -vv
- cargo test -v --all
- cargo test -v --all --exclude hdf5-src
before_install:
- |
if [ `uname` = "Darwin" ] && [ ! -z "$H5_BREW" ]; then
Expand Down
5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ default = []
mpio = ["mpi-sys", "hdf5-sys/mpio"]

[workspace]
members = ["hdf5-types", "hdf5-derive", "hdf5-sys"]
members = ["hdf5-types", "hdf5-derive", "hdf5-sys", "hdf5-src"]
exclude = ["*.yml", "ci/*"]

[dependencies]
Expand All @@ -39,6 +39,3 @@ rand = { version = "0.7", features = ["small_rng"] }
regex = "1.3"
scopeguard = "1.0"
tempdir = "0.3"

[build-dependencies]
hdf5-sys = { path = "hdf5-sys", version = "0.6.1" } # !V
18 changes: 17 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
use std::env;

fn main() {
hdf5_sys::emit_cfg_flags();
for (key, _) in env::vars() {
let key = match key.as_str() {
"DEP_HDF5_HAVE_DIRECT" => "h5_have_direct".into(),
"DEP_HDF5_HAVE_STDBOOL" => "h5_have_stdbool".into(),
"DEP_HDF5_HAVE_PARALLEL" => "h5_have_parallel".into(),
"DEP_HDF5_HAVE_THREADSAFE" => "h5_have_threadsafe".into(),
"DEP_HDF5_MSVC_DLL_INDIRECTION" => "h5_dll_indirection".into(),
key if key.starts_with("DEP_HDF5_VERSION_") => {
let version = key.trim_start_matches("DEP_HDF5_VERSION_");
format!("hdf5_{}", version)
}
_ => continue,
};
println!("cargo:rustc-cfg={}", key);
}
}
2 changes: 1 addition & 1 deletion ci/appveyor.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def run_tests():
env['HDF5_VERSION'] = env['H5_VERSION']
print('Pinning HDF5 version to', env['HDF5_VERSION'])
run_command('cargo', 'build', '-vv', env=env)
run_command('cargo', 'test', '-v', '--all', env=env)
run_command('cargo', 'test', '-v', '--all', '--exclude', 'hdf5-src', env=env)


def main():
Expand Down
2 changes: 1 addition & 1 deletion hdf5-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ syn = { version = "^1.0.5", features = ["derive", "extra-traits"]}

[dev-dependencies]
trybuild = "1.0"
hdf5 = { version = ">=0.5", path = ".." }
hdf5 = { version = "0.6.1", path = ".." } # !V
38 changes: 38 additions & 0 deletions hdf5-src/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "hdf5-src"
version = "0.6.1" # !V
authors = ["Ivan Smirnov <[email protected]>"]
keywords = ["hdf5"]
license-file = "ext/hdf5/COPYING"
build = "build.rs"
repository = "https://github.com/aldanor/hdf5-rust"
homepage = "https://github.com/aldanor/hdf5-rust"
description = "Build script for compiling hdf5 from source"
edition = "2018"
links = "hdf5src"
exclude = [
"ext/hdf5/bin/**",
"ext/hdf5/c++/**",
"ext/hdf5/examples/**",
"ext/hdf5/fortran/**",
"ext/hdf5/java/**",
"ext/hdf5/release_docs/**",
"ext/hdf5/test/**",
"ext/hdf5/testpar/**",
"ext/hdf5/tools/**",
"ext/hdf5/hl/test/**",
"ext/hdf5/hl/tools/**",
"ext/hdf5/hl/examples/**",
]

[features]
hl = []
zlib = ["libz-sys"]
deprecated = []
threadsafe = []

[dependencies]
libz-sys = { version = "1.0.25", features = ["static"], optional = true }

[build-dependencies]
cmake = "0.1.44"
87 changes: 87 additions & 0 deletions hdf5-src/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use std::env;

fn feature_enabled(feature: &str) -> bool {
env::var(format!("CARGO_FEATURE_{}", feature)).is_ok()
}

fn main() {
println!("cargo:rerun-if-changed=build.rs");
let mut cfg = cmake::Config::new("ext/hdf5");

// only build the static c library, disable everything else
cfg.define("HDF5_NO_PACKAGES", "ON");
for option in &[
"BUILD_SHARED_LIBS",
"BUILD_TESTING",
"HDF5_BUILD_TOOLS",
"HDF5_BUILD_EXAMPLES",
"HDF5_BUILD_JAVA",
"HDF5_BUILD_FORTRAN",
"HDF5_BUILD_CPP_LIB",
"HDF5_ENABLE_PARALLEL",
] {
cfg.define(option, "OFF");
}

// disable these by default, can be enabled via features
for option in &[
"HDF5_ENABLE_DEPRECATED_SYMBOLS",
"HDF5_ENABLE_THREADSAFE",
"ALLOW_UNSUPPORTED",
"HDF5_BUILD_HL_LIB",
] {
cfg.define(option, "OFF");
}

if feature_enabled("ZLIB") {
let zlib_include_dir = env::var_os("DEP_Z_INCLUDE").unwrap();
let mut zlib_header = env::split_paths(&zlib_include_dir).next().unwrap();
zlib_header.push("zlib.h");
let zlib_lib = "z";
cfg.define("HDF5_ENABLE_Z_LIB_SUPPORT", "ON")
.define("H5_ZLIB_HEADER", &zlib_header)
.define("ZLIB_STATIC_LIBRARY", &zlib_lib);
println!("cargo:zlib_header={}", zlib_header.to_str().unwrap());
println!("cargo:zlib={}", zlib_lib);
}

if feature_enabled("DEPRECATED") {
cfg.define("HDF5_ENABLE_DEPRECATED_SYMBOLS", "ON");
}

if feature_enabled("THREADSAFE") {
cfg.define("HDF5_ENABLE_THREADSAFE", "ON");
if feature_enabled("HL") {
println!("cargo:warning=Unsupported HDF5 options: hl with threadsafe.");
cfg.define("ALLOW_UNSUPPORTED", "ON");
}
}

let debug_postfix = if cfg!(target_os = "windows") { "_D" } else { "_debug" };

if feature_enabled("HL") {
cfg.define("HDF5_BUILD_HL_LIB", "ON");
let mut hdf5_hl_lib =
if cfg!(target_env = "msvc") { "libhdf5_hl" } else { "hdf5_hl" }.to_owned();
if let Ok(opt_level) = env::var("OPT_LEVEL") {
if opt_level == "0" {
hdf5_hl_lib.push_str(debug_postfix);
}
}
println!("cargo:hl_library={}", hdf5_hl_lib);
}

let dst = cfg.build();
println!("cargo:root={}", dst.display());

let hdf5_incdir = format!("{}/include", dst.display());
println!("cargo:include={}", hdf5_incdir);

let mut hdf5_lib = if cfg!(target_env = "msvc") { "libhdf5" } else { "hdf5" }.to_owned();
if let Ok(opt_level) = env::var("OPT_LEVEL") {
if opt_level == "0" {
hdf5_lib.push_str(debug_postfix);
}
}
println!("cargo:library={}", hdf5_lib);
}
1 change: 1 addition & 0 deletions hdf5-src/ext/hdf5
Submodule hdf5 added at f53318
1 change: 1 addition & 0 deletions hdf5-src/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//! Dummy crate for building `hdf5` from source
8 changes: 8 additions & 0 deletions hdf5-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@ repository = "https://github.com/aldanor/hdf5-rust"
homepage = "https://github.com/aldanor/hdf5-rust"
description = "Native bindings to the HDF5 library."
edition = "2018"
links = "hdf5"

[dependencies]
libc = "0.2"
mpi-sys = { version = "0.1", optional = true }
libz-sys = { version = "1.0.25", optional = true }
hdf5-src = { path = "../hdf5-src", version = "0.6.1", optional = true } # !V

[features]
default = []
mpio = ["mpi-sys"]
hl = ["hdf5-src/hl"]
threadsafe = ["hdf5-src/threadsafe"]
zlib = ["libz-sys", "hdf5-src/zlib"]
static = ["hdf5-src"]
deprecated = ["hdf5-src/deprecated"]

[build-dependencies]
libloading = "0.6"
Expand Down
69 changes: 62 additions & 7 deletions hdf5-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ use std::fs;
use std::os::raw::{c_int, c_uint};
use std::path::{Path, PathBuf};
use std::process::Command;
use std::str;

use regex::Regex;

fn feature_enabled(feature: &str) -> bool {
env::var(format!("CARGO_FEATURE_{}", feature)).is_ok()
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct Version {
pub major: u8,
Expand Down Expand Up @@ -450,7 +453,7 @@ mod windows {
impl LibrarySearcher {
pub fn new_from_env() -> Self {
let mut config = Self::default();
if let Ok(var) = env::var("HDF5_DIR") {
if let Some(var) = env::var_os("HDF5_DIR") {
println!("Setting HDF5 root from environment variable:");
println!(" HDF5_DIR = {:?}", var);
let root = PathBuf::from(var);
Expand Down Expand Up @@ -571,6 +574,17 @@ impl Config {
}
println!("cargo:rerun-if-env-changed=HDF5_DIR");
println!("cargo:rerun-if-env-changed=HDF5_VERSION");

if cfg!(target_env = "msvc") {
println!("cargo:msvc_dll_indirection=1");
}
println!("cargo:include={}", self.inc_dir.to_str().unwrap());

println!("cargo:library=hdf5");

if feature_enabled("HL") {
println!("cargo:hl_library=hdf5_hl");
}
}

pub fn emit_cfg_flags(&self) {
Expand All @@ -580,27 +594,68 @@ impl Config {
vs.extend((0..=5).map(|v| Version::new(1, 10, v))); // 1.10.[0-5]
for v in vs.into_iter().filter(|&v| version >= v) {
println!("cargo:rustc-cfg=hdf5_{}_{}_{}", v.major, v.minor, v.micro);
println!("cargo:version_{}_{}_{}=1", v.major, v.minor, v.micro);
}
if self.header.have_stdbool_h {
println!("cargo:rustc-cfg=h5_have_stdbool_h");
println!("cargo:have_stdbool=1");
}
if self.header.have_direct {
println!("cargo:rustc-cfg=h5_have_direct");
println!("cargo:have_direct=1");
}
if self.header.have_parallel {
println!("cargo:rustc-cfg=h5_have_parallel");
println!("cargo:have_parallel=1");
}
if self.header.have_threadsafe {
println!("cargo:rustc-cfg=h5_have_threadsafe");
println!("cargo:have_threadsafe=1");
}
}
}

fn main() {
let mut searcher = LibrarySearcher::new_from_env();
searcher.try_locate_hdf5_library();
let config = searcher.finalize();
println!("{:#?}", config);
config.emit_link_flags();
if feature_enabled("STATIC") && !std::env::var_os("HDF5_DIR").is_some() {
get_build_and_emit();
} else {
let mut searcher = LibrarySearcher::new_from_env();
searcher.try_locate_hdf5_library();
let config = searcher.finalize();
println!("{:#?}", config);
config.emit_link_flags();
config.emit_cfg_flags();
}
}

fn get_build_and_emit() {
println!("cargo:rerun-if-changed=build.rs");

if feature_enabled("ZLIB") {
let zlib_lib = env::var("DEP_HDF5SRC_ZLIB").unwrap();
println!("cargo:zlib={}", &zlib_lib);
let zlib_lib_header = env::var("DEP_HDF5SRC_ZLIB").unwrap();
println!("cargo:zlib={}", &zlib_lib_header);
println!("cargo:rustc-link-lib=static={}", &zlib_lib);
}

if feature_enabled("HL") {
let hdf5_hl_lib = env::var("DEP_HDF5SRC_HL_LIBRARY").unwrap();
println!("cargo:rustc-link-lib=static={}", &hdf5_hl_lib);
println!("cargo:hl_library={}", &hdf5_hl_lib);
}

let hdf5_root = env::var("DEP_HDF5SRC_ROOT").unwrap();
println!("cargo:root={}", &hdf5_root);
let hdf5_incdir = env::var("DEP_HDF5SRC_INCLUDE").unwrap();
println!("cargo:include={}", &hdf5_incdir);
let hdf5_lib = env::var("DEP_HDF5SRC_LIBRARY").unwrap();
println!("cargo:library={}", &hdf5_lib);

println!("cargo:rustc-link-search=native={}/lib", &hdf5_root);
println!("cargo:rustc-link-lib=static={}", &hdf5_lib);

let header = Header::parse(&hdf5_incdir);
let config = Config { header, inc_dir: "".into(), link_paths: Vec::new() };
config.emit_cfg_flags();
}
4 changes: 2 additions & 2 deletions hdf5-sys/src/h5e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ extern "C" {

pub use self::globals::*;

#[cfg(not(target_env = "msvc"))]
#[cfg(not(all(target_env = "msvc", not(feature = "static"))))]
mod globals {
pub use crate::h5i::hid_t as id_t;

Expand Down Expand Up @@ -241,7 +241,7 @@ mod globals {
extern_static!(H5E_BADSIZE, H5E_BADSIZE_g);
}

#[cfg(target_env = "msvc")]
#[cfg(all(target_env = "msvc", not(feature = "static")))]
mod globals {
// dllimport hack
pub type id_t = usize;
Expand Down
8 changes: 4 additions & 4 deletions hdf5-sys/src/h5p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub type H5P_iterate_t =

pub use self::globals::*;

#[cfg(all(not(hdf5_1_8_14), not(target_env = "msvc")))]
#[cfg(all(not(hdf5_1_8_14), not(all(target_env = "msvc", not(feature = "static")))))]
mod globals {
pub use crate::h5i::hid_t as id_t;

Expand Down Expand Up @@ -85,7 +85,7 @@ mod globals {
extern_static!(H5P_LST_LINK_ACCESS, H5P_LST_LINK_ACCESS_g);
}

#[cfg(all(hdf5_1_8_14, not(target_env = "msvc")))]
#[cfg(all(hdf5_1_8_14, not(all(target_env = "msvc", not(feature = "static")))))]
mod globals {
pub use crate::h5i::hid_t as id_t;

Expand Down Expand Up @@ -125,7 +125,7 @@ mod globals {
extern_static!(H5P_LST_LINK_ACCESS, H5P_LST_LINK_ACCESS_ID_g);
}

#[cfg(all(not(hdf5_1_8_14), target_env = "msvc"))]
#[cfg(all(not(hdf5_1_8_14), all(target_env = "msvc", not(feature = "static"))))]
mod globals {
// dllimport hack
pub type id_t = usize;
Expand Down Expand Up @@ -166,7 +166,7 @@ mod globals {
extern_static!(H5P_LST_LINK_ACCESS, __imp_H5P_LST_LINK_ACCESS_g);
}

#[cfg(all(hdf5_1_8_14, target_env = "msvc"))]
#[cfg(all(hdf5_1_8_14, all(target_env = "msvc", not(feature = "static"))))]
mod globals {
// dllimport hack
pub type id_t = usize;
Expand Down
Loading

0 comments on commit ade1e18

Please sign in to comment.