11// NOTE: Adapted from cortex-m/build.rs
22
3- use std:: { collections:: HashSet , env, fs, io, path:: PathBuf } ;
3+ use riscv_target_parser:: RiscvTarget ;
4+ use std:: { env, fs, io, path:: PathBuf } ;
5+
6+ // List of all possible RISC-V configurations to check for in risv-rt
7+ const RISCV_CFG : [ & str ; 4 ] = [ "riscvi" , "riscvm" , "riscvf" , "riscvd" ] ;
48
59fn add_linker_script ( arch_width : u32 ) -> io:: Result < ( ) > {
610 // Read the file to a string and replace all occurrences of ${ARCH_WIDTH} with the arch width
@@ -17,96 +21,39 @@ fn add_linker_script(arch_width: u32) -> io::Result<()> {
1721 Ok ( ( ) )
1822}
1923
20- /// Parse the target RISC-V architecture and returns its bit width and the extension set
21- fn parse_target ( target : & str , cargo_flags : & str ) -> ( u32 , HashSet < char > ) {
22- // isolate bit width and extensions from the rest of the target information
23- let arch = target
24- . trim_start_matches ( "riscv" )
25- . split ( '-' )
26- . next ( )
27- . unwrap ( ) ;
28-
29- let bits = arch
30- . chars ( )
31- . take_while ( |c| c. is_ascii_digit ( ) )
32- . collect :: < String > ( )
33- . parse :: < u32 > ( )
34- . unwrap ( ) ;
35-
36- let mut extensions: HashSet < char > = arch. chars ( ) . skip_while ( |c| c. is_ascii_digit ( ) ) . collect ( ) ;
37- // expand the 'g' shorthand extension
38- if extensions. contains ( & 'g' ) {
39- extensions. insert ( 'i' ) ;
40- extensions. insert ( 'm' ) ;
41- extensions. insert ( 'a' ) ;
42- extensions. insert ( 'f' ) ;
43- extensions. insert ( 'd' ) ;
44- }
45-
46- let cargo_flags = cargo_flags
47- . split ( 0x1fu8 as char )
48- . filter ( |arg| !arg. is_empty ( ) ) ;
49-
50- cargo_flags
51- . filter ( |k| k. starts_with ( "target-feature=" ) )
52- . flat_map ( |str| {
53- let flags = str. split ( '=' ) . collect :: < Vec < & str > > ( ) [ 1 ] ;
54- flags. split ( ',' )
55- } )
56- . for_each ( |feature| {
57- let chars = feature. chars ( ) . collect :: < Vec < char > > ( ) ;
58- match chars[ 0 ] {
59- '+' => {
60- extensions. insert ( chars[ 1 ] ) ;
61- }
62- '-' => {
63- extensions. remove ( & chars[ 1 ] ) ;
64- }
65- _ => {
66- panic ! ( "Unsupported target feature operation" ) ;
67- }
68- }
69- } ) ;
70-
71- ( bits, extensions)
72- }
73-
7424fn main ( ) {
75- println ! ( "cargo:rustc-check-cfg=cfg(riscv)" ) ;
76- println ! ( "cargo:rustc-check-cfg=cfg(riscv32)" ) ;
77- println ! ( "cargo:rustc-check-cfg=cfg(riscv64)" ) ;
78- for ext in [ 'i' , 'e' , 'm' , 'a' , 'f' , 'd' , 'g' , 'c' ] {
79- println ! ( "cargo:rustc-check-cfg=cfg(riscv{})" , ext) ;
25+ // Required until target_feature risc-v is stable and in-use (rust 1.75)
26+ for ext in RISCV_CFG . iter ( ) {
27+ println ! ( "cargo:rustc-check-cfg=cfg({ext})" ) ;
8028 }
8129
8230 let target = env:: var ( "TARGET" ) . unwrap ( ) ;
8331 let cargo_flags = env:: var ( "CARGO_ENCODED_RUSTFLAGS" ) . unwrap ( ) ;
84- let _name = env:: var ( "CARGO_PKG_NAME" ) . unwrap ( ) ;
8532
86- // set configuration flags depending on the target
87- if target. starts_with ( "riscv" ) {
88- println ! ( "cargo:rustc-cfg=riscv" ) ;
89- // This is required until target_arch & target_feature risc-v work is
90- // stable and in-use (rust 1.75.0)
91- let ( bits, extensions) = parse_target ( & target, & cargo_flags) ;
92-
93- // generate the linker script and expose the ISA width
94- let arch_width = match bits {
95- 32 => {
96- println ! ( "cargo:rustc-cfg=riscv32" ) ;
97- 4
98- }
99- 64 => {
100- println ! ( "cargo:rustc-cfg=riscv64" ) ;
101- 8
33+ if let Ok ( target) = RiscvTarget :: build ( & target, & cargo_flags) {
34+ let width = target. width ( ) ;
35+
36+ // set environmet variable RISCV_RT_BASE_ISA to the base ISA of the target.
37+ println ! (
38+ "cargo:rustc-env=RISCV_RT_BASE_ISA={}" ,
39+ target. llvm_base_isa( )
40+ ) ;
41+ // set environment variable RISCV_RT_LLVM_ARCH_PATCH to patch LLVM bug.
42+ // (this env variable is temporary and will be removed after LLVM being fixed)
43+ println ! (
44+ "cargo:rustc-env=RISCV_RT_LLVM_ARCH_PATCH={}" ,
45+ target. llvm_arch_patch( )
46+ ) ;
47+ // make sure that these env variables are not changed without notice.
48+ println ! ( "cargo:rerun-if-env-changed=RISCV_RT_BASE_ISA" ) ;
49+ println ! ( "cargo:rerun-if-env-changed=RISCV_RT_LLVM_ARCH_PATCH" ) ;
50+
51+ for flag in target. rustc_flags ( ) {
52+ // Required until target_feature risc-v is stable and in-use
53+ if RISCV_CFG . contains ( & flag. as_str ( ) ) {
54+ println ! ( "cargo:rustc-cfg={flag}" ) ;
10255 }
103- _ => panic ! ( "Unsupported bit width" ) ,
104- } ;
105- add_linker_script ( arch_width) . unwrap ( ) ;
106-
107- // expose the ISA extensions
108- for ext in & extensions {
109- println ! ( "cargo:rustc-cfg=riscv{}" , ext) ;
11056 }
57+ add_linker_script ( width. into ( ) ) . unwrap ( ) ;
11158 }
11259}
0 commit comments