axfive-libzip-sys 0.2.3

Bindgen bindings to system libzip
Documentation
use std::{env, fs::File, io::Write, path::PathBuf};

fn out_dir() -> PathBuf {
    PathBuf::from(env::var("OUT_DIR").unwrap())
}

#[cfg(feature = "build")]
fn build_libzip() {
    use std::path::Path;
    use std::process::Command;

    if !Path::new("libzip/.git").exists() {
        let _ = Command::new("git")
            .args(["submodule", "update", "--init"])
            .status();
    }

    println!("cargo:rustc-link-lib=zip");
    println!("cargo:rerun-if-changed=wrapper.h");

    if std::env::var("DOCS_RS").is_ok() {
        // Just a simple cheat to get around docs.rs not having libzip
        let mut output = File::create(out_dir().join("bindings.rs")).unwrap();
        output.write_all(include_bytes!("docs_zip.rs")).unwrap();

        return;
    }

    let mut config = cmake::Config::new("libzip");
    config.define("ENABLE_NETTLE", "OFF");
    config.define("ENABLE_GNUTLS", "OFF");
    config.define("ENABLE_MBEDTLS", "OFF");
    config.define("BUILD_TOOLS", "OFF");
    config.define("BUILD_REGRESS", "OFF");
    config.define("BUILD_EXAMPLES", "OFF");
    config.define("BUILD_DOC", "OFF");
    config.pic(true);
    config.register_dep("ssl");
    config.register_dep("crypto");
    config.register_dep("z");

    #[cfg(feature = "static")]
    {
        config.define("ENABLE_BZIP2", "OFF");
        config.define("ENABLE_LZMA", "OFF");
        config.define("ENABLE_ZSTD", "OFF");
        config.define("BUILD_SHARED_LIBS", "OFF");
        config.define("OPENSSL_ROOT_DIR", env::var("DEP_OPENSSL_ROOT").unwrap());
    }

    println!("Configuring and compiling zip");
    let dst = config.build();

    println!("cargo:rustc-link-search=native={}/lib", dst.display());

    #[cfg(feature = "static")]
    {
        println!(
            "cargo:rustc-link-search={}/lib",
            env::var("DEP_OPENSSL_ROOT").unwrap()
        );

        println!(
            "cargo:rustc-link-search={}/lib",
            env::var("DEP_Z_ROOT").unwrap()
        );

        println!("cargo:rustc-link-lib=static=ssl");
        println!("cargo:rustc-link-lib=static=crypto");

        #[cfg(all(windows, target_env = "gnu"))]
        println!("cargo:rustc-link-lib=static=zlib");

        #[cfg(not(all(windows, target_env = "gnu")))]
        println!("cargo:rustc-link-lib=static=z");

        println!("cargo:rustc-link-lib=static=zip");
    }

    #[cfg(not(feature = "static"))]
    {
        println!("cargo:rustc-link-lib=ssl");
        println!("cargo:rustc-link-lib=crypto");
        println!("cargo:rustc-link-lib=z");
        println!("cargo:rustc-link-lib=zip");
    }

    let bindings = bindgen::Builder::default()
        .clang_arg(format!("-I{}/include/", out_dir().display()))
        .clang_arg(format!("-I{}", dst.as_path().display()))
        .header("wrapper.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        .generate()
        .expect("Unable to generate bindings");

    bindings
        .write_to_file(out_dir().join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

fn pkgconfig() {
    let library = pkg_config::probe_library("libzip").unwrap();
    let bindings = bindgen::Builder::default()
        .clang_args(
            library
                .include_paths
                .iter()
                .map(|path| format!("-I{}", path.to_string_lossy())),
        )
        .header("wrapper.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        .generate()
        .expect("Unable to generate bindings");

    bindings
        .write_to_file(out_dir().join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

fn main() {
    let use_pkg_config;

    #[cfg(feature = "build")]
    {
        println!("cargo:rerun-if-env-changed=LIBZIP_SYS_USE_PKG_CONFIG");
        use_pkg_config = env::var("LIBZIP_SYS_USE_PKG_CONFIG").is_ok();
    }
    #[cfg(not(feature = "build"))]
    {
        use_pkg_config = true;
    }

    if use_pkg_config {
        #[cfg(feature = "pkg-config")]
        {
            pkgconfig()
        }
        #[cfg(not(feature = "pkg-config"))]
        {
            panic!("LIBZIP_SYS_USE_PKG_CONFIG set but pkg-config feature was disabled");
        }
    } else {
        #[cfg(feature = "build")]
        {
            build_libzip()
        }
        #[cfg(not(feature = "build"))]
        {
            panic!("axfive-libzip-sys was configured without the 'build' feature and LIBZIP_SYS_USE_PKG_CONFIG was not set");
        }
    }
}