]>
Commit | Line | Data |
---|---|---|
7453a54e SL |
1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
a7813a04 XL |
11 | #![deny(warnings)] |
12 | ||
7453a54e | 13 | extern crate build_helper; |
ea8adc8c | 14 | extern crate cc; |
7453a54e SL |
15 | |
16 | use std::env; | |
17 | use std::path::PathBuf; | |
18 | use std::process::Command; | |
ea8adc8c | 19 | use build_helper::{run, native_lib_boilerplate, BuildExpectation}; |
7453a54e SL |
20 | |
21 | fn main() { | |
c30ab7b3 SL |
22 | // FIXME: This is a hack to support building targets that don't |
23 | // support jemalloc alongside hosts that do. The jemalloc build is | |
24 | // controlled by a feature of the std crate, and if that feature | |
25 | // changes between targets, it invalidates the fingerprint of | |
26 | // std's build script (this is a cargo bug); so we must ensure | |
27 | // that the feature set used by std is the same across all | |
28 | // targets, which means we have to build the alloc_jemalloc crate | |
29 | // for targets like emscripten, even if we don't use it. | |
8bb4bdeb XL |
30 | let target = env::var("TARGET").expect("TARGET was not set"); |
31 | let host = env::var("HOST").expect("HOST was not set"); | |
c30ab7b3 | 32 | if target.contains("rumprun") || target.contains("bitrig") || target.contains("openbsd") || |
32a655c1 | 33 | target.contains("msvc") || target.contains("emscripten") || target.contains("fuchsia") || |
abe05a73 | 34 | target.contains("redox") || target.contains("wasm32") { |
c30ab7b3 SL |
35 | println!("cargo:rustc-cfg=dummy_jemalloc"); |
36 | return; | |
37 | } | |
38 | ||
8bb4bdeb XL |
39 | if target.contains("android") { |
40 | println!("cargo:rustc-link-lib=gcc"); | |
41 | } else if !target.contains("windows") && !target.contains("musl") { | |
42 | println!("cargo:rustc-link-lib=pthread"); | |
43 | } | |
44 | ||
7453a54e SL |
45 | if let Some(jemalloc) = env::var_os("JEMALLOC_OVERRIDE") { |
46 | let jemalloc = PathBuf::from(jemalloc); | |
47 | println!("cargo:rustc-link-search=native={}", | |
48 | jemalloc.parent().unwrap().display()); | |
49 | let stem = jemalloc.file_stem().unwrap().to_str().unwrap(); | |
50 | let name = jemalloc.file_name().unwrap().to_str().unwrap(); | |
3157f602 XL |
51 | let kind = if name.ends_with(".a") { |
52 | "static" | |
53 | } else { | |
54 | "dylib" | |
55 | }; | |
7453a54e | 56 | println!("cargo:rustc-link-lib={}={}", kind, &stem[3..]); |
3157f602 | 57 | return; |
7453a54e SL |
58 | } |
59 | ||
8bb4bdeb XL |
60 | let link_name = if target.contains("windows") { "jemalloc" } else { "jemalloc_pic" }; |
61 | let native = match native_lib_boilerplate("jemalloc", "jemalloc", link_name, "lib") { | |
62 | Ok(native) => native, | |
63 | _ => return, | |
64 | }; | |
65 | ||
7453a54e | 66 | let mut cmd = Command::new("sh"); |
8bb4bdeb XL |
67 | cmd.arg(native.src_dir.join("configure") |
68 | .to_str() | |
69 | .unwrap() | |
70 | .replace("C:\\", "/c/") | |
71 | .replace("\\", "/")) | |
72 | .current_dir(&native.out_dir) | |
5bcae85e SL |
73 | // jemalloc generates Makefile deps using GCC's "-MM" flag. This means |
74 | // that GCC will run the preprocessor, and only the preprocessor, over | |
75 | // jemalloc's source files. If we don't specify CPPFLAGS, then at least | |
76 | // on ARM that step fails with a "Missing implementation for 32-bit | |
77 | // atomic operations" error. This is because no "-march" flag will be | |
78 | // passed to GCC, and then GCC won't define the | |
79 | // "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" macro that jemalloc needs to | |
80 | // select an atomic operation implementation. | |
abe05a73 | 81 | .env("CPPFLAGS", env::var_os("CFLAGS").unwrap_or_default()); |
7453a54e | 82 | |
3b2f2976 | 83 | if target.contains("ios") { |
7453a54e SL |
84 | cmd.arg("--disable-tls"); |
85 | } else if target.contains("android") { | |
86 | // We force android to have prefixed symbols because apparently | |
87 | // replacement of the libc allocator doesn't quite work. When this was | |
88 | // tested (unprefixed symbols), it was found that the `realpath` | |
89 | // function in libc would allocate with libc malloc (not jemalloc | |
90 | // malloc), and then the standard library would free with jemalloc free, | |
91 | // causing a segfault. | |
92 | // | |
93 | // If the test suite passes, however, without symbol prefixes then we | |
94 | // should be good to go! | |
95 | cmd.arg("--with-jemalloc-prefix=je_"); | |
96 | cmd.arg("--disable-tls"); | |
cc61c64b | 97 | } else if target.contains("dragonfly") || target.contains("musl") { |
54a0048b | 98 | cmd.arg("--with-jemalloc-prefix=je_"); |
7453a54e SL |
99 | } |
100 | ||
ea8adc8c XL |
101 | // FIXME: building with jemalloc assertions is currently broken. |
102 | // See <https://github.com/rust-lang/rust/issues/44152>. | |
103 | //if cfg!(feature = "debug") { | |
104 | // cmd.arg("--enable-debug"); | |
105 | //} | |
7453a54e | 106 | |
7453a54e SL |
107 | cmd.arg(format!("--host={}", build_helper::gnu_target(&target))); |
108 | cmd.arg(format!("--build={}", build_helper::gnu_target(&host))); | |
109 | ||
32a655c1 SL |
110 | // for some reason, jemalloc configure doesn't detect this value |
111 | // automatically for this target | |
112 | if target == "sparc64-unknown-linux-gnu" { | |
113 | cmd.arg("--with-lg-quantum=4"); | |
114 | } | |
115 | ||
ea8adc8c | 116 | run(&mut cmd, BuildExpectation::None); |
8bb4bdeb | 117 | |
476ff2be | 118 | let mut make = Command::new(build_helper::make(&host)); |
8bb4bdeb | 119 | make.current_dir(&native.out_dir) |
476ff2be SL |
120 | .arg("build_lib_static"); |
121 | ||
041b39d2 XL |
122 | // These are intended for mingw32-make which we don't use |
123 | if cfg!(windows) { | |
124 | make.env_remove("MAKEFLAGS").env_remove("MFLAGS"); | |
125 | } | |
126 | ||
476ff2be SL |
127 | // mingw make seems... buggy? unclear... |
128 | if !host.contains("windows") { | |
129 | make.arg("-j") | |
130 | .arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")); | |
131 | } | |
132 | ||
ea8adc8c | 133 | run(&mut make, BuildExpectation::None); |
7453a54e | 134 | |
32a655c1 SL |
135 | // The pthread_atfork symbols is used by jemalloc on android but the really |
136 | // old android we're building on doesn't have them defined, so just make | |
137 | // sure the symbols are available. | |
138 | if target.contains("androideabi") { | |
139 | println!("cargo:rerun-if-changed=pthread_atfork_dummy.c"); | |
ea8adc8c | 140 | cc::Build::new() |
32a655c1 SL |
141 | .flag("-fvisibility=hidden") |
142 | .file("pthread_atfork_dummy.c") | |
143 | .compile("libpthread_atfork_dummy.a"); | |
144 | } | |
7453a54e | 145 | } |