46
46
47
47
extern crate cc;
48
48
49
+ use std:: collections:: HashMap ;
49
50
use std:: env;
50
51
use std:: ffi:: { OsStr , OsString } ;
51
52
use std:: fs:: { self , File } ;
@@ -80,6 +81,7 @@ pub struct Config {
80
81
pic : Option < bool > ,
81
82
c_cfg : Option < cc:: Build > ,
82
83
cxx_cfg : Option < cc:: Build > ,
84
+ env_cache : HashMap < String , Option < OsString > > ,
83
85
}
84
86
85
87
/// Builds the native library rooted at `path` with the default cmake options.
@@ -202,6 +204,7 @@ impl Config {
202
204
pic : None ,
203
205
c_cfg : None ,
204
206
cxx_cfg : None ,
207
+ env_cache : HashMap :: new ( ) ,
205
208
}
206
209
}
207
210
@@ -422,13 +425,13 @@ impl Config {
422
425
t
423
426
}
424
427
} ;
428
+ let host = self . host . clone ( ) . unwrap_or_else ( || getenv_unwrap ( "HOST" ) ) ;
425
429
426
- let mut generator = self
430
+ let generator = self
427
431
. generator
428
432
. clone ( )
429
- . or_else ( || std :: env :: var_os ( "CMAKE_GENERATOR" ) ) ;
433
+ . or_else ( || self . getenv_target_os ( "CMAKE_GENERATOR" ) ) ;
430
434
431
- let host = self . host . clone ( ) . unwrap_or_else ( || getenv_unwrap ( "HOST" ) ) ;
432
435
let msvc = target. contains ( "msvc" ) ;
433
436
let ndk = self . uses_android_ndk ( ) ;
434
437
let mut c_cfg = self . c_cfg . clone ( ) . unwrap_or_default ( ) ;
@@ -483,12 +486,16 @@ impl Config {
483
486
cmake_prefix_path. push ( PathBuf :: from ( root) ) ;
484
487
}
485
488
}
486
- let system_prefix = env:: var_os ( "CMAKE_PREFIX_PATH" ) . unwrap_or ( OsString :: new ( ) ) ;
489
+ let system_prefix = self
490
+ . getenv_target_os ( "CMAKE_PREFIX_PATH" )
491
+ . unwrap_or ( OsString :: new ( ) ) ;
487
492
cmake_prefix_path. extend ( env:: split_paths ( & system_prefix) . map ( |s| s. to_owned ( ) ) ) ;
488
493
let cmake_prefix_path = env:: join_paths ( & cmake_prefix_path) . unwrap ( ) ;
489
494
490
495
// Build up the first cmake command to build the build system.
491
- let executable = env:: var ( "CMAKE" ) . unwrap_or ( "cmake" . to_owned ( ) ) ;
496
+ let executable = self
497
+ . getenv_target_os ( "CMAKE" )
498
+ . unwrap_or ( OsString :: from ( "cmake" ) ) ;
492
499
let mut cmd = Command :: new ( & executable) ;
493
500
494
501
if self . verbose_cmake {
@@ -607,7 +614,7 @@ impl Config {
607
614
if let Some ( ref generator) = generator {
608
615
cmd. arg ( "-G" ) . arg ( generator) ;
609
616
}
610
- let profile = self . get_profile ( ) ;
617
+ let profile = self . get_profile ( ) . to_string ( ) ;
611
618
for & ( ref k, ref v) in & self . defines {
612
619
let mut os = OsString :: from ( "-D" ) ;
613
620
os. push ( k) ;
@@ -735,8 +742,10 @@ impl Config {
735
742
}
736
743
737
744
if !self . defined ( "CMAKE_TOOLCHAIN_FILE" ) {
738
- if let Ok ( s) = env:: var ( "CMAKE_TOOLCHAIN_FILE" ) {
739
- cmd. arg ( & format ! ( "-DCMAKE_TOOLCHAIN_FILE={}" , s) ) ;
745
+ if let Some ( s) = self . getenv_target_os ( "CMAKE_TOOLCHAIN_FILE" ) {
746
+ let mut cmake_toolchain_file = OsString :: from ( "-DCMAKE_TOOLCHAIN_FILE=" ) ;
747
+ cmake_toolchain_file. push ( & s) ;
748
+ cmd. arg ( cmake_toolchain_file) ;
740
749
}
741
750
}
742
751
@@ -823,6 +832,32 @@ impl Config {
823
832
return dst;
824
833
}
825
834
835
+ fn getenv_os ( & mut self , v : & str ) -> Option < OsString > {
836
+ if let Some ( val) = self . env_cache . get ( v) {
837
+ return val. clone ( ) ;
838
+ }
839
+ let r = env:: var_os ( v) ;
840
+ println ! ( "{} = {:?}" , v, r) ;
841
+ self . env_cache . insert ( v. to_string ( ) , r. clone ( ) ) ;
842
+ r
843
+ }
844
+
845
+ /// Gets a target-specific environment variable.
846
+ fn getenv_target_os ( & mut self , var_base : & str ) -> Option < OsString > {
847
+ let host = self . host . clone ( ) . unwrap_or_else ( || getenv_unwrap ( "HOST" ) ) ;
848
+ let target = self
849
+ . target
850
+ . clone ( )
851
+ . unwrap_or_else ( || getenv_unwrap ( "TARGET" ) ) ;
852
+
853
+ let kind = if host == target { "HOST" } else { "TARGET" } ;
854
+ let target_u = target. replace ( "-" , "_" ) ;
855
+ self . getenv_os ( & format ! ( "{}_{}" , var_base, target) )
856
+ . or_else ( || self . getenv_os ( & format ! ( "{}_{}" , var_base, target_u) ) )
857
+ . or_else ( || self . getenv_os ( & format ! ( "{}_{}" , kind, var_base) ) )
858
+ . or_else ( || self . getenv_os ( var_base) )
859
+ }
860
+
826
861
fn visual_studio_generator ( & self , target : & str ) -> String {
827
862
use cc:: windows_registry:: { find_vs_version, VsVers } ;
828
863
@@ -836,7 +871,7 @@ impl Config {
836
871
doesn't know how to generate cmake files for it, \
837
872
can the `cmake` crate be updated?"
838
873
) ,
839
- Err ( msg) => panic ! ( msg) ,
874
+ Err ( msg) => panic ! ( "{}" , msg) ,
840
875
} ;
841
876
if [ "i686" , "x86_64" , "thumbv7a" , "aarch64" ]
842
877
. iter ( )
0 commit comments