Skip to content

Commit d541d9d

Browse files
Ryan ClantonSchrodingerZhu
authored andcommitted
Allow specification of cc as a feature
1 parent f4e4de7 commit d541d9d

File tree

6 files changed

+200
-24
lines changed

6 files changed

+200
-24
lines changed

.github/workflows/rust.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ jobs:
3131
run: cargo test --all
3232
- name: Run tests 1mib
3333
run: cargo test --all --features 1mib
34+
- name: Run tests 1mib build_cc
35+
run: cargo test --all --features build_cc
3436
- name: Run tests debug
3537
run: cargo test --all --features debug
3638
- name: Run tests cache-friendly

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ cache:
9595
script:
9696
- cargo test --all
9797
- cargo test --all --features 1mib
98+
- cargo test --all --features build_cc
9899
- cargo test --all --features debug
99100
- cargo test --all --features cache-friendly
100101

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ readme = "README.md"
1616
members = ["snmalloc-sys" ]
1717

1818
[dependencies]
19-
snmalloc-sys = {version = "0.2.25", path = "snmalloc-sys"}
19+
snmalloc-sys = {version = "0.2.25", path = "snmalloc-sys",default-features = false }
2020

2121
[features]
2222
default = ["1mib"]
23+
build_cc = ["snmalloc-sys/build_cc","1mib"]
2324
1mib = ["snmalloc-sys/1mib"]
2425
16mib = ["snmalloc-sys/16mib"]
2526
qemu = ["snmalloc-sys/qemu"]

snmalloc-sys/Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ build = "build.rs"
1313
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1414

1515
[build-dependencies]
16-
cc = {version = "1.0.67"}
16+
cc = {version = "1.0",optional=true}
17+
cmake = {version = "0.1",optional=true}
18+
1719

1820
[dependencies.libc]
1921
version = "0.2"
2022
default-features = false
2123

2224
[features]
23-
default = ["1mib"]
25+
default = ["1mib","cmake"]
26+
build_cc = ["cc"]
2427
1mib = []
2528
16mib = []
2629
qemu = []

snmalloc-sys/build.rs

Lines changed: 181 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
#[cfg(feature = "build_cc")]
12
fn main() {
23
let mut build = cc::Build::new();
34
build.include("snmalloc/src");
45
build.file("snmalloc/src/override/rust.cc".to_string());
56
build.flag_if_supported("/O2");
7+
build.flag_if_supported("/Zi");
8+
build.flag_if_supported("/nologo");
69
build.flag_if_supported("/W4");
710
build.flag_if_supported("/WX");
811
build.flag_if_supported("/wd4127");
@@ -12,24 +15,32 @@ fn main() {
1215
build.flag_if_supported("/DNDEBUG");
1316
build.flag_if_supported("/EHsc");
1417
build.flag_if_supported("/std:c++17");
18+
build.flag_if_supported("/Gd");
19+
build.flag_if_supported("/TP");
20+
build.flag_if_supported("/Gm-");
21+
build.flag_if_supported("/GS");
22+
build.flag_if_supported("/fp:precise");
23+
build.flag_if_supported("/Zc:wchar_t");
24+
build.flag_if_supported("/Zc:forScope");
25+
build.flag_if_supported("/Zc:inline");
1526
build.flag_if_supported("-O3");
1627
build.flag_if_supported("-Wc++17-extensions");
1728
build.flag_if_supported("-std=c++1z");
1829
build.flag_if_supported("-std=gnu++1z");
1930
build.flag_if_supported("-mcx16");
20-
build.flag_if_supported("-fno-exceptions");
21-
build.flag_if_supported("-fno-rtti");
22-
build.flag_if_supported("-g");
23-
build.flag_if_supported("-fomit-frame-pointer");
31+
build.flag_if_supported("-fno-exceptions");
32+
build.flag_if_supported("-fno-rtti");
33+
build.flag_if_supported("-g");
34+
build.flag_if_supported("-fomit-frame-pointer");
35+
build.flag_if_supported("-fpermissive");
2436
build.cpp(true);
2537
build.debug(false);
2638

2739
let triple = std::env::var("TARGET").unwrap();
2840
let target_os = std::env::var("CARGO_CFG_TARGET_OS").expect("target_os not defined!");
2941
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").expect("target_env not defined!");
30-
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").expect("target family not set");
42+
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").expect("target family not set");
3143

32-
3344
if triple.contains("android") {
3445
if cfg!(feature = "android-lld") {
3546
build.define("ANDROID_LD", "lld");
@@ -54,16 +65,16 @@ fn main() {
5465
build.define("ANDROID_ABI", "armeabi-v7a");
5566
}
5667
}
57-
58-
if target_os=="windows" && target_env == "gnu" {
68+
69+
if target_os == "windows" && target_env == "gnu" {
5970
build.define("CMAKE_SH", "CMAKE_SH-NOTFOUND");
6071
if cfg!(feature = "local_dynamic_tls") {
6172
build.flag_if_supported("-ftls-model=local-dynamic");
6273
} else {
6374
build.flag_if_supported("-ftls-model=initial-exec");
6475
}
6576
}
66-
77+
6778
if target_family == "unix" && target_os != "haiku" {
6879
if cfg!(feature = "local_dynamic_tls") {
6980
build.flag_if_supported("-ftls-model=local-dynamic");
@@ -82,7 +93,7 @@ fn main() {
8293

8394
if cfg!(feature = "native-cpu") {
8495
build.define("SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE", "ON");
85-
build.flag_if_supported("-march=native");
96+
build.flag_if_supported("-march=native");
8697
}
8798

8899
if cfg!(feature = "stats") {
@@ -107,8 +118,8 @@ fn main() {
107118
println!("cargo:rustc-link-lib=dylib=mincore");
108119
}
109120

110-
if target_os=="windows" && target_env == "gnu" {
111-
println!("cargo:rustc-link-lib=dylib=stdc++");
121+
if target_os == "windows" && target_env == "gnu" {
122+
//using cc
112123
println!("cargo:rustc-link-lib=dylib=atomic");
113124
}
114125

@@ -129,3 +140,161 @@ fn main() {
129140
println!("cargo:rustc-link-lib=dylib=atomic");
130141
};
131142
}
143+
144+
145+
#[cfg(not(feature = "build_cc"))]
146+
fn main() {
147+
let mut cfg = &mut cmake::Config::new("snmalloc");
148+
149+
let build_type = if cfg!(feature = "debug") {
150+
"Debug"
151+
} else {
152+
"Release"
153+
};
154+
155+
cfg = cfg
156+
.define("SNMALLOC_RUST_SUPPORT", "ON")
157+
.profile(build_type)
158+
.very_verbose(true);
159+
160+
let triple = std::env::var("TARGET").unwrap();
161+
if triple.contains("android") {
162+
if let Ok(ndk) = std::env::var("ANDROID_NDK") {
163+
cfg = cfg.define(
164+
"CMAKE_TOOLCHAIN_FILE",
165+
format!("{}/build/cmake/android.toolchain.cmake", ndk),
166+
);
167+
} else {
168+
eprintln!("please set ANDROID_NDK environment variable");
169+
std::process::abort();
170+
}
171+
172+
if let Ok(platform) = std::env::var("ANDROID_PLATFORM") {
173+
cfg = cfg.define("ANDROID_PLATFORM", platform);
174+
}
175+
176+
if cfg!(feature = "android-lld") {
177+
cfg = cfg.define("ANDROID_LD", "lld");
178+
}
179+
180+
if cfg!(feature = "android-shared-stl") {
181+
println!("cargo:rustc-link-lib=dylib=c++_shared");
182+
cfg = cfg.define("ANDROID_STL", "c++_shared");
183+
}
184+
185+
if triple.contains("aarch64") {
186+
cfg = cfg.define("ANDROID_ABI", "arm64-v8a");
187+
} else if triple.contains("armv7") {
188+
cfg = cfg
189+
.define("ANDROID_ABI", "armeabi-v7a")
190+
.define("ANDROID_ARM_MODE", "arm");
191+
} else if triple.contains("x86_64") {
192+
cfg = cfg.define("ANDROID_ABI", "x86_64");
193+
} else if triple.contains("i686") {
194+
cfg = cfg.define("ANDROID_ABI", "x86_64");
195+
} else if triple.contains("neon") {
196+
cfg = cfg.define("ANDROID_ABI", "armeabi-v7a with NEON")
197+
} else if triple.contains("arm") {
198+
cfg = cfg.define("ANDROID_ABI", "armeabi-v7a");
199+
}
200+
}
201+
202+
if cfg!(all(windows, target_env = "msvc")) {
203+
cfg = cfg.define("CMAKE_CXX_FLAGS_RELEASE", "/O2 /Ob2 /DNDEBUG /EHsc");
204+
cfg = cfg.define("CMAKE_C_FLAGS_RELEASE", "/O2 /Ob2 /DNDEBUG /EHsc");
205+
}
206+
207+
if cfg!(all(windows, target_env = "gnu")) {
208+
cfg = cfg.define("CMAKE_SH", "CMAKE_SH-NOTFOUND");
209+
}
210+
211+
let target = if cfg!(feature = "1mib") {
212+
"snmallocshim-1mib-rust"
213+
} else if cfg!(feature = "16mib") {
214+
"snmallocshim-16mib-rust"
215+
} else {
216+
panic!("please set a chunk configuration");
217+
};
218+
219+
if cfg!(feature = "native-cpu") {
220+
cfg = cfg.define("SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE", "ON")
221+
}
222+
223+
if cfg!(feature = "stats") {
224+
cfg = cfg.define("USE_SNMALLOC_STATS", "ON")
225+
}
226+
227+
if cfg!(feature = "qemu") {
228+
cfg = cfg.define("SNMALLOC_QEMU_WORKAROUND", "ON")
229+
}
230+
231+
let mut dst = if cfg!(feature = "cache-friendly") {
232+
cfg.define("CACHE_FRIENDLY_OFFSET", "64")
233+
.build_target(target)
234+
.build()
235+
} else {
236+
cfg.build_target(target).build()
237+
};
238+
239+
dst.push("./build");
240+
241+
println!("cargo:rustc-link-lib={}", target);
242+
243+
if cfg!(all(windows, target_env = "msvc")) {
244+
println!("cargo:rustc-link-lib=dylib=mincore");
245+
println!(
246+
"cargo:rustc-link-search=native={}/{}",
247+
dst.display(),
248+
build_type
249+
);
250+
} else {
251+
println!("cargo:rustc-link-search=native={}", dst.display());
252+
}
253+
254+
if cfg!(all(windows, target_env = "gnu")) {
255+
let stdout = std::process::Command::new("gcc")
256+
.args(&["-print-search-dirs"])
257+
.output()
258+
.unwrap_or_else(|_| {
259+
eprintln!("Cannot run gcc.exe");
260+
std::process::abort();
261+
})
262+
.stdout;
263+
264+
let outputs = String::from_utf8(stdout).unwrap_or_else(|_| {
265+
eprintln!("gcc output contains non-utf8 characters");
266+
std::process::abort();
267+
});
268+
269+
outputs
270+
.lines()
271+
.filter(|line| line.starts_with("libraries: ="))
272+
.map(|line| line.split_at("libraries: =".len()).1)
273+
.flat_map(|line| line.split(";"))
274+
.for_each(|path| {
275+
println!("cargo:rustc-link-search=native={}", path);
276+
});
277+
278+
println!("cargo:rustc-link-lib=dylib=stdc++");
279+
println!("cargo:rustc-link-lib=dylib=atomic");
280+
println!("cargo:rustc-link-lib=dylib=winpthread");
281+
println!("cargo:rustc-link-lib=dylib=gcc_s");
282+
}
283+
284+
if cfg!(target_os = "macos") {
285+
println!("cargo:rustc-link-lib=dylib=c++");
286+
}
287+
288+
if cfg!(target_os = "openbsd") {
289+
println!("cargo:rustc-link-lib=dylib=c++");
290+
}
291+
292+
if cfg!(target_os = "freebsd") {
293+
println!("cargo:rustc-link-lib=dylib=c++");
294+
}
295+
296+
if cfg!(target_os = "linux") {
297+
println!("cargo:rustc-link-lib=dylib=stdc++");
298+
println!("cargo:rustc-link-lib=dylib=atomic");
299+
}
300+
}

src/lib.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
//! - Memory that is freed by the same thread that allocated it does not require any synchronising operations.
55
//! - Freeing memory in a different thread to initially allocated it, does not take any locks and instead uses a novel message passing scheme to return the memory to the original allocator, where it is recycled.
66
//! - The allocator uses large ranges of pages to reduce the amount of meta-data required.
7-
//!
7+
//!
88
//! The benchmark is available at the [paper](https://github.com/microsoft/snmalloc/blob/master/snmalloc.pdf) of `snmalloc`
99
//! There are three features defined in this crate:
1010
//! - `debug`: Enable the `Debug` mode in `snmalloc`.
1111
//! - `1mib`: Use the `1mib` chunk configuration.
1212
//! - `cache-friendly`: Make the allocator more cache friendly (setting `CACHE_FRIENDLY_OFFSET` to `64` in building the library).
13-
//!
13+
//!
1414
//! The whole library supports `no_std`.
15-
//!
15+
//!
1616
//! To use `snmalloc-rs` add it as a dependency:
1717
//! ```toml
1818
//! # Cargo.toml
1919
//! [dependencies]
2020
//! snmalloc-rs = "0.1.0"
2121
//! ```
22-
//!
22+
//!
2323
//! To set `SnMalloc` as the global allocator add this to your project:
2424
//! ```rust
2525
//! #[global_allocator]
@@ -32,8 +32,8 @@ use core::alloc::{GlobalAlloc, Layout};
3232
pub struct SnMalloc;
3333

3434
unsafe impl GlobalAlloc for SnMalloc {
35-
/// Allocate the memory with the given alignment and size.
36-
/// On success, it returns a pointer pointing to the required memory address.
35+
/// Allocate the memory with the given alignment and size.
36+
/// On success, it returns a pointer pointing to the required memory address.
3737
/// On failure, it returns a null pointer.
3838
/// The client must assure the following things:
3939
/// - `alignment` is greater than zero
@@ -44,7 +44,7 @@ unsafe impl GlobalAlloc for SnMalloc {
4444
ffi::rust_alloc(layout.align(), layout.size()) as _
4545
}
4646

47-
/// De-allocate the memory at the given address with the given alignment and size.
47+
/// De-allocate the memory at the given address with the given alignment and size.
4848
/// The client must assure the following things:
4949
/// - the memory is acquired using the same allocator and the pointer points to the start position.
5050
/// - Other constrains are the same as the rust standard library.
@@ -54,8 +54,8 @@ unsafe impl GlobalAlloc for SnMalloc {
5454
ffi::rust_dealloc(ptr as _, layout.align(), layout.size());
5555
}
5656

57-
/// Re-allocate the memory at the given address with the given alignment and size.
58-
/// On success, it returns a pointer pointing to the required memory address.
57+
/// Re-allocate the memory at the given address with the given alignment and size.
58+
/// On success, it returns a pointer pointing to the required memory address.
5959
/// The memory content within the `new_size` will remains the same as previous.
6060
/// On failure, it returns a null pointer. In this situation, the previous memory is not returned to the allocator.
6161
/// The client must assure the following things:

0 commit comments

Comments
 (0)