it2play-sys 0.1.2

Unsafe Rust FFI bindings to it2play, an Impulse Tracker module player.
Documentation
use std::env;
use std::path::PathBuf;
use std::path::Path;

fn main() {
    println!("cargo:rerun-if-changed=wrapper.h");

    // Statically bind SDL2
    //println!("cargo:rustc-link-lib=static:-bundle=SDL2");
    
    // Scan for C files
    let mut files = vec![];
    scan(&[
        Path::new("it2play/audiodrivers/sdl"),
        Path::new("it2play/loaders/mmcmp"),
        Path::new("it2play/loaders"),
        Path::new("it2play/it2drivers"),
        Path::new("it2play"),
    ], &mut files);

    // Get rid of sdldriver.c
    if let Some(pos) = files.iter().position(|x| x.ends_with("sdldriver.c")) {
        files.swap_remove(pos);        
    }
    
    // Build it2play
    cc::Build::new()
        .warnings(false)
        // Preprocessor definition to use SDL audio drivers
        .define("AUDIODRIVER_SDL", None)
        // Header files
        .include(Path::new("it2play/audiodrivers"))
        .include(Path::new("it2play/audiodrivers/sdl"))
        .include(Path::new("it2play/loaders/mmcmp"))
        .include(Path::new("it2play/loaders"))
        .include(Path::new("it2play/it2drivers"))
        .include(Path::new("it2play"))
        // C files
        .files(&files)
        .file("dummydriver.c")
        .compile("it2play");

    // Generate bindings
    let bindings = bindgen::Builder::default()
        .header("wrapper.h")
        // Regenerate bindings if wrapper.h changes
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        .generate()
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
        
}

/// Scans each folder in `folders`, looking for C files and adding them to `files`.
fn scan(folders: &[&Path], files: &mut Vec<PathBuf>) {
    folders.iter().for_each(|folder| {
        // Loop through just the first level of each folder, looking for .c files.
        std::fs::read_dir(folder).unwrap().filter(|x| {
            x.as_ref().unwrap().path().extension().is_some_and(|y| y == "c")
        }).for_each(|x| {
            let path = x.unwrap().path();
            files.push(path);
        });
    });
}