overdrive-db 1.4.2

OverDrive-DB — Embeddable hybrid SQL+NoSQL database. Like SQLite for JSON. #OverDriveDB #AFOT
Documentation
// build.rs — OverDrive InCode SDK (Rust)
//
// This build script:
// 1. Emits linker search paths so the native library is found at link time
//    when building from source (not needed for crates.io users).
// 2. Copies the native library from lib/ to the output directory so it is
//    found at runtime next to the compiled binary.
// 3. Emits cargo:rustc-link-search so `cargo test` and `cargo run` work
//    without manual PATH setup.

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

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=lib/");

    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap_or_default();
    let lib_dir = Path::new(&manifest_dir).join("lib");
    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap_or_default());

    // Determine the native library name for this platform
    let (lib_file, link_name) = if cfg!(target_os = "windows") {
        ("overdrive.dll", "overdrive")
    } else if cfg!(target_os = "macos") {
        ("liboverdrive.dylib", "overdrive")
    } else {
        ("liboverdrive.so", "overdrive")
    };

    // If lib/ directory exists and contains the native library, emit linker paths
    let lib_path = lib_dir.join(lib_file);
    if lib_dir.exists() {
        println!("cargo:rustc-link-search=native={}", lib_dir.display());
        println!("cargo:rustc-link-lib=dylib={}", link_name);
    }

    // Copy the native library to the output directory so it's found at runtime
    // This helps `cargo run` and `cargo test` work without manual setup
    if lib_path.exists() {
        // Copy to OUT_DIR/../../../ (the target/debug or target/release directory)
        // Walk up from OUT_DIR (which is target/{profile}/build/{pkg}/out)
        let mut target_dir = out_dir.clone();
        for _ in 0..3 {
            target_dir = match target_dir.parent() {
                Some(p) => p.to_path_buf(),
                None => break,
            };
        }

        let dest = target_dir.join(lib_file);
        if !dest.exists() {
            if let Err(e) = std::fs::copy(&lib_path, &dest) {
                eprintln!(
                    "cargo:warning=Could not copy {} to {}: {}",
                    lib_path.display(),
                    dest.display(),
                    e
                );
            } else {
                eprintln!(
                    "cargo:warning=Copied {} to {}",
                    lib_file,
                    dest.display()
                );
            }
        }
    } else {
        // Native library not found in lib/ — emit a helpful warning
        eprintln!(
            "cargo:warning=OverDrive native library not found at {}",
            lib_path.display()
        );
        eprintln!(
            "cargo:warning=Download {} from: https://github.com/ALL-FOR-ONE-TECH/OverDrive-DB_IncodeSDK/releases/latest",
            lib_file
        );
        eprintln!(
            "cargo:warning=Place it in the lib/ directory next to Cargo.toml"
        );
    }

    // cbindgen — generate C header from Rust FFI (optional, only if cbindgen is available)
    #[cfg(feature = "generate-header")]
    {
        let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
        cbindgen::Builder::new()
            .with_crate(crate_dir)
            .with_config(cbindgen::Config::from_file("cbindgen.toml").unwrap_or_default())
            .generate()
            .expect("Unable to generate C bindings")
            .write_to_file("c/include/overdrive.h");
    }
}