@@ -6,6 +6,32 @@ use std::path::Path;
6
6
use std:: process:: { Command , Stdio } ;
7
7
use std:: ffi:: OsString ;
8
8
9
+ fn is_cargo ( path : & str ) -> bool {
10
+ let output = Command :: new ( path) . arg ( "-V" ) . output ( ) ;
11
+ if let Ok ( output) = Command :: new ( path) . arg ( "-V" ) . output ( ) {
12
+ let s = String :: from_utf8_lossy ( & output. stdout ) ;
13
+ if s. contains ( "cargo" ) {
14
+ return true ;
15
+ }
16
+ }
17
+
18
+ false
19
+ }
20
+
21
+ fn find_cargo_path ( ) -> Option < String > {
22
+ let mut p: Vec < String > = vec ! [ "cargo" . to_string( ) ] ;
23
+ if let Some ( home) = env:: home_dir ( ) {
24
+ p. push ( format ! ( "{}/.cargo/bin/cargo" , home. display( ) ) ) ;
25
+ }
26
+
27
+ for path in p {
28
+ if is_cargo ( & path) {
29
+ return Some ( path. into ( ) ) ;
30
+ }
31
+ }
32
+
33
+ None
34
+ }
9
35
10
36
#[ derive( Clone , Debug ) ]
11
37
pub struct FoundFile {
@@ -47,104 +73,76 @@ pub struct CrossbuildOptions {
47
73
#[ derive( Debug ) ]
48
74
pub struct CrossbuiltTests {
49
75
pub object_paths : Vec < String > ,
50
- pub tests : Vec < String >
76
+ pub tests : Vec < String > ,
77
+ pub library_path : String
51
78
}
52
79
53
80
pub fn crossbuild_rust_tests ( options : & CrossbuildOptions ) -> CrossbuiltTests {
54
81
82
+ // check if we can find cargo for cross building
83
+ let cargo_path = find_cargo_path ( ) ;
84
+ let cargo_path = cargo_path. expect ( "Cargo not found! Install Rust's package manager." ) ;
85
+
55
86
let build_proj_root = {
56
87
let p = Path :: new ( & options. tests_project_path ) ;
57
88
let mut absolute_path = :: std:: env:: current_dir ( ) . expect ( "Can't find current dir?" ) ;
58
89
absolute_path. push ( p) ;
59
90
p. canonicalize ( ) . expect ( "Error canonicalizing" )
60
91
} ;
61
92
62
- // cross-build the tests library
63
- let cargo_build = Command :: new ( "cargo" )
64
- . current_dir ( & options. tests_project_path )
65
- . arg ( "build" )
66
- . arg ( "--verbose" )
67
- . arg ( "--target" )
68
- . arg ( & options. target_arch )
69
- . env ( "CARGO_INCREMENTAL" , "" )
70
- . env ( "RUSTFLAGS" , "--emit=obj" )
71
- . env ( "RUST_TARGET_PATH" , & build_proj_root. to_str ( ) . expect ( "Missing path to proj root for target path?" ) )
72
- . stdout ( Stdio :: inherit ( ) )
73
- . stderr ( Stdio :: inherit ( ) )
74
- . output ( ) ;
75
-
76
- let output = cargo_build. expect ( "Cargo build of the tests projects failed" ) ;
77
- if !output. status . success ( ) {
78
- panic ! ( "cargo build failed" ) ;
79
- }
80
-
81
93
// grab the list of tests to compile binaries for
82
- let tests = {
83
- // slightly hackish way that requires each test entrypoint to be in its
84
- // own source file with a matching name
85
-
86
- let dir = format ! ( "{}/src/" , & options. tests_project_path) ;
94
+ let tests: Vec < _ > = {
95
+ let dir = format ! ( "{}/examples/" , & options. tests_project_path) ;
87
96
let tests = find_files ( & dir, |n| {
88
97
n. starts_with ( "test_" ) && n. ends_with ( ".rs" )
89
98
} ) . iter ( ) . cloned ( ) . map ( |f| f. name ) . map ( |n| { n. replace ( ".rs" , "" ) } ) . collect ( ) ;
90
99
91
100
tests
92
101
} ;
93
-
94
- let object_paths = {
95
- let active_toolchain : String = {
96
- let output = Command :: new ( "rustup" )
97
- . arg ( "show" )
98
- . arg ( "active-toolchain" )
99
- . stderr ( Stdio :: inherit ( ) )
100
- . output ( )
101
- . expect ( "Can't get a current toolchain" ) ;
102
-
103
- let active_toolchain = String :: from_utf8_lossy ( & output . stdout ) ;
104
- let mut split = active_toolchain . split_whitespace ( ) ;
105
- split . next ( ) . expect ( "active toolchain missing" ) . trim ( ) . to_owned ( )
106
- } ;
107
-
108
- let rustup_sysroot = {
109
- let home = env:: home_dir ( ) . expect ( "missing profile home dir" ) ;
110
- format ! ( "{}/.rustup/toolchains/{}/lib/rustlib/{}/lib/" ,
111
- home . to_str ( ) . unwrap ( ) , active_toolchain , & options . target_arch )
112
- } ;
113
-
114
- let mut sysroot_rlibs : Vec < FoundFile > = find_files ( & rustup_sysroot , |n| {
115
- n . ends_with ( ".rlib" )
116
- } ) . iter ( ) . cloned ( ) . collect ( ) ;
117
-
118
- let tests_deps_dir = format ! ( "{}/target/{}/debug/deps/" , & options . tests_project_path , & options . target_arch ) ;
119
-
120
- for sysroot_rlib in sysroot_rlibs {
121
- copy ( sysroot_rlib . absolute_path , format ! ( "{}/{}.o" , tests_deps_dir , sysroot_rlib . name . trim_right_matches ( ".rlib" ) ) ) ;
102
+ let mut built_tests = vec ! [ ] ;
103
+
104
+ for test in & tests {
105
+ // cross-build the tests library
106
+ let cargo_build = Command :: new ( & cargo_path )
107
+ . current_dir ( & options . tests_project_path )
108
+ . arg ( "build" )
109
+
110
+ . arg ( "--example" )
111
+ . arg ( test )
112
+
113
+ . arg ( "--verbose" )
114
+
115
+ . arg ( "--target" )
116
+ . arg ( & options . target_arch )
117
+
118
+ //. env("RUSTFLAGS", "-C linker=arm-none-eabi-gcc -Z linker-flavor=gcc")
119
+
120
+ . env ( "CARGO_INCREMENTAL" , "0" )
121
+ //.env("RUSTFLAGS", "--emit=obj")
122
+ //.env("RUST_TARGET_PATH", &build_proj_root.to_str().expect("Missing path to proj root for target path?"))
123
+
124
+ . stdout ( Stdio :: inherit ( ) )
125
+ . stderr ( Stdio :: inherit ( ) )
126
+ . output ( ) ;
127
+
128
+ let output = cargo_build . expect ( "Cargo build of the tests projects failed" ) ;
129
+ if !output . status . success ( ) {
130
+ panic ! ( "Cargo build failed" ) ;
122
131
}
123
132
124
- let mut test_objects: Vec < _ > = find_files ( & tests_deps_dir, |n| {
125
- n. ends_with ( ".o" )
126
- } ) . iter ( ) . cloned ( ) . collect ( ) ;
127
-
128
- test_objects. sort_by_key ( |f| {
129
- if f. name . contains ( "freertos_rs" ) { 0 }
130
- else if f. name . contains ( "lazy_static" ) { 1 }
131
- else if f. name . contains ( "liballoc" ) { 2 }
132
- else if f. name . contains ( "libcompiler_builtins" ) { 3 }
133
- else if f. name . contains ( "libcore" ) { 4 }
134
- else if f. name . contains ( "librustc_std_workspace_core" ) { 5 }
135
- else { 6 }
136
- } ) ;
137
-
138
- let mut test_objects: Vec < _ > = test_objects. into_iter ( ) . map ( |f| f. absolute_path ) . collect ( ) ;
133
+ built_tests. push ( test. clone ( ) ) ;
134
+ }
139
135
140
- let mut objects = vec ! [ ] ;
141
- objects. append ( & mut test_objects) ;
142
- objects
136
+ let library_path = {
137
+ let p = format ! ( "{}/target/{}/debug/examples/" , & options. tests_project_path, & options. target_arch) ;
138
+ let p = Path :: new ( & p) ;
139
+ p. canonicalize ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . into ( )
143
140
} ;
144
-
141
+
145
142
CrossbuiltTests {
146
- object_paths : object_paths,
147
- tests : tests
143
+ object_paths : vec ! [ ] ,
144
+ tests : built_tests,
145
+ library_path : library_path
148
146
}
149
147
}
150
148
@@ -168,19 +166,28 @@ pub fn build_test_binaries(options: &CrossbuildOptions, tests: &CrossbuiltTests)
168
166
for test in & tests. tests {
169
167
let mut test_renames = "" . to_string ( ) ;
170
168
169
+ /*
171
170
if test.contains("isr_timer4") {
172
171
test_renames.push_str(&format!("testbed_timer4_isr = {}_timer4_isr;", test));
173
172
}
173
+ */
174
+
175
+
176
+ let mut test_deps = vec ! [
177
+ format!( "{}/lib{}.a" , & tests. library_path, & test)
178
+ ] ;
174
179
175
180
let test_binary_build = Command :: new ( "make" )
176
181
. current_dir ( & gcc_proj_dir)
177
- . env ( "TEST_ENTRY" , test. clone ( ) )
182
+ . env ( "TEST_NAME" , test. clone ( ) )
183
+ . env ( "TEST_LIBRARY_PATH" , format ! ( "-L {}" , & tests. library_path) )
184
+ . env ( "TEST_LIBRARY_PRE" , format ! ( "-l:lib{}.a" , & test) )
178
185
. env ( "TEST_OBJECTS" , & test_objects)
186
+ . env ( "TEST_DEPS" , test_deps. join ( " " ) )
179
187
. env ( "TEST_RENAMES" , test_renames)
180
188
. stdout ( Stdio :: inherit ( ) )
181
189
. stderr ( Stdio :: inherit ( ) )
182
190
. output ( ) ;
183
-
184
191
let output = test_binary_build. unwrap ( ) ;
185
192
if !output. status . success ( ) {
186
193
panic ! ( format!( "GCC ARM build for '{}' failed" , test) ) ;
0 commit comments