Repository: libsql/libsql
File: libsql-ffi/build.rs (Rust)

Code before:
    println!("cargo:rerun-if-env-changed=SQLITE_MAX_EXPR_DEPTH");

    if let Ok(limit) = env::var("SQLITE_MAX_COLUMN") {
        cfg.flag(&format!("-DSQLITE_MAX_COLUMN={limit}"));
    }
    println!("cargo:rerun-if-env-changed=SQLITE_MAX_COLUMN");

    if let Ok(extras) = env::var("LIBSQLITE3_FLAGS") {
        for extra in extras.split_whitespace() {
            if extra.starts_with("-D") || extra.starts_with("-U") {
                cfg.flag(extra);
            } else if extra.starts_with("SQLITE_") {
                cfg.flag(&format!("-D{extra}"));
            } else {
                panic!("Don't understand {} in LIBSQLITE3_FLAGS", extra);
            }
        }
    }
    println!("cargo:rerun-if-env-changed=LIBSQLITE3_FLAGS");

    cfg.compile(LIB_NAME);

    println!("cargo:lib_dir={out_dir}");
}

fn copy_multiple_ciphers(out_dir: &str) {
    std::fs::copy(
        format!("{BUNDLED_DIR}/SQLite3MultipleCiphers/build/libsqlite3mc_static.a"),
        format!("{out_dir}/libsqlite3mc.a"),
    )
    .unwrap();
    println!("cargo:rustc-link-lib=static=sqlite3mc");
    println!("cargo:rustc-link-search={out_dir}");
}

fn build_multiple_ciphers(out_path: &Path) {
    let bindgen_rs_path = if cfg!(feature = "session") {
        "bundled/bindings/session_bindgen.rs"
    } else {
        "bundled/bindings/bindgen.rs"
    };
    if std::env::var("LIBSQL_DEV").is_ok() {
        let header = HeaderLocation::FromPath(format!("{BUNDLED_DIR}/src/sqlite3.h"));
        bindings::write_to_out_dir(header, bindgen_rs_path.as_ref());
    }
    let dir = env!("CARGO_MANIFEST_DIR");
    std::fs::copy(format!("{dir}/{bindgen_rs_path}"), out_path).unwrap();

    std::fs::copy(
        (BUNDLED_DIR.as_ref() as &Path)
            .join("src")

Review comment (suggestion):
We need to separate the code that copies the needed linkable files into the out dir and the code that actually builds it. We originally had a cyclic issue where we were building code that then was placed right back into the bundled folder, which caused the build script to re-run and execute the same build. This cuts down recompiles from 45s to 0.14s.

Code after:
        cfg.flag("-DSQLITE_ENABLE_PREUPDATE_HOOK");
    }
    if cfg!(feature = "session") {
        cfg.flag("-DSQLITE_ENABLE_SESSION");
    }

    if let Ok(limit) = env::var("SQLITE_MAX_VARIABLE_NUMBER") {
        cfg.flag(&format!("-DSQLITE_MAX_VARIABLE_NUMBER={limit}"));
    }
    println!("cargo:rerun-if-env-changed=SQLITE_MAX_VARIABLE_NUMBER");

    if let Ok(limit) = env::var("SQLITE_MAX_EXPR_DEPTH") {
        cfg.flag(&format!("-DSQLITE_MAX_EXPR_DEPTH={limit}"));
    }
    println!("cargo:rerun-if-env-changed=SQLITE_MAX_EXPR_DEPTH");

    if let Ok(limit) = env::var("SQLITE_MAX_COLUMN") {
        cfg.flag(&format!("-DSQLITE_MAX_COLUMN={limit}"));
    }
    println!("cargo:rerun-if-env-changed=SQLITE_MAX_COLUMN");

    if let Ok(extras) = env::var("LIBSQLITE3_FLAGS") {
        for extra in extras.split_whitespace() {
            if extra.starts_with("-D") || extra.starts_with("-U") {
                cfg.flag(extra);
            } else if extra.starts_with("SQLITE_") {
                cfg.flag(&format!("-D{extra}"));
            } else {
                panic!("Don't understand {} in LIBSQLITE3_FLAGS", extra);
            }
        }
    }
    println!("cargo:rerun-if-env-changed=LIBSQLITE3_FLAGS");

    cfg.compile(LIB_NAME);

    println!("cargo:lib_dir={out_dir}");
}

fn copy_multiple_ciphers(out_dir: &str, out_path: &Path) {
    let dylib = format!("{BUNDLED_DIR}/SQLite3MultipleCiphers/build/libsqlite3mc_static.a");
    if !Path::new(&dylib).exists() {
        build_multiple_ciphers(&out_path);
    }

    std::fs::copy(dylib, format!("{out_dir}/libsqlite3mc.a")).unwrap();
    println!("cargo:rustc-link-lib=static=sqlite3mc");
    println!("cargo:rustc-link-search={out_dir}");
}

fn build_multiple_ciphers(out_path: &Path) {