mimalloc-pprof 1.0.0

mimalloc global allocator with pprof-compatible sampled heap profiling
Documentation
use std::env;

fn main() {
    // Everything the compiler needs lives in vendor/: the amalgamated
    // translation unit plus two verbatim support headers it opens via
    // `#include <...>` (see rust/xtask/src/main.rs's
    // ANGLE_BRACKET_SUPPORT_HEADERS for why). No path outside vendor/ is
    // referenced, so this crate no longer reads ../../src or ../../include
    // at build time -- only `cargo run -p xtask -- amalgamate-c/-h` does.
    println!("cargo:rerun-if-changed=vendor/mimalloc-pprof-amalgamated.c");
    println!("cargo:rerun-if-changed=vendor/mimalloc-pprof-amalgamated.h");
    println!("cargo:rerun-if-changed=vendor/mimalloc.h");
    println!("cargo:rerun-if-changed=vendor/mimalloc-stats.h");
    // The ABI layout probe (see layout_probe.c) is compiled into the same static
    // library. It is referenced only from tests/t19_layout.rs, so the linker drops it
    // from ordinary consumers; keeping it in this one `cc::Build` means it always sees
    // exactly the defines the library itself was built with.
    println!("cargo:rerun-if-changed=layout_probe.c");

    let mut build = cc::Build::new();
    build
        .include("vendor")
        .file("vendor/mimalloc-pprof-amalgamated.c")
        .file("layout_probe.c")
        .define("MI_STATIC_LIB", None)
        // #414: every observability subsystem is opt-in, so each of the five defines below
        // is derived from its cargo feature and is ALWAYS defined, to 0 or 1 -- the C code
        // tests `#if MI_<X>`, and mirrors CMake's option of the same name. With nothing
        // enabled the C library is a plain fast allocator and every API is a C stub.
        .define(
            "MI_PPROF",
            if env::var_os("CARGO_FEATURE_PPROF").is_some() {
                "1"
            } else {
                "0"
            },
        )
        // Issue #20: allocation-change accounting and callbacks, behind `memory-events`.
        // Note `dhat` implies this feature, and the C side additionally keeps the hook
        // sites whenever `MI_MEMEVT || MI_DHAT`.
        .define(
            "MI_MEMEVT",
            if env::var_os("CARGO_FEATURE_MEMORY_EVENTS").is_some() {
                "1"
            } else {
                "0"
            },
        )
        // Issues #338/#269: heap snapshot + live-heap JSON dump, behind `diagnostics`.
        .define(
            "MI_DIAGNOSTICS",
            if env::var_os("CARGO_FEATURE_DIAGNOSTICS").is_some() {
                "1"
            } else {
                "0"
            },
        )
        // #371: the exact DHAT observer, behind the opt-in (default-off) `dhat` feature. Mirrors
        // CMake's `MI_DHAT` option; the C code tests `#if MI_DHAT`, so it is always
        // defined, to 0 or 1. With it off, `sys::mi_dhat_*` link to C's stubs and
        // `dhat::start()` returns `false`.
        .define(
            "MI_DHAT",
            if env::var_os("CARGO_FEATURE_DHAT").is_some() {
                "1"
            } else {
                "0"
            },
        )
        // Issue #366: the per-thread owner gate behind `purge_all`. Mirrors CMake's
        // `MI_OWNER_GATE` option; the C code tests `#if MI_OWNER_GATE`, so it is always
        // defined, to 0 or 1.
        .define(
            "MI_OWNER_GATE",
            if env::var_os("CARGO_FEATURE_OWNER_GATE").is_some() {
                "1"
            } else {
                "0"
            },
        );
    if env::var("PROFILE").as_deref() == Ok("release") {
        build.define("NDEBUG", None);
    }
    build.compile("mimalloc");

    if env::var("TARGET").is_ok_and(|target| target.contains("windows")) {
        for library in ["psapi", "shell32", "user32", "advapi32", "bcrypt"] {
            println!("cargo:rustc-link-lib={library}");
        }
    }
}