1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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}");
}
}
}