1
+ use std:: env;
2
+ use std:: process:: Command ;
3
+ use std:: sync:: { Once , ONCE_INIT } ;
4
+ use std:: sync:: atomic:: { AtomicBool , ATOMIC_BOOL_INIT , Ordering } ;
5
+
6
+ use support:: { project, main_file, basic_bin_manifest} ;
7
+
8
+ pub fn disabled ( ) -> bool {
9
+ // First, disable if ./configure requested so
10
+ match env:: var ( "CFG_DISABLE_CROSS_TESTS" ) {
11
+ Ok ( ref s) if * s == "1" => return true ,
12
+ _ => { }
13
+ }
14
+
15
+ // Right now the windows bots cannot cross compile due to the mingw setup,
16
+ // so we disable ourselves on all but macos/linux setups where the rustc
17
+ // install script ensures we have both architectures
18
+ if !( cfg ! ( target_os = "macos" ) ||
19
+ cfg ! ( target_os = "linux" ) ||
20
+ cfg ! ( target_env = "msvc" ) ) {
21
+ return true ;
22
+ }
23
+
24
+ // It's not particularly common to have a cross-compilation setup, so
25
+ // try to detect that before we fail a bunch of tests through no fault
26
+ // of the user.
27
+ static CAN_RUN_CROSS_TESTS : AtomicBool = ATOMIC_BOOL_INIT ;
28
+ static CHECK : Once = ONCE_INIT ;
29
+
30
+ let cross_target = alternate ( ) ;
31
+
32
+ CHECK . call_once ( || {
33
+ let p = project ( "cross_test" )
34
+ . file ( "Cargo.toml" , & basic_bin_manifest ( "cross_test" ) )
35
+ . file ( "src/cross_test.rs" , & main_file ( r#""testing!""# , & [ ] ) ) ;
36
+
37
+ let result = p. cargo_process ( "build" )
38
+ . arg ( "--target" ) . arg ( & cross_target)
39
+ . exec_with_output ( ) ;
40
+
41
+ if result. is_ok ( ) {
42
+ CAN_RUN_CROSS_TESTS . store ( true , Ordering :: SeqCst ) ;
43
+ }
44
+ } ) ;
45
+
46
+ if CAN_RUN_CROSS_TESTS . load ( Ordering :: SeqCst ) {
47
+ // We were able to compile a simple project, so the user has the
48
+ // necessary std:: bits installed. Therefore, tests should not
49
+ // be disabled.
50
+ return false ;
51
+ }
52
+
53
+ // We can't compile a simple cross project. We want to warn the user
54
+ // by failing a single test and having the remainder of the cross tests
55
+ // pass. We don't use std::sync::Once here because panicing inside its
56
+ // call_once method would poison the Once instance, which is not what
57
+ // we want.
58
+ static HAVE_WARNED : AtomicBool = ATOMIC_BOOL_INIT ;
59
+
60
+ if HAVE_WARNED . swap ( true , Ordering :: SeqCst ) {
61
+ // We are some other test and somebody else is handling the warning.
62
+ // Just disable the current test.
63
+ return true ;
64
+ }
65
+
66
+ // We are responsible for warning the user, which we do by panicing.
67
+ let rustup_available = Command :: new ( "rustup" ) . output ( ) . is_ok ( ) ;
68
+
69
+ let linux_help = if cfg ! ( target_os = "linux" ) {
70
+ "
71
+
72
+ You may need to install runtime libraries for your Linux distribution as well." . to_string ( )
73
+ } else {
74
+ "" . to_string ( )
75
+ } ;
76
+
77
+ let rustup_help = if rustup_available {
78
+ format ! ( "
79
+
80
+ Alternatively, you can install the necessary libraries for cross-compilation with
81
+
82
+ rustup target add {}{}" , cross_target, linux_help)
83
+ } else {
84
+ "" . to_string ( )
85
+ } ;
86
+
87
+ panic ! ( "Cannot cross compile to {}.
88
+
89
+ This failure can be safely ignored. If you would prefer to not see this
90
+ failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \" 1\" .{}
91
+ " , cross_target, rustup_help) ;
92
+ }
93
+
94
+ pub fn alternate ( ) -> String {
95
+ let platform = match env:: consts:: OS {
96
+ "linux" => "unknown-linux-gnu" ,
97
+ "macos" => "apple-darwin" ,
98
+ "windows" => "pc-windows-msvc" ,
99
+ _ => unreachable ! ( ) ,
100
+ } ;
101
+ let arch = match env:: consts:: ARCH {
102
+ "x86" => "x86_64" ,
103
+ "x86_64" => "i686" ,
104
+ _ => unreachable ! ( ) ,
105
+ } ;
106
+ format ! ( "{}-{}" , arch, platform)
107
+ }
108
+
109
+ pub fn alternate_arch ( ) -> & ' static str {
110
+ match env:: consts:: ARCH {
111
+ "x86" => "x86_64" ,
112
+ "x86_64" => "x86" ,
113
+ _ => unreachable ! ( ) ,
114
+ }
115
+ }
116
+
117
+ pub fn host ( ) -> String {
118
+ let platform = match env:: consts:: OS {
119
+ "linux" => "unknown-linux-gnu" ,
120
+ "macos" => "apple-darwin" ,
121
+ "windows" => "pc-windows-msvc" ,
122
+ _ => unreachable ! ( ) ,
123
+ } ;
124
+ let arch = match env:: consts:: ARCH {
125
+ "x86" => "i686" ,
126
+ "x86_64" => "x86_64" ,
127
+ _ => unreachable ! ( ) ,
128
+ } ;
129
+ format ! ( "{}-{}" , arch, platform)
130
+ }
0 commit comments