1010
1111#![ deny( warnings) ]
1212
13+ #[ macro_use]
1314extern crate build_helper;
1415extern crate gcc;
1516
1617use std:: env;
17- use std:: path:: PathBuf ;
18+ use std:: fs:: { self , File } ;
19+ use std:: path:: { Path , PathBuf } ;
1820use std:: process:: Command ;
19- use build_helper:: run;
21+ use build_helper:: { run, rerun_if_changed_anything_in_dir , up_to_date } ;
2022
2123fn main ( ) {
2224 println ! ( "cargo:rustc-cfg=cargobuild" ) ;
2325 println ! ( "cargo:rerun-if-changed=build.rs" ) ;
2426
25- let target = env:: var ( "TARGET" ) . expect ( "TARGET was not set" ) ;
26- let host = env:: var ( "HOST" ) . expect ( "HOST was not set" ) ;
27- let build_dir = PathBuf :: from ( env:: var_os ( "OUT_DIR" ) . unwrap ( ) ) ;
28- let src_dir = env:: current_dir ( ) . unwrap ( ) ;
29-
3027 // FIXME: This is a hack to support building targets that don't
3128 // support jemalloc alongside hosts that do. The jemalloc build is
3229 // controlled by a feature of the std crate, and if that feature
@@ -35,6 +32,8 @@ fn main() {
3532 // that the feature set used by std is the same across all
3633 // targets, which means we have to build the alloc_jemalloc crate
3734 // for targets like emscripten, even if we don't use it.
35+ let target = env:: var ( "TARGET" ) . expect ( "TARGET was not set" ) ;
36+ let host = env:: var ( "HOST" ) . expect ( "HOST was not set" ) ;
3837 if target. contains ( "rumprun" ) || target. contains ( "bitrig" ) || target. contains ( "openbsd" ) ||
3938 target. contains ( "msvc" ) || target. contains ( "emscripten" ) || target. contains ( "fuchsia" ) ||
4039 target. contains ( "redox" ) {
@@ -63,6 +62,23 @@ fn main() {
6362 return ;
6463 }
6564
65+ let build_dir = env:: var_os ( "RUSTBUILD_NATIVE_DIR" ) . unwrap_or ( env:: var_os ( "OUT_DIR" ) . unwrap ( ) ) ;
66+ let build_dir = PathBuf :: from ( build_dir) . join ( "jemalloc" ) ;
67+ let _ = fs:: create_dir_all ( & build_dir) ;
68+
69+ if target. contains ( "windows" ) {
70+ println ! ( "cargo:rustc-link-lib=static=jemalloc" ) ;
71+ } else {
72+ println ! ( "cargo:rustc-link-lib=static=jemalloc_pic" ) ;
73+ }
74+ println ! ( "cargo:rustc-link-search=native={}/lib" , build_dir. display( ) ) ;
75+ let src_dir = env:: current_dir ( ) . unwrap ( ) . join ( "../jemalloc" ) ;
76+ rerun_if_changed_anything_in_dir ( & src_dir) ;
77+ let timestamp = build_dir. join ( "rustbuild.timestamp" ) ;
78+ if up_to_date ( & Path :: new ( "build.rs" ) , & timestamp) && up_to_date ( & src_dir, & timestamp) {
79+ return
80+ }
81+
6682 let compiler = gcc:: Config :: new ( ) . get_compiler ( ) ;
6783 // only msvc returns None for ar so unwrap is okay
6884 let ar = build_helper:: cc2ar ( compiler. path ( ) , & target) . unwrap ( ) ;
@@ -72,23 +88,8 @@ fn main() {
7288 . collect :: < Vec < _ > > ( )
7389 . join ( " " ) ;
7490
75- let mut stack = src_dir. join ( "../jemalloc" )
76- . read_dir ( )
77- . unwrap ( )
78- . map ( |e| e. unwrap ( ) )
79- . filter ( |e| & * e. file_name ( ) != ".git" )
80- . collect :: < Vec < _ > > ( ) ;
81- while let Some ( entry) = stack. pop ( ) {
82- let path = entry. path ( ) ;
83- if entry. file_type ( ) . unwrap ( ) . is_dir ( ) {
84- stack. extend ( path. read_dir ( ) . unwrap ( ) . map ( |e| e. unwrap ( ) ) ) ;
85- } else {
86- println ! ( "cargo:rerun-if-changed={}" , path. display( ) ) ;
87- }
88- }
89-
9091 let mut cmd = Command :: new ( "sh" ) ;
91- cmd. arg ( src_dir. join ( "../jemalloc/ configure" )
92+ cmd. arg ( src_dir. join ( "configure" )
9293 . to_str ( )
9394 . unwrap ( )
9495 . replace ( "C:\\ " , "/c/" )
@@ -164,6 +165,7 @@ fn main() {
164165 }
165166
166167 run ( & mut cmd) ;
168+
167169 let mut make = Command :: new ( build_helper:: make ( & host) ) ;
168170 make. current_dir ( & build_dir)
169171 . arg ( "build_lib_static" ) ;
@@ -176,13 +178,6 @@ fn main() {
176178
177179 run ( & mut make) ;
178180
179- if target. contains ( "windows" ) {
180- println ! ( "cargo:rustc-link-lib=static=jemalloc" ) ;
181- } else {
182- println ! ( "cargo:rustc-link-lib=static=jemalloc_pic" ) ;
183- }
184- println ! ( "cargo:rustc-link-search=native={}/lib" , build_dir. display( ) ) ;
185-
186181 // The pthread_atfork symbols is used by jemalloc on android but the really
187182 // old android we're building on doesn't have them defined, so just make
188183 // sure the symbols are available.
@@ -193,4 +188,6 @@ fn main() {
193188 . file ( "pthread_atfork_dummy.c" )
194189 . compile ( "libpthread_atfork_dummy.a" ) ;
195190 }
191+
192+ t ! ( File :: create( & timestamp) ) ;
196193}
0 commit comments