44//!
55//! Also see the docs in `asm.rs`.
66
7- use std:: collections:: BTreeMap ;
8- use std:: env:: current_dir;
9- use std:: fs:: { self , File } ;
10- use std:: path:: Path ;
11- use std:: process:: { Command , Stdio } ;
12-
13- fn toolchain ( ) -> String {
14- fs:: read_to_string ( "cortex-m/asm-toolchain" )
15- . unwrap ( )
16- . trim ( )
17- . to_string ( )
18- }
19-
20- fn rustc ( ) -> Command {
21- let mut cmd = Command :: new ( "rustc" ) ;
22- cmd. arg ( format ! ( "+{}" , toolchain( ) ) ) ;
23- cmd
24- }
25-
26- fn assemble_really ( target : & str , cfgs : & [ & str ] , plugin_lto : bool ) {
27- let mut cmd = rustc ( ) ;
28-
29- // Set the codegen target.
30- cmd. arg ( "--target" ) . arg ( target) ;
31- // Set all the `--cfg` directives for the target.
32- cmd. args ( cfgs. iter ( ) . map ( |cfg| format ! ( "--cfg={}" , cfg) ) ) ;
33-
34- // We want some level of debuginfo to allow unwinding through the functions.
35- cmd. arg ( "-g" ) ;
36- // We always optimize the assembly shims. There's not really any reason not to.
37- cmd. arg ( "-O" ) ;
38-
39- // We use LTO on the archive to ensure the (unused) panic handler is removed, preventing
40- // a linker error when the archives are linked into final crates with two panic handlers.
41- cmd. arg ( "-Clto=yes" ) ;
42-
43- // rustc will usually add frame pointers by default to aid with debugging, but that is a high
44- // overhead for the tiny assembly routines.
45- cmd. arg ( "-Cforce-frame-pointers=no" ) ;
46-
47- // We don't want any system-specific paths to show up since we ship the result to other users.
48- // Add `--remap-path-prefix $(pwd)=.`.
49- let mut dir = current_dir ( )
50- . unwrap ( )
51- . join ( "cortex-m" )
52- . as_os_str ( )
53- . to_os_string ( ) ;
54- dir. push ( "=." ) ;
55- cmd. arg ( "--remap-path-prefix" ) . arg ( dir) ;
56-
57- // We let rustc build a single object file, not a staticlib, since the latter pulls in loads of
58- // code that will never be used (`compiler_builtins` and `core::fmt`, etc.). We build the static
59- // archive by hand after compiling.
60- cmd. arg ( "--emit=obj" ) ;
61-
62- if plugin_lto {
63- // Make artifacts compatible with Linker-Plugin LTO (and incompatible with everything else).
64- cmd. arg ( "-Clinker-plugin-lto" ) ;
65- }
66-
67- let file_stub = if plugin_lto {
68- format ! ( "{}-lto" , target)
69- } else {
70- target. to_string ( )
71- } ;
72-
73- let obj_file = format ! ( "bin/{}.o" , file_stub) ;
74-
75- // Pass output and input file.
76- cmd. arg ( "-o" ) . arg ( & obj_file) ;
77- cmd. arg ( "asm/lib.rs" ) ;
78- cmd. current_dir ( "cortex-m" ) ;
79-
80- println ! ( "{:?}" , cmd) ;
81- let status = cmd. status ( ) . unwrap ( ) ;
82- assert ! ( status. success( ) ) ;
83-
84- let full_obj_file_path = Path :: new ( "cortex-m" ) . join ( & obj_file) ;
85-
86- // Archive `target.o` -> `bin/target.a`.
87- let mut builder =
88- ar:: Builder :: new ( File :: create ( format ! ( "cortex-m/bin/{}.a" , file_stub) ) . unwrap ( ) ) ;
89-
90- // Use `append`, not `append_path`, to avoid adding any filesystem metadata (modification times,
91- // etc.).
92- let file = fs:: read ( & full_obj_file_path) . unwrap ( ) ;
93- builder
94- . append (
95- & ar:: Header :: new ( obj_file. as_bytes ( ) . to_vec ( ) , file. len ( ) as u64 ) ,
96- & * file,
97- )
98- . unwrap ( ) ;
99-
100- fs:: remove_file ( & full_obj_file_path) . unwrap ( ) ;
101- }
102-
103- fn assemble ( target : & str , cfgs : & [ & str ] ) {
104- assemble_really ( target, cfgs, false ) ;
105- assemble_really ( target, cfgs, true ) ;
106- }
107-
108- // `--target` -> `--cfg` list (mirrors what `build.rs` does).
109- static TARGETS : & [ ( & str , & [ & str ] ) ] = & [
110- ( "thumbv6m-none-eabi" , & [ ] ) ,
111- ( "thumbv7m-none-eabi" , & [ "armv7m" ] ) ,
112- ( "thumbv7em-none-eabi" , & [ "armv7m" , "armv7em" ] ) ,
113- ( "thumbv7em-none-eabihf" , & [ "armv7m" , "armv7em" , "has_fpu" ] ) ,
114- ( "thumbv8m.base-none-eabi" , & [ "armv8m" , "armv8m_base" ] ) ,
115- (
116- "thumbv8m.main-none-eabi" ,
117- & [ "armv7m" , "armv8m" , "armv8m_main" ] ,
118- ) ,
119- (
120- "thumbv8m.main-none-eabihf" ,
121- & [ "armv7m" , "armv8m" , "armv8m_main" , "has_fpu" ] ,
122- ) ,
123- ] ;
7+ use std:: process:: Command ;
1248
1259pub fn install_targets ( targets : & mut dyn Iterator < Item = & str > , toolchain : Option < & str > ) {
12610 let mut rustup = Command :: new ( "rustup" ) ;
@@ -134,90 +18,6 @@ pub fn install_targets(targets: &mut dyn Iterator<Item = &str>, toolchain: Optio
13418 assert ! ( status. success( ) , "rustup command failed: {:?}" , rustup) ;
13519}
13620
137- pub fn assemble_blobs ( ) {
138- let mut cmd = rustc ( ) ;
139- cmd. arg ( "-V" ) ;
140- cmd. stdout ( Stdio :: null ( ) ) ;
141- let status = cmd. status ( ) . unwrap ( ) ;
142- let toolchain = toolchain ( ) ;
143-
144- if !status. success ( ) {
145- println ! (
146- "asm toolchain {} does not seem to be installed. installing it now." ,
147- toolchain
148- ) ;
149-
150- let mut rustup = Command :: new ( "rustup" ) ;
151- let status = rustup. arg ( "install" ) . arg ( & toolchain) . status ( ) . unwrap ( ) ;
152- assert ! ( status. success( ) , "rustup command failed: {:?}" , rustup) ;
153- }
154-
155- install_targets (
156- & mut TARGETS . iter ( ) . map ( |( target, _) | * target) ,
157- Some ( & * toolchain) ,
158- ) ;
159-
160- for ( target, cfgs) in TARGETS {
161- println ! ( "building artifacts for {}" , target) ;
162- assemble ( target, cfgs) ;
163- }
164- }
165-
166- pub fn check_blobs ( ) {
167- // Load each `.a` file in `bin` into memory.
168- let mut files_before = BTreeMap :: new ( ) ;
169- for entry in fs:: read_dir ( "cortex-m/bin" ) . unwrap ( ) {
170- let entry = entry. unwrap ( ) ;
171- if entry. path ( ) . extension ( ) . unwrap ( ) == "a" {
172- files_before. insert (
173- entry
174- . path ( )
175- . file_name ( )
176- . unwrap ( )
177- . to_str ( )
178- . unwrap ( )
179- . to_string ( ) ,
180- fs:: read ( entry. path ( ) ) . unwrap ( ) ,
181- ) ;
182- }
183- }
184-
185- assemble_blobs ( ) ;
186-
187- let mut files_after = BTreeMap :: new ( ) ;
188- for entry in fs:: read_dir ( "cortex-m/bin" ) . unwrap ( ) {
189- let entry = entry. unwrap ( ) ;
190- if entry. path ( ) . extension ( ) . unwrap ( ) == "a" {
191- files_after. insert (
192- entry
193- . path ( )
194- . file_name ( )
195- . unwrap ( )
196- . to_str ( )
197- . unwrap ( )
198- . to_string ( ) ,
199- fs:: read ( entry. path ( ) ) . unwrap ( ) ,
200- ) ;
201- }
202- }
203-
204- // Ensure they contain the same files.
205- let before = files_before. keys ( ) . collect :: < Vec < _ > > ( ) ;
206- let after = files_after. keys ( ) . collect :: < Vec < _ > > ( ) ;
207- assert_eq ! ( before, after) ;
208-
209- for ( ( file, before) , ( _, after) ) in files_before. iter ( ) . zip ( files_after. iter ( ) ) {
210- if before != after {
211- panic ! (
212- "{} is not up-to-date, please run `cargo xtask assemble`" ,
213- file
214- ) ;
215- }
216- }
217-
218- println ! ( "Blobs identical." ) ;
219- }
220-
22121// Check that serde and PartialOrd works with VectActive
22222pub fn check_host_side ( ) {
22323 use cortex_m:: peripheral:: scb:: VectActive ;
0 commit comments