diff --git a/.travis.yml b/.travis.yml index 238d0fc..59a9886 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: rust -dist: trusty sudo: false cache: cargo @@ -22,10 +21,24 @@ before_script: - rustup toolchain install nightly-2019-09-11 - rustup component add rustfmt --toolchain nightly-2019-09-11 - rustup component add clippy --toolchain nightly-2019-09-11 + # Use official clang in order to test out libfuzzer on osx. + - if [[ "$TRAVIS_OS_NAME" = "osx" ]]; then + brew update; + brew install llvm; + export PATH="/usr/local/opt/llvm/bin:$PATH"; + export LDFLAGS="-L/usr/local/opt/llvm/lib"; + export CPPFLAGS="-I/usr/local/opt/llvm/include"; + fi script: - cargo +nightly-2019-09-11 fmt --all -- --check - cargo +nightly-2019-09-11 clippy --all-features -- -D warnings -A clippy::match-ref-pats -A clippy::needless-lifetimes + - cargo build --features with-clang --verbose + - cargo build --features with-asan --verbose + - cargo build --features with-fuzzer --verbose + - cargo build --features with-fuzzer-no-link --verbose + - cargo build --features with-asan,with-fuzzer --verbose + - cargo build --features with-asan,with-fuzzer-no-link --verbose - cargo build --verbose - export RUST_BACKTRACE=1 - cargo test --all --verbose diff --git a/Cargo.toml b/Cargo.toml index db5ccad..c5591f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,3 +50,10 @@ lmdb-rkv-sys = { path = "./lmdb-sys" } [dev-dependencies] rand = "0.4.6" tempdir = "0.3.7" + +[features] +default = [] +with-clang = ["lmdb-rkv-sys/with-clang"] +with-asan = ["lmdb-rkv-sys/with-asan"] +with-fuzzer = ["lmdb-rkv-sys/with-fuzzer"] +with-fuzzer-no-link = ["lmdb-rkv-sys/with-fuzzer-no-link"] diff --git a/lmdb-sys/Cargo.toml b/lmdb-sys/Cargo.toml index 946b7a1..d3477ae 100644 --- a/lmdb-sys/Cargo.toml +++ b/lmdb-sys/Cargo.toml @@ -33,6 +33,10 @@ bindgen = "0.51.0" [features] default = [] +with-clang = [] +with-asan = ["with-clang"] +with-fuzzer = ["with-clang"] +with-fuzzer-no-link = ["with-clang"] # These features configure the MDB_IDL_LOGN macro, which determines # the size of the free and dirty page lists (and thus the amount of memory diff --git a/lmdb-sys/build.rs b/lmdb-sys/build.rs index 3caeb24..75737fe 100644 --- a/lmdb-sys/build.rs +++ b/lmdb-sys/build.rs @@ -32,21 +32,49 @@ const MDB_IDL_LOGN: u8 = 15; )))] const MDB_IDL_LOGN: u8 = 16; +macro_rules! warn { + ($message:expr) => { + println!("cargo:warning={}", $message); + }; +} + fn main() { let mut lmdb = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()); lmdb.push("lmdb"); lmdb.push("libraries"); lmdb.push("liblmdb"); + if cfg!(feature = "with-fuzzer") && cfg!(feature = "with-fuzzer-no-link") { + warn!("Features `with-fuzzer` and `with-fuzzer-no-link` are mutually exclusive."); + warn!("Building with `-fsanitize=fuzzer`."); + } + if !pkg_config::find_library("liblmdb").is_ok() { - cc::Build::new() + let mut builder = cc::Build::new(); + + builder .define("MDB_IDL_LOGN", Some(MDB_IDL_LOGN.to_string().as_str())) .file(lmdb.join("mdb.c")) .file(lmdb.join("midl.c")) // https://github.com/mozilla/lmdb/blob/b7df2cac50fb41e8bd16aab4cc5fd167be9e032a/libraries/liblmdb/Makefile#L23 .flag_if_supported("-Wno-unused-parameter") .flag_if_supported("-Wbad-function-cast") - .flag_if_supported("-Wuninitialized") - .compile("liblmdb.a") + .flag_if_supported("-Wuninitialized"); + + if env::var("CARGO_FEATURE_WITH_CLANG").is_ok() { + builder.compiler("clang"); + } + + if env::var("CARGO_FEATURE_WITH_ASAN").is_ok() { + builder.flag("-fsanitize=address"); + } + + if env::var("CARGO_FEATURE_WITH_FUZZER").is_ok() { + builder.flag("-fsanitize=fuzzer"); + } else if env::var("CARGO_FEATURE_WITH_FUZZER_NO_LINK").is_ok() { + builder.flag("-fsanitize=fuzzer-no-link"); + } + + builder.compile("liblmdb.a") } }