@@ -5,43 +5,6 @@ terms of the MIT license. A copy of the license can be found in the file
55"LICENSE" at the root of this distribution.
66-----------------------------------------------------------------------------*/
77use std:: env;
8- use std:: path:: PathBuf ;
9-
10- // Locate the mimalloc sources: `MIMALLOC_SRC_DIR`, a vendored `mimalloc/` directory, or this repository.
11- fn mimalloc_dir ( ) -> PathBuf {
12- println ! ( "cargo:rerun-if-env-changed=MIMALLOC_SRC_DIR" ) ;
13- let manifest = PathBuf :: from ( env:: var_os ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ;
14- let dir = match env:: var_os ( "MIMALLOC_SRC_DIR" ) {
15- Some ( dir) => PathBuf :: from ( dir) ,
16- None if manifest. join ( "mimalloc/src/static.c" ) . exists ( ) => manifest. join ( "mimalloc" ) ,
17- None => manifest. join ( "../.." ) ,
18- } ;
19- if !dir. join ( "src/static.c" ) . exists ( ) {
20- panic ! (
21- "cannot find the mimalloc sources in {} (set MIMALLOC_SRC_DIR)" ,
22- dir. display( )
23- ) ;
24- }
25- dir
26- }
27-
28- fn feature ( name : & str ) -> bool {
29- env:: var_os ( format ! ( "CARGO_FEATURE_{}" , name. to_uppercase( ) ) ) . is_some ( )
30- }
31-
32- // Extra defines from `MIMALLOC_DEFINES`, e.g. `MI_DEBUG=3 MI_SKIP_COLLECT_ON_EXIT=1`
33- fn user_defines ( ) -> Vec < ( String , Option < String > ) > {
34- println ! ( "cargo:rerun-if-env-changed=MIMALLOC_DEFINES" ) ;
35- let defines = env:: var ( "MIMALLOC_DEFINES" ) . unwrap_or_default ( ) ;
36- defines
37- . split ( |c : char | c. is_whitespace ( ) || c == ',' )
38- . filter ( |d| !d. is_empty ( ) )
39- . map ( |d| match d. split_once ( '=' ) {
40- Some ( ( name, value) ) => ( name. to_string ( ) , Some ( value. to_string ( ) ) ) ,
41- None => ( d. to_string ( ) , None ) ,
42- } )
43- . collect ( )
44- }
458
469// The `Allocator` trait is stable since Rust 1.100 (but not on all 1.100 nightlies)
4710fn allocator_api_is_stable ( ) -> bool {
@@ -63,147 +26,4 @@ fn main() {
6326 if allocator_api_is_stable ( ) {
6427 println ! ( "cargo:rustc-cfg=allocator_api_stable" ) ;
6528 }
66-
67- let dir = mimalloc_dir ( ) ;
68- let include = dir. join ( "include" ) ;
69- println ! ( "cargo:rerun-if-changed={}" , include. display( ) ) ;
70- println ! ( "cargo:rerun-if-changed={}" , dir. join( "src" ) . display( ) ) ;
71- println ! ( "cargo:include={}" , include. display( ) ) ;
72-
73- let var = |name : & str | env:: var ( name) . unwrap_or_default ( ) ;
74- let target_os = var ( "CARGO_CFG_TARGET_OS" ) ;
75- let target_env = var ( "CARGO_CFG_TARGET_ENV" ) ;
76- let target_arch = var ( "CARGO_CFG_TARGET_ARCH" ) ;
77- let target_vendor = var ( "CARGO_CFG_TARGET_VENDOR" ) ;
78- let target_features = var ( "CARGO_CFG_TARGET_FEATURE" ) ;
79- let has_features = |names : & [ & str ] | {
80- names
81- . iter ( )
82- . all ( |f| target_features. split ( ',' ) . any ( |t| t == * f) )
83- } ;
84- let is_apple = target_vendor == "apple" ;
85- let is_windows = target_os == "windows" ;
86- let is_musl = target_env == "musl" ;
87-
88- let mut build = cc:: Build :: new ( ) ;
89- build. include ( & include) . file ( dir. join ( "src/static.c" ) ) ;
90- let compiler = build. get_compiler ( ) ;
91- let is_msvc = compiler. is_like_msvc ( ) ;
92- let is_gnu_like = ( compiler. is_like_gnu ( ) || compiler. is_like_clang ( ) ) && !is_msvc;
93-
94- // `MIMALLOC_DEFINES` take precedence over the defines set by features
95- let user = user_defines ( ) ;
96- let is_user = |name : & str | user. iter ( ) . any ( |( n, _) | n == name) ;
97- let mut define = |name : & str , value : & str | {
98- if !is_user ( name) {
99- build. define ( name, value) ;
100- }
101- } ;
102-
103- // build options
104- let debug = feature ( "debug" )
105- || ( feature ( "debug_in_debug" ) && env:: var_os ( "CARGO_CFG_DEBUG_ASSERTIONS" ) . is_some ( ) ) ;
106- if debug {
107- define ( "MI_DEBUG" , "2" ) ;
108- } else if !is_user ( "MI_DEBUG" ) {
109- define ( "MI_DEBUG" , "0" ) ;
110- define ( "NDEBUG" , "1" ) ;
111- }
112- if feature ( "secure" ) {
113- define ( "MI_SECURE" , "4" ) ;
114- }
115- let is_override = feature ( "override" ) && !is_windows;
116- if is_override {
117- define ( "MI_MALLOC_OVERRIDE" , "1" ) ;
118- if is_apple {
119- define ( "MI_OSX_ZONE" , "1" ) ;
120- define ( "MI_OSX_INTERPOSE" , "1" ) ;
121- }
122- }
123- if feature ( "no_thp" ) && ( target_os == "linux" || target_os == "android" ) {
124- define ( "MI_DEFAULT_ALLOW_THP" , "0" ) ;
125- }
126- if is_musl {
127- define ( "MI_LIBC_MUSL" , "1" ) ;
128- }
129- if feature ( "win_direct_tls" ) && is_windows {
130- define ( "MI_WIN_DIRECT_TLS" , "1" ) ;
131- }
132- for ( name, value) in & user {
133- build. define ( name, value. as_deref ( ) ) ;
134- }
135- if is_override && is_gnu_like {
136- build. flag ( "-fno-builtin-malloc" ) ;
137- }
138-
139- // compiler flags (as in CMakeLists.txt)
140- if is_msvc {
141- // use C++ atomics with msvc and clang-cl
142- build
143- . cpp ( true )
144- . flag ( "/TP" )
145- . flag ( "/Zc:__cplusplus" )
146- . std ( "c++17" ) ;
147- } else if is_gnu_like {
148- build
149- . flag ( "-fvisibility=hidden" )
150- . flag ( "-Wno-unknown-pragmas" ) ;
151- if compiler. is_like_clang ( ) {
152- build
153- . flag ( "-Wno-static-in-inline" )
154- . flag_if_supported ( "-mno-outline" ) ;
155- if is_apple && target_arch == "aarch64" && is_apple_clang ( & compiler) {
156- build. flag ( "-Xclang" ) . flag ( "-fno-split-cold-code" ) ;
157- }
158- }
159- if target_os != "haiku" {
160- let tls = if feature ( "local_dynamic_tls" ) || is_musl {
161- "local-dynamic"
162- } else {
163- "initial-exec"
164- } ;
165- build. flag ( format ! ( "-ftls-model={tls}" ) ) ;
166- }
167- }
168-
169- // architecture specific optimizations: enabled with `opt_arch`, or if the Rust target already implies them
170- let opt_arch = feature ( "opt_arch" ) ;
171- match target_arch. as_str ( ) {
172- "x86_64" if opt_arch || has_features ( & [ "avx2" , "bmi1" , "bmi2" , "lzcnt" ] ) => {
173- if is_msvc {
174- build. flag ( "/arch:AVX2" ) ;
175- } else if is_gnu_like {
176- build. flag ( "-march=haswell" ) . flag ( "-mavx2" ) ;
177- }
178- }
179- "aarch64" if is_apple && ( opt_arch || has_features ( & [ "lse" , "rcpc" ] ) ) => {
180- if is_gnu_like {
181- build. flag ( "-march=armv8.3-a" ) ;
182- }
183- }
184- "aarch64" if opt_arch || has_features ( & [ "lse" ] ) => {
185- if is_msvc {
186- build. flag ( "/arch:armv8.1" ) ;
187- } else if is_gnu_like {
188- build. flag ( "-march=armv8.1-a" ) ;
189- }
190- }
191- _ => { }
192- }
193-
194- build. compile ( "mimalloc" ) ;
195-
196- // system libraries
197- if is_windows {
198- for lib in [ "psapi" , "shell32" , "user32" , "advapi32" , "bcrypt" ] {
199- println ! ( "cargo:rustc-link-lib={lib}" ) ;
200- }
201- } else if target_os == "linux" && ( target_arch == "arm" || target_arch. starts_with ( "riscv32" ) ) {
202- println ! ( "cargo:rustc-link-lib=atomic" ) ;
203- }
204- }
205-
206- fn is_apple_clang ( compiler : & cc:: Tool ) -> bool {
207- let out = compiler. to_command ( ) . arg ( "--version" ) . output ( ) ;
208- out. is_ok_and ( |out| String :: from_utf8_lossy ( & out. stdout ) . contains ( "Apple clang" ) )
20929}
0 commit comments