diff --git a/libzfs-sys/build.rs b/libzfs-sys/build.rs index 81834f1..8fec2f1 100644 --- a/libzfs-sys/build.rs +++ b/libzfs-sys/build.rs @@ -6,18 +6,19 @@ extern crate bindgen; extern crate pkg_config; use std::env; +use std::io::{BufRead, BufReader}; +use std::path::PathBuf; +use std::process::{Command, Stdio}; fn main() { let out_file = env::current_dir().unwrap().join("src").join("bindings.rs"); - env::set_var("LIBCLANG_PATH", "/opt/llvm-5.0.0/lib64/"); - - pkg_config::Config::new().probe("libzfs").unwrap(); - println!("cargo:rustc-link-lib=zpool"); + // necessary for CI machines to find their libclang install + env::set_var("LIBCLANG_PATH", "/opt/llvm-5.0.0/lib64"); let bindings = bindgen::Builder::default() .header("wrapper.h") - .constified_enum_module("boolean") + .constified_enum_module("boolean_t") .whitelist_var("vdev_stat_t") .whitelist_type("vdev_stat_t") .whitelist_var("ZPOOL_MAXPROPLEN") @@ -61,8 +62,6 @@ fn main() { .blacklist_type("nvlist") .whitelist_function("libzfs_init") .whitelist_function("libzfs_fini") - .whitelist_function("thread_init") - .whitelist_function("thread_fini") .whitelist_function("zpool_import") .whitelist_function("zpool_export") .whitelist_function("zpool_find_import") @@ -91,15 +90,55 @@ fn main() { .whitelist_function("zfs_expand_proplist") .whitelist_function("zfs_prop_to_name") .whitelist_function("zfs_validate_name") - .whitelist_function("zprop_free_list") - .clang_arg("-I/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/") - .clang_arg("-I/usr/src/zfs-0.7.9/lib/libspl/include/") - .clang_arg("-I/usr/src/zfs-0.7.9/include/") - .generate() - .expect("Unable to generate bindings"); + .whitelist_function("zprop_free_list"); + + let bindings = if cfg!(target_os = "freebsd") { + println!("cargo:rustc-link-lib=zfs"); + // a subset of include paths in cddl/sbin/zfs/Makefile + bindings + .clang_arg("-I/usr/src/cddl/compat/opensolaris/include") + .clang_arg("-I/usr/src/cddl/compat/opensolaris/lib/libumem") + .clang_arg("-I/usr/src/cddl/contrib/opensolaris/head") + .clang_arg("-I/usr/src/cddl/contrib/opensolaris/lib/libuutil/common") + .clang_arg("-I/usr/src/cddl/contrib/opensolaris/lib/libzfs/common") + .clang_arg("-I/usr/src/cddl/contrib/opensolaris/lib/libzpool/common") + .clang_arg("-I/usr/src/sys/cddl/compat/opensolaris") + .clang_arg("-I/usr/src/sys/cddl/contrib/opensolaris/uts/common") + .clang_arg("-I/usr/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs") + .clang_arg("-I/usr/src/sys/cddl/contrib/opensolaris/common/zfs") + } else { + let libzfs = pkg_config::Config::new().probe("libzfs").unwrap(); + list_gcc_include_paths() + .chain(libzfs.include_paths) + .fold(bindings, |bindings, include_path| { + let flag = format!("-I{}", include_path.to_string_lossy()); + bindings.clang_arg(flag) + }) + // include directory for zfsonlinux/zfs master branch + .clang_arg("-I/usr/src/zfs-0.7.0/include") + }; + + let bindings = bindings.generate().expect("Unable to generate bindings"); + + println!("cargo:rustc-link-lib=zpool"); // Write bindings to src. bindings .write_to_file(out_file) .expect("Couldn't write bindings!"); } + +fn list_gcc_include_paths() -> impl Iterator { + let script_path = "./list_gcc_include_paths.sh"; + let child = Command::new(script_path) + .stdout(Stdio::piped()) + .spawn() + .expect(&format!("Unable to spawn {}", script_path)); + + match child.stdout { + Some(stdout) => + BufReader::new(stdout).lines() + .map(|line| PathBuf::from(line.unwrap())), + None => panic!("Couldn't read from {}", script_path), + } +} diff --git a/libzfs-sys/list_gcc_include_paths.sh b/libzfs-sys/list_gcc_include_paths.sh new file mode 100755 index 0000000..67579e9 --- /dev/null +++ b/libzfs-sys/list_gcc_include_paths.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +gcc -Wp,-v -x c - -fsyntax-only < /dev/null 2>&1 | grep '^ ' | sed -e 's/^ //' diff --git a/libzfs-sys/wrapper.h b/libzfs-sys/wrapper.h index 8b5c3c7..41e46f1 100644 --- a/libzfs-sys/wrapper.h +++ b/libzfs-sys/wrapper.h @@ -4,4 +4,6 @@ #define _LARGEFILE64_SOURCE +#define NEED_SOLARIS_BOOLEAN + #include diff --git a/libzfs/src/libzfs.rs b/libzfs/src/libzfs.rs index 6952b3b..57d5390 100644 --- a/libzfs/src/libzfs.rs +++ b/libzfs/src/libzfs.rs @@ -60,9 +60,7 @@ impl Libzfs { pub fn find_importable_pools(&mut self) -> nvpair::NvList { let _l = LOCK.lock().unwrap(); unsafe { - sys::thread_init(); let x = sys::zpool_find_import(self.raw, 0, ptr::null_mut()); - sys::thread_fini(); nvpair::NvList::from_ptr(x) } diff --git a/libzfs/src/zfs.rs b/libzfs/src/zfs.rs index 80d46d5..d8c59fb 100644 --- a/libzfs/src/zfs.rs +++ b/libzfs/src/zfs.rs @@ -47,8 +47,8 @@ impl Zfs { sys::zfs_expand_proplist( self.raw, &mut prop_list_ptr, - sys::boolean::B_TRUE, - sys::boolean::B_TRUE, + sys::boolean_t::B_TRUE, + sys::boolean_t::B_TRUE, ) }; @@ -62,7 +62,7 @@ impl Zfs { let pl = self.prop_list()?; let xs = pl.filter_map(|x: ZpropItem| match x.prop() { - sys::zfs_prop_t_ZFS_PROP_BAD => self.user_props() + sys::zfs_prop_t_ZPROP_INVAL => self.user_props() .lookup_nv_list(x.user_prop()) .and_then(|nv| nv.lookup_string(sys::zprop_value())) .map(|v| ZProp { @@ -82,7 +82,7 @@ impl Zfs { ptr::null_mut(), ptr::null_mut(), 0, - sys::boolean::B_TRUE, + sys::boolean_t::B_TRUE, ) }; diff --git a/libzfs/src/zpool.rs b/libzfs/src/zpool.rs index fd32106..65977d8 100644 --- a/libzfs/src/zpool.rs +++ b/libzfs/src/zpool.rs @@ -56,7 +56,7 @@ impl Zpool { raw, sys::ZPOOL_MAXPROPLEN as usize, ptr::null_mut(), - sys::boolean::B_FALSE, + sys::boolean_t::B_FALSE, ); let out = CString::from_raw(raw); @@ -141,7 +141,7 @@ impl Zpool { } } pub fn disable_datasets(&self) -> Result<()> { - let code = unsafe { sys::zpool_disable_datasets(self.raw, sys::boolean::B_FALSE) }; + let code = unsafe { sys::zpool_disable_datasets(self.raw, sys::boolean_t::B_FALSE) }; match code { 0 => Ok(()), @@ -149,7 +149,7 @@ impl Zpool { } } pub fn export(&self) -> Result<()> { - let code = unsafe { sys::zpool_export(self.raw, sys::boolean::B_FALSE, ptr::null_mut()) }; + let code = unsafe { sys::zpool_export(self.raw, sys::boolean_t::B_FALSE, ptr::null_mut()) }; match code { 0 => Ok(()),