|
1 | | -#![allow(clippy::collapsible_if)] |
2 | | -use cmake::Config; |
3 | 1 | use std::env; |
4 | 2 |
|
5 | | -enum CMakeBuildType { |
6 | | - Debug, |
7 | | - Release, |
8 | | - RelWithDebInfo, |
9 | | - MinSizeRel, |
10 | | -} |
11 | | - |
12 | | -/// Determine the CMake build type that will be picked by `cmake-rs`. |
13 | | -/// |
14 | | -/// This is mostly pasted from `cmake-rs`: |
15 | | -/// https://github.com/alexcrichton/cmake-rs/blob/7f85e323/src/lib.rs#L498 |
16 | | -fn get_cmake_build_type() -> Result<CMakeBuildType, String> { |
17 | | - fn getenv(v: &str) -> Result<String, String> { |
18 | | - env::var(v).map_err(|_| format!("environment variable `{}` not defined", v)) |
19 | | - } |
20 | | - |
21 | | - // Determine Rust's profile, optimization level, and debug info: |
22 | | - #[derive(PartialEq)] |
23 | | - enum RustProfile { |
24 | | - Debug, |
25 | | - Release, |
26 | | - } |
27 | | - #[derive(PartialEq, Debug)] |
28 | | - enum OptLevel { |
29 | | - Debug, |
30 | | - Release, |
31 | | - Size, |
32 | | - } |
33 | | - |
34 | | - let rust_profile = match getenv("PROFILE")?.as_str() { |
35 | | - "debug" => RustProfile::Debug, |
36 | | - "release" | "bench" => RustProfile::Release, |
37 | | - _ => RustProfile::Release, |
38 | | - }; |
39 | | - |
40 | | - let opt_level = match getenv("OPT_LEVEL")?.as_str() { |
41 | | - "0" => OptLevel::Debug, |
42 | | - "1" | "2" | "3" => OptLevel::Release, |
43 | | - "s" | "z" => OptLevel::Size, |
44 | | - _ => match rust_profile { |
45 | | - RustProfile::Debug => OptLevel::Debug, |
46 | | - RustProfile::Release => OptLevel::Release, |
47 | | - }, |
48 | | - }; |
49 | | - |
50 | | - let debug_info: bool = match getenv("DEBUG")?.as_str() { |
51 | | - "false" => false, |
52 | | - "true" => true, |
53 | | - _ => true, |
54 | | - }; |
55 | | - |
56 | | - Ok(match (opt_level, debug_info) { |
57 | | - (OptLevel::Debug, _) => CMakeBuildType::Debug, |
58 | | - (OptLevel::Release, false) => CMakeBuildType::Release, |
59 | | - (OptLevel::Release, true) => CMakeBuildType::RelWithDebInfo, |
60 | | - (OptLevel::Size, _) => CMakeBuildType::MinSizeRel, |
61 | | - }) |
62 | | -} |
63 | | - |
64 | 3 | fn main() { |
65 | | - let mut cfg = &mut Config::new("c_src/mimalloc"); |
| 4 | + let mut build = cc::Build::new(); |
| 5 | + |
| 6 | + build.include("c_src/mimalloc/include"); |
| 7 | + build.files( |
| 8 | + [ |
| 9 | + "alloc-aligned", |
| 10 | + "alloc-posix", |
| 11 | + "alloc", |
| 12 | + "arena", |
| 13 | + "bitmap", |
| 14 | + "heap", |
| 15 | + "init", |
| 16 | + "options", |
| 17 | + "os", |
| 18 | + "page", |
| 19 | + "random", |
| 20 | + "region", |
| 21 | + "segment", |
| 22 | + "stats", |
| 23 | + ] |
| 24 | + .iter() |
| 25 | + .map(|fname| format!("c_src/mimalloc/src/{}.c", fname)), |
| 26 | + ); |
| 27 | + |
| 28 | + build.define("MI_STATIC_LIB", None); |
| 29 | + |
| 30 | + let target_os = env::var("CARGO_CFG_TARGET_OS").expect("target_os not defined!"); |
66 | 31 |
|
67 | 32 | if cfg!(feature = "override") { |
68 | | - cfg = cfg.define("MI_OVERRIDE", "ON"); |
69 | | - } else { |
70 | | - cfg = cfg.define("MI_OVERRIDE", "OFF"); |
| 33 | + // Overriding malloc is only available on windows in shared mode, but we |
| 34 | + // only ever build a static lib. |
| 35 | + if target_os != "windows" { |
| 36 | + build.define("MI_MALLOC_OVERRIDE", None); |
| 37 | + } |
71 | 38 | } |
72 | 39 |
|
73 | | - cfg = cfg.define("MI_BUILD_TESTS", "OFF"); |
74 | | - |
75 | 40 | if cfg!(feature = "secure") { |
76 | | - cfg = cfg.define("MI_SECURE", "ON"); |
77 | | - } else { |
78 | | - cfg = cfg.define("MI_SECURE", "OFF"); |
| 41 | + build.define("MI_SECURE", "4"); |
79 | 42 | } |
80 | 43 |
|
81 | | - if cfg!(feature = "local_dynamic_tls") { |
82 | | - cfg = cfg.define("MI_LOCAL_DYNAMIC_TLS", "ON"); |
83 | | - } else { |
84 | | - cfg = cfg.define("MI_LOCAL_DYNAMIC_TLS", "OFF"); |
85 | | - } |
86 | | - |
87 | | - // Inject MI_DEBUG=0 |
88 | | - // This set mi_option_verbose and mi_option_show_errors options to false. |
89 | | - cfg = cfg.define("mi_defines", "MI_DEBUG=0"); |
90 | | - |
91 | | - let (is_debug, win_folder) = match get_cmake_build_type() { |
92 | | - Ok(CMakeBuildType::Debug) => (true, "Debug"), |
93 | | - Ok(CMakeBuildType::Release) => (false, "Release"), |
94 | | - Ok(CMakeBuildType::RelWithDebInfo) => (false, "RelWithDebInfo"), |
95 | | - Ok(CMakeBuildType::MinSizeRel) => (false, "MinSizeRel"), |
96 | | - Err(e) => panic!("Cannot determine CMake build type: {}", e), |
97 | | - }; |
98 | | - |
99 | | - // Turning off shared lib, tests, PADDING. |
100 | | - // See also: https://github.com/microsoft/mimalloc/blob/master/CMakeLists.txt |
101 | | - cfg = cfg.define("MI_PADDING", "OFF"); |
102 | | - cfg = cfg.define("MI_BUILD_TESTS", "OFF"); |
103 | | - cfg = cfg.define("MI_BUILD_SHARED", "OFF"); |
104 | | - cfg = cfg.define("MI_BUILD_OBJECT", "OFF"); |
| 44 | + let dynamic_tls = cfg!(feature = "local_dynamic_tls"); |
105 | 45 |
|
106 | | - let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap(); |
107 | | - if target_env == "msvc" { |
108 | | - cfg = cfg.define("CMAKE_SH", "CMAKE_SH-NOTFOUND"); |
109 | | - |
110 | | - // cc::get_compiler have /nologo /MD default flags that are cmake::Config |
111 | | - // defaults to. Those flags prevents mimalloc from building on windows |
112 | | - // extracted from default cmake configuration on windows |
113 | | - if is_debug { |
114 | | - // CMAKE_C_FLAGS + CMAKE_C_FLAGS_DEBUG |
115 | | - cfg = cfg.cflag("/DWIN32 /D_WINDOWS /W3 /MDd /Zi /Ob0 /Od /RTC1"); |
116 | | - } else { |
117 | | - // CMAKE_C_FLAGS + CMAKE_C_FLAGS_RELEASE |
118 | | - cfg = cfg.cflag("/DWIN32 /D_WINDOWS /W3 /MD /O2 /Ob2 /DNDEBUG"); |
119 | | - } |
120 | | - } else if target_env == "gnu" { |
121 | | - cfg = cfg.define("CMAKE_SH", "CMAKE_SH-NOTFOUND"); |
122 | | - // Those flags prevents mimalloc from building on windows |
123 | | - if is_debug { |
124 | | - // CMAKE_C_FLAGS + CMAKE_C_FLAGS_DEBUG |
125 | | - cfg = cfg.cflag("-ffunction-sections -fdata-sections -m64 -O2 -fpic"); |
| 46 | + if env::var("CARGO_CFG_TARGET_FAMILY").expect("target family not set") == "unix" |
| 47 | + && target_os != "haiku" |
| 48 | + { |
| 49 | + if dynamic_tls { |
| 50 | + build.flag_if_supported("-ftls-model=local-dynamic"); |
126 | 51 | } else { |
127 | | - // CMAKE_C_FLAGS + CMAKE_C_FLAGS_RELEASE |
128 | | - cfg = cfg.cflag("-ffunction-sections -fdata-sections -m64 -O3 -fpic"); |
| 52 | + build.flag_if_supported("-ftls-model=initial-exec"); |
129 | 53 | } |
130 | | - }; |
| 54 | + } |
131 | 55 |
|
132 | | - let mut out_dir = "./build".to_string(); |
133 | | - if cfg!(all(windows)) { |
134 | | - if target_env == "msvc" { |
135 | | - out_dir.push('/'); |
136 | | - out_dir.push_str(win_folder); |
137 | | - } |
| 56 | + // Remove heavy debug assertions etc |
| 57 | + build.define("MI_DEBUG", "0"); |
| 58 | + |
| 59 | + if build.get_compiler().is_like_msvc() { |
| 60 | + build.cpp(true); |
138 | 61 | } |
139 | | - let out_name = if cfg!(all(windows)) { |
140 | | - if is_debug { |
141 | | - if cfg!(feature = "secure") { |
142 | | - "mimalloc-static-secure-debug" |
143 | | - } else { |
144 | | - "mimalloc-static-debug" |
145 | | - } |
146 | | - } else if cfg!(feature = "secure") { |
147 | | - "mimalloc-static-secure" |
148 | | - } else { |
149 | | - "mimalloc-static" |
150 | | - } |
151 | | - } else if is_debug { |
152 | | - if cfg!(feature = "secure") { |
153 | | - "mimalloc-secure-debug" |
154 | | - } else { |
155 | | - "mimalloc-debug" |
156 | | - } |
157 | | - } else if cfg!(feature = "secure") { |
158 | | - "mimalloc-secure" |
159 | | - } else { |
160 | | - "mimalloc" |
161 | | - }; |
162 | 62 |
|
163 | | - // Build mimalloc-static |
164 | | - let mut dst = cfg.build_target("mimalloc-static").build(); |
165 | | - dst.push(out_dir); |
166 | | - println!("cargo:rustc-link-search=native={}", dst.display()); |
167 | | - println!("cargo:rustc-link-lib={}", out_name); |
| 63 | + build.compile("mimalloc"); |
168 | 64 | } |
0 commit comments