commonware-allocator 2026.9.0

Allocate and manage memory.
Documentation
//! Compiles the vendored mimalloc sources into the crate when the `mimalloc`
//! feature is enabled.

use std::env;

fn main() {
    println!("cargo:rerun-if-changed=mimalloc");
    if env::var_os("CARGO_FEATURE_MIMALLOC").is_none() {
        return;
    }

    let mut build = cc::Build::new();
    build
        .include("mimalloc/include")
        .file("mimalloc/src/static.c")
        .opt_level(3)
        .warnings(false);

    // Freeing memory at exit only matters when mimalloc is repeatedly loaded
    // and unloaded as a shared library. The `local-dynamic-tls` feature
    // targets such libraries and keeps that step.
    let dynamic = env::var_os("CARGO_FEATURE_LOCAL_DYNAMIC_TLS").is_some();
    if !dynamic {
        build.define("MI_SKIP_COLLECT_ON_EXIT", "1");
    }

    // Scale the arena slice for the `large-objects-*` features. The large
    // object limit is eight slices, and the largest enabled feature wins.
    let slice_shift = [("4MB", "19"), ("2MB", "18"), ("1MB", "17")]
        .into_iter()
        .find(|(name, _)| env::var_os(format!("CARGO_FEATURE_LARGE_OBJECTS_{name}")).is_some())
        .map(|(_, shift)| shift);
    if let Some(shift) = slice_shift {
        build.define("MI_ARENA_SLICE_SHIFT", shift);
    }

    // Build with release semantics in every profile (no internal assertions,
    // padding, or guard sampling), so tests see the same size classes and
    // alignment as release binaries.
    build.define("MI_DEBUG", "0").define("NDEBUG", None);

    // Initial-exec TLS makes the thread-local heap lookup a direct load, but
    // its storage comes from a static block the loader sizes at startup. A
    // library loaded later with `dlopen` can only use the loader's reserve,
    // and musl's block is fixed-size. The `local-dynamic-tls` and musl builds
    // therefore use local-dynamic TLS, as mimalloc's own musl support does.
    let musl = env::var("CARGO_CFG_TARGET_ENV").as_deref() == Ok("musl");
    if musl {
        build.define("MI_LIBC_MUSL", "1");
    }
    if dynamic || musl {
        build.flag_if_supported("-ftls-model=local-dynamic");
    } else {
        build.flag_if_supported("-ftls-model=initial-exec");
    }
    build.compile("mimalloc");
}