Newer
Older
TelosDB / src-tauri / build.rs
fn main() {
    tauri_build::build();

    // Allow skipping DLL copy in userland/dev environments where copying may require elevated permissions.
    if std::env::var("SKIP_DLL_COPY").is_ok() {
        println!("cargo:warning=[DLL-COPY] SKIP_DLL_COPY set; skipping DLL copy steps.");
        return;
    }

    // MinGW-free DLL handling: Copy vec0.dll from node_modules
    let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set");
    let out_path = std::path::Path::new(&out_dir);

    // Find the target directory (debug or release)
    // Traverse up until we find "debug" or "release" directory that is a direct child of "target"
    let mut debug_dir = out_path.to_path_buf();
    let mut found = false;
    for _ in 0..10 {
        if let Some(file_name) = debug_dir.file_name().and_then(|n| n.to_str()) {
            if file_name == "debug" || file_name == "release" {
                if let Some(parent) = debug_dir.parent() {
                    if parent.file_name().and_then(|n| n.to_str()) == Some("target") {
                        found = true;
                        break;
                    }
                }
            }
        }
        if !debug_dir.pop() {
            break;
        }
    }

    if !found {
        println!("cargo:warning=[DLL-COPY] Could not find target/debug root from {:?}. Using default ancestor logic.", out_path);
        // Fallback: 3 levels up from OUT_DIR is usually target/debug/build/app/out -> target/debug
        if let Some(ancestor) = out_path.ancestors().nth(3) {
            debug_dir = ancestor.to_path_buf();
        }
    } else {
        println!(
            "cargo:warning=[DLL-COPY] Found output root: {:?}",
            debug_dir
        );
    }

    let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("MANIFEST_DIR not set");
    let manifest_path = std::path::Path::new(&manifest_dir);

    let copy_to_output = |src: &std::path::Path, name: &str| {
        // Copy to target/debug (for execution) and target/debug/deps (for tests/build)
        let dests = vec![debug_dir.join(name), debug_dir.join("deps").join(name)];
        for dest in dests {
            if let Some(parent) = dest.parent() {
                let _ = std::fs::create_dir_all(parent);
            }
            match std::fs::copy(src, &dest) {
                Ok(_) => println!("cargo:warning=[DLL-COPY] Copied {:?} to {:?}", src, dest),
                Err(e) => println!(
                    "cargo:warning=[DLL-COPY] Failed to copy {:?} to {:?}: {}",
                    src, dest, e
                ),
            }
        }
    };

    // 1. Copy vec0.dll from node_modules
    let vec0_src = manifest_path.join("../node_modules/sqlite-vec-windows-x64/vec0.dll");
    if vec0_src.exists() {
        copy_to_output(&vec0_src, "vec0.dll");
    } else {
        println!(
            "cargo:warning=[DLL-COPY] vec0.dll not found in node_modules at {:?}",
            vec0_src
        );
    }

    // 2. Copy all DLLs from bin/ to support sidecar execution during development
    let bin_dir = manifest_path.join("bin");
    if bin_dir.exists() {
        if let Ok(entries) = std::fs::read_dir(&bin_dir) {
            for entry in entries.flatten() {
                let path = entry.path();
                if path.extension().and_then(|s| s.to_str()) == Some("dll") {
                    if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) {
                        copy_to_output(&path, file_name);
                    }
                }
            }
        }
    } else {
        println!(
            "cargo:warning=[DLL-COPY] bin directory not found at {:?}",
            bin_dir
        );
    }
}