crun-sys 0.1.1

Rust FFI bindings for libcrun (OCI container runtime, Linux only)
Documentation
//! build.rs for crun-sys
//!
//! Generates Rust FFI bindings for libcrun using bindgen.
//! Requires libcrun development headers and pkg-config.
//!
//! NOTE: libcrun is Linux-only. On non-Linux platforms,
//! this build script does nothing (stub module provided).

fn main() {
    // Declare custom cfg for check-cfg lint (Rust 1.80+)
    println!("cargo::rustc-check-cfg=cfg(libcrun_stub)");

    // libcrun is Linux-only (uses cgroups, namespaces, seccomp)
    #[cfg(not(target_os = "linux"))]
    {
        println!("cargo:warning=libcrun is Linux-only, building stub module");
        return;
    }

    #[cfg(target_os = "linux")]
    linux_build();
}

#[cfg(target_os = "linux")]
fn linux_build() {
    use std::env;
    use std::path::PathBuf;

    // Locate libcrun via pkg-config
    let libcrun = match pkg_config::Config::new()
        .atleast_version("1.8")
        .probe("libcrun")
    {
        Ok(lib) => lib,
        Err(e) => {
            // libcrun not found - emit cfg flag for stub module
            println!("cargo:warning=pkg-config failed to find libcrun: {}", e);
            println!("cargo:warning=Building with stub module (no libcrun functionality)");
            println!("cargo:rustc-cfg=libcrun_stub");
            return;
        }
    };

    // Link libcrun and its dependencies
    for lib in &libcrun.libs {
        println!("cargo:rustc-link-lib={}", lib);
    }
    for path in &libcrun.link_paths {
        println!("cargo:rustc-link-search=native={}", path.display());
    }

    // Generate bindings with bindgen
    let mut builder = bindgen::Builder::default()
        .header("wrapper.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        // Allowlist libcrun functions
        .allowlist_function("libcrun_.*")
        .allowlist_function("crun_.*")
        // Allowlist libcrun types
        .allowlist_type("libcrun_.*")
        .allowlist_type("crun_.*")
        .allowlist_type("runtime_spec_schema_.*")
        // Allowlist constants
        .allowlist_var("LIBCRUN_.*")
        // Options
        .generate_comments(true)
        .derive_debug(true)
        .derive_default(true)
        .size_t_is_usize(true);

    // Add include paths from pkg-config
    for path in &libcrun.include_paths {
        builder = builder.clang_arg(format!("-I{}", path.display()));
    }

    let bindings = builder
        .generate()
        .expect("Unable to generate bindings for libcrun");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");

    // Rerun if wrapper or environment changes
    println!("cargo:rerun-if-changed=wrapper.h");
    println!("cargo:rerun-if-env-changed=PKG_CONFIG_PATH");
    println!("cargo:rerun-if-env-changed=LIBRARY_PATH");
    println!("cargo:rerun-if-env-changed=C_INCLUDE_PATH");
}