diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-08-04 21:14:59 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-04 21:14:59 +0000 |
commit | 7da80fa5a5bc824ec7b2885167adf3c511e1ac52 (patch) | |
tree | e7cca01221d94bd0a452f50653be67a6e729c2ae | |
parent | 510241689fb8b2acdf4e2cc13edbd32deb2252aa (diff) | |
parent | b2d69e85634fa536f2f21e2e3ed21407e5b10c7e (diff) | |
download | rust-libzfs-7da80fa5a5bc824ec7b2885167adf3c511e1ac52.zip |
Merge #67
67: fix crosscompilations and support macos with zfs 2.0.1 r=jmesmon a=jmesmon
Co-authored-by: Cody P Schafer <dev@codyps.com>
-rw-r--r-- | .github/workflows/mac.yml | 41 | ||||
-rw-r--r-- | Cargo.lock | 87 | ||||
-rw-r--r-- | nvpair-sys/build.rs | 16 | ||||
-rwxr-xr-x | nvpair-sys/generate-bindings | 22 | ||||
-rw-r--r-- | nvpair-sys/src/bindings.rs | 7 | ||||
-rw-r--r-- | zfs-core-sys/Cargo.toml | 2 | ||||
-rw-r--r-- | zfs-core-sys/build.rs | 116 | ||||
-rw-r--r-- | zfs-core/tests/basic.rs | 14 |
8 files changed, 245 insertions, 60 deletions
diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml new file mode 100644 index 0000000..d6a2fa7 --- /dev/null +++ b/.github/workflows/mac.yml @@ -0,0 +1,41 @@ +on: + push: + branches-ignore: + - '**.tmp' + +name: mac +jobs: + mac: + runs-on: macos-10.15 + strategy: + matrix: + rust: + - stable + - beta + - nightly + - 1.48.0 + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v1 + + - name: Download openzfs-on-osx + run: curl -o zfs.pkg https://openzfsonosx.org/forum/download/file.php?id=309&sid=f486243ccdc8e8e13894f14ce0b28d93 + + - name: Install openzfs-on-osx + run: sudo installer -verbose -pkg zfs.pkg -target / + + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --all-targets --all + + @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "bitflags" version = "1.2.1" @@ -7,6 +9,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] +name = "build-env" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1522ac6ee801a11bf9ef3f80403f4ede6eb41291fac3dde3de09989679305f25" + +[[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -63,37 +71,37 @@ checksum = "7684cf33bb7f28497939e8c7cf17e3e4e3b8d9a0080ffa4f8ae2f515442ee855" [[package]] name = "getrandom" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.1+wasi-snapshot-preview1", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] name = "libc" -version = "0.2.88" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "nvpair" @@ -132,18 +140,18 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] @@ -154,7 +162,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.15", + "getrandom 0.1.16", "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", @@ -163,14 +171,14 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c24fcd450d3fa2b592732565aa4f17a27a61c65ece4726353e000939b0edee34" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.0", - "rand_core 0.6.1", - "rand_hc 0.3.0", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", ] [[package]] @@ -185,12 +193,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.1", + "rand_core 0.6.3", ] [[package]] @@ -199,16 +207,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.15", + "getrandom 0.1.16", ] [[package]] name = "rand_core" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.1", + "getrandom 0.2.3", ] [[package]] @@ -222,18 +230,18 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.6.1", + "rand_core 0.6.3", ] [[package]] name = "redox_syscall" -version = "0.2.4" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] @@ -270,9 +278,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.54" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" dependencies = [ "proc-macro2", "quote", @@ -287,7 +295,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if 1.0.0", "libc", - "rand 0.8.1", + "rand 0.8.4", "redox_syscall", "remove_dir_all", "winapi", @@ -295,9 +303,9 @@ dependencies = [ [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "wasi" @@ -307,9 +315,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.1+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c6c3420963c5c64bca373b25e77acb562081b9bb4dd5bb864187742186cea9" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "winapi" @@ -352,6 +360,7 @@ dependencies = [ name = "zfs-core-sys" version = "0.5.0" dependencies = [ + "build-env", "libc", "nvpair-sys", "pkg-config", diff --git a/nvpair-sys/build.rs b/nvpair-sys/build.rs index 885fe37..0b2b1f9 100644 --- a/nvpair-sys/build.rs +++ b/nvpair-sys/build.rs @@ -1,10 +1,24 @@ +fn var(s: &str) -> Result<String, std::env::VarError> { + println!("cargo:rerun-if-env-changed={}", s); + std::env::var(s) +} + fn main() { + let target_os = var("CARGO_CFG_TARGET_OS").expect("Could not get env var CARGO_CFG_TARGET_OS"); + + // when using "openzfs on macos", zfs libs are installed outside the default link path. Add it + // in + // TODO: Provide a way to disable + if target_os == "macos" { + println!("cargo:rustc-link-search=native=/usr/local/zfs/lib"); + } + println!("cargo:rustc-link-lib=nvpair"); // FIXME: a bug exists in some versions of libnvpair causing it to depend on a symbol called // `aok`, which is in `libzfs`. println!("cargo:rustc-link-lib=zfs"); // nvpair uses functions from libspl on FreeBSD - if cfg!(target_os = "freebsd") { + if target_os == "freebsd" { println!("cargo:rustc-link-lib=spl"); }; } diff --git a/nvpair-sys/generate-bindings b/nvpair-sys/generate-bindings index 6b73490..611ca72 100755 --- a/nvpair-sys/generate-bindings +++ b/nvpair-sys/generate-bindings @@ -1,4 +1,17 @@ #!/bin/sh + +os=$(uname -s) +case "$os" in +Darwin) + export PKG_CONFIG_PATH=/usr/local/zfs/lib/pkgconfig + sdkpath="$(xcrun --sdk macosx --show-sdk-path)" + CFLAGS=(-I "$sdkpath/usr/include/") + ;; +*) + CFLAGS=() + ;; +esac + d=$(dirname $0) bindgen "$d/wrapper.h" \ -o "$d/src/bindings.rs" \ @@ -13,10 +26,15 @@ bindgen "$d/wrapper.h" \ --whitelist-type 'nvlist.*' \ --whitelist-type 'hrtime.*' \ --whitelist-type 'data_type_.*' \ - --whitelist-type 'size_t' \ --constified-enum-module '.*' \ --blacklist-type 'va_list' \ --blacklist-type '_IO_FILE' \ --blacklist-type 'FILE' \ --no-recursive-whitelist \ - -- `pkg-config libzfs_core --cflags` + --raw-line \ +' +// workaround for https://github.com/rust-lang/rust-bindgen/issues/1651 +#[allow(unknown_lints)] +#[allow(deref_nullptr)] +pub type size_t = ::std::os::raw::c_ulong;' \ + -- `pkg-config libzfs_core --cflags` "${CFLAGS[@]}" diff --git a/nvpair-sys/src/bindings.rs b/nvpair-sys/src/bindings.rs index 2c84193..d8ce9c3 100644 --- a/nvpair-sys/src/bindings.rs +++ b/nvpair-sys/src/bindings.rs @@ -1,6 +1,11 @@ -/* automatically generated by rust-bindgen 0.55.1 */ +/* automatically generated by rust-bindgen 0.59.1 */ + +// workaround for https://github.com/rust-lang/rust-bindgen/issues/1651 +#[allow(unknown_lints)] +#[allow(deref_nullptr)] pub type size_t = ::std::os::raw::c_ulong; + pub mod boolean_t { pub type Type = ::std::os::raw::c_uint; pub const B_FALSE: Type = 0; diff --git a/zfs-core-sys/Cargo.toml b/zfs-core-sys/Cargo.toml index edbf50a..920e50f 100644 --- a/zfs-core-sys/Cargo.toml +++ b/zfs-core-sys/Cargo.toml @@ -11,7 +11,7 @@ edition = "2018" [build-dependencies] pkg-config = "0.3" -#bindgen = "0.30" +build-env = "0.3" [dependencies] libc = "0.2" diff --git a/zfs-core-sys/build.rs b/zfs-core-sys/build.rs index e745be2..3b80d27 100644 --- a/zfs-core-sys/build.rs +++ b/zfs-core-sys/build.rs @@ -1,14 +1,118 @@ -extern crate pkg_config; +use std::{ffi::OsStr, path::PathBuf, str::FromStr}; + +fn var(s: &str) -> Result<String, std::env::VarError> { + println!("cargo:rerun-if-env-changed={}", s); + std::env::var(s) +} + +#[derive(Debug)] +enum Lookup { + PkgConfig, + Link, +} + +#[derive(Debug)] +struct LookupParseErr; + +impl FromStr for Lookup { + type Err = LookupParseErr; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "pkg-config" => Ok(Lookup::PkgConfig), + "link" => Ok(Lookup::Link), + _ => Err(LookupParseErr), + } + } +} + +fn env_var_append<V: AsRef<OsStr>>(key: &str, value: V) { + let value = value.as_ref(); + let mut v = if let Some(v) = std::env::var_os(value) { + v + } else { + std::env::set_var(key, value); + return; + }; + + if v.is_empty() { + std::env::set_var(key, value); + return; + } + + v.push(":"); + v.push(value); + std::env::set_var(key, v); +} fn main() { - if cfg!(target_os = "freebsd") || cfg!(target_os = "macos") { - println!("cargo:rustc-link-lib=zfs_core"); + // openzfs on osx: fixed paths, under /usr/local/zfs (has pkg-config for libzfs_core) + + let target_os = var("CARGO_CFG_TARGET_OS").expect("Could not get env var CARGO_CFG_TARGET_OS"); + let mut build_env = build_env::BuildEnv::from_env().expect("Could not determine build_env"); + + let lzc_libdir = build_env.var("LIBZFS_CORE_LIBDIR"); + let lzc_lookup = if lzc_libdir.as_ref().is_some() { + // Implies users want `LIBZFS_CORE_LOOKUP_WITH=link` + Lookup::Link } else { - pkg_config::probe_library("libzfs_core").unwrap(); + let lookup_with = build_env.var("LIBZFS_CORE_LOOKUP_WITH"); + let lookup_with: Option<Lookup> = lookup_with.map(|v| v.to_str().unwrap().parse().unwrap()); + + lookup_with.unwrap_or_else(|| match target_os.as_str() { + // users have reported that this is required for freebsd. I have not tested it. + "freebsd" => Lookup::Link, + + // openzfs on osx has the `libzfs_core.pc` file, installed into + // `/usr/local/zfs/lib/pkgconfig`. Users _must_ ensure this is part of their + // `PKG_CONFIG_PATH`. Note that when cross compiling, this may cause some difficulty, + // because the `pkg-config` crate doesn't allow distinguishing right now. We could + // workaround this by hacking up std::env ourselves, or ideally the pkg-config crate would + // use a build-env style lookup to pick the right `PKG_CONFIG_PATH` itself. + // + // Right now, if the link method is _not_ supplied, we tweak PKG_CONFIG_PATH so things + // will automatically work in the common case (with openzfs on osx 2.01 at least) + // + // This will almost certainly behave poorly in the case of cross compilation, where + // users should probably specify a `LIBZFS_CORE_LOOKUP_WITH` explicitly. + "macos" => { + let pc_path = PathBuf::from_str("/usr/local/zfs/lib/pkgconfig").unwrap(); + if pc_path.exists() { + env_var_append("PKG_CONFIG_PATH", pc_path); + } + Lookup::PkgConfig + } + // + // zfs on linux: use pkg-config for libzfs_core (no pc for nvpair) + // default to true otherwise. + _ => Lookup::PkgConfig, + }) + }; + + match lzc_lookup { + Lookup::PkgConfig => { + pkg_config::probe_library("libzfs_core").unwrap(); + } + Lookup::Link => { + if let Some(v) = lzc_libdir { + println!("cargo:rustc-link-search=native={}", v.to_str().unwrap()); + } + println!("cargo:rustc-link-lib=native=zfs_core"); + } } + // FIXME: we don't provide a way to specify the search path for nvpair. One can add search + // paths with RUSTFLAGS or some cargo.toml build target hacking. Consider if we should either + // rely on that mechanism entirely (even for libzfs_core), or add a LIB_DIR env var for + // nvpair/zutil/etc + // + // there is currently no nvpair pkg-config, so unconditionally link + if target_os == "macos" { + // TODO: this is an openzfs on osx specific path. Provide a way to disable + println!("cargo:rustc-link-search=native=/usr/local/zfs/lib"); + } println!("cargo:rustc-link-lib=nvpair"); - if cfg!(target_os = "freebsd") { + if target_os == "freebsd" { println!("cargo:rustc-link-lib=dylib:-as-needed=zutil"); - }; + } } diff --git a/zfs-core/tests/basic.rs b/zfs-core/tests/basic.rs index 8154d22..d403a09 100644 --- a/zfs-core/tests/basic.rs +++ b/zfs-core/tests/basic.rs @@ -316,13 +316,11 @@ fn hold_not_snap() { // variant. This might be a bug in our code, or some change in how lzc handles errors for // single results match e { - // zfs 2.0.0 on linux: - #[cfg(target_os = "linux")] + // openzfs 2.0.0: zfs_core::Error::Io { source: e } => { assert_eq!(e.kind(), io::ErrorKind::InvalidInput); } - // zfs 1.9.4 on macos: - #[cfg(target_os = "macos")] + // openzfs 1.9.4: zfs_core::Error::List { source: el } => { let mut hm = std::collections::HashMap::new(); hm.insert(tmpfs.path().to_owned() + "/2", io::ErrorKind::InvalidInput); @@ -336,10 +334,6 @@ fn hold_not_snap() { } } } - - _ => { - panic!("unexpected error kind: {:?}", e); - } } } @@ -364,13 +358,14 @@ fn hold_not_exist() { e } else { // macos hits this for some reason + /* #[cfg(target_os = "macos")] { eprintln!("macos zfs 1.9.4 is for some reason totally cool with creating holds on non-existent snaps"); return; } + */ - #[cfg(not(target_os = "macos"))] panic!("expected an error, got {:?}", e); }; @@ -379,7 +374,6 @@ fn hold_not_exist() { // linux (zfs 2.0.0) doesn't appear to return our error list, which is also concerning match e { // zfs 2.0.0 on linux: - #[cfg(target_os = "linux")] zfs_core::Error::Io { source: e } => { assert_eq!(e.kind(), io::ErrorKind::NotFound); } |