leveldb-rs-binding 2.2.0

An interface for the LevelDB
Documentation
//! Main build script entry point.
//!
//! This file serves as the entry point for C++ dependencies building

mod boost;
mod extension;
mod leveldb;
mod linker;
mod snappy;
mod t3lru;
mod zstd;

use std::{env, path::PathBuf};

/// Directory name within `$OUT_DIR` where the static libraries should be built.
pub const LIB_DIR: &str = "lib";

/// Check if the enable_lto feature is enabled.
pub fn is_lto_enabled() -> bool {
    env::var("CARGO_FEATURE_ENABLE_LTO").is_ok()
}

/// Configure CMake settings common to all dependencies.
pub fn apply_cmake_flags(config: &mut cmake::Config) {
    #[cfg(target_env = "msvc")]
    {
        // Workaround: the cmake crate (0.1.x) hardcodes `/MD` in
        // CMAKE_CXX_FLAGS for all configs.  Projects with CMP0091=NEW
        // (cmake_minimum_required >= 3.15) override this via
        // CMAKE_MSVC_RUNTIME_LIBRARY, but projects with CMP0091=OLD
        // don't — causing Debug/Release runtime mismatches between
        // dependencies (e.g. snappy vs leveldb).
        //
        // Rust always links the Release CRT (msvcrt.lib) on MSVC, even
        // in debug builds, so MultiThreadedDLL is always correct here.
        //
        // Remove this block when the cmake crate stops injecting `/MD`
        // into CMAKE_CXX_FLAGS and instead delegates to
        // CMAKE_MSVC_RUNTIME_LIBRARY natively.
        config
            .define("CMAKE_POLICY_DEFAULT_CMP0091", "NEW")
            .define("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreadedDLL");
    }
    // Apply LTO compiler flags if enabled.
    if is_lto_enabled() {
        println!("[build] LTO optimization enabled");
        config
            .cxxflag("-flto")
            .cxxflag("-ffat-lto-objects")
            .cflag("-flto");
    } else {
        println!("[build] LTO optimization disabled");
    }
}
#[cfg(feature = "experimental-extension")]
pub const CXX_STANDARD: &str = "20";
#[cfg(not(feature = "experimental-extension"))]
pub const CXX_STANDARD: &str = "17";
pub const C_STANDARD: &str = "11";

/// Initialize build environment and return the library installation directory.
fn get_install_dir() -> PathBuf {
    let outdir = env::var("OUT_DIR").unwrap();
    std::path::Path::new(&outdir).join(LIB_DIR)
}

fn set_cmake_env() {
    unsafe {
        env::set_var("CMAKE_BUILD_PARALLEL_LEVEL", num_cpus::get().to_string());
    }
}

fn determine_build_type() -> &'static str {
    match env::var("PROFILE")
        .iter()
        .find(|s| s.eq_ignore_ascii_case("release"))
    {
        Some(_) => "Release",
        None => "Debug",
    }
}

fn main() {
    println!("[build] Started");
    set_cmake_env();
    let build_type = determine_build_type();

    let install_dir = get_install_dir();
    println!("cargo:rustc-link-search=native={}", &install_dir.display());

    #[cfg(feature = "snappy")]
    let snappy_prefix = Some(snappy::build(&install_dir, build_type));
    #[cfg(not(feature = "snappy"))]
    let snappy_prefix: Option<std::path::PathBuf> = None;

    #[cfg(feature = "zstd")]
    let zstd_prefix = Some(zstd::build(&install_dir, build_type));
    #[cfg(not(feature = "zstd"))]
    let zstd_prefix: Option<std::path::PathBuf> = None;

    #[allow(unused)]
    let leveldb_prefix = leveldb::build(&install_dir, build_type, snappy_prefix, zstd_prefix);

    #[cfg(feature = "experimental-extension")]
    let t3lru_build = Some(t3lru::build(build_type));

    #[cfg(feature = "experimental-extension")]
    let boost_build = Some(boost::build());

    #[cfg(feature = "experimental-extension")]
    extension::build(
        &install_dir,
        build_type,
        &leveldb_prefix,
        t3lru_build.as_ref(),
        boost_build.as_ref(),
    );

    linker::configure();
    println!("[build] Finished");
}