1
1
//! Command-line argument parser
2
2
3
- use std:: path:: PathBuf ;
4
-
5
- use lazy_static:: lazy_static;
6
- use regex:: Regex ;
7
-
8
3
use crate :: {
9
- config:: RLLVM_CONFIG ,
10
- constants:: { ARG_EXACT_MATCH_MAP , ARG_PATTERNS } ,
4
+ config:: rllvm_config ,
5
+ constants:: { arg_exact_match_map , arg_patterns } ,
11
6
error:: Error ,
12
7
utils:: * ,
13
8
} ;
9
+ use regex:: Regex ;
10
+ use std:: { path:: PathBuf , sync:: OnceLock } ;
14
11
15
12
/// Compile mode
16
13
#[ derive( Debug ) ]
@@ -93,10 +90,9 @@ impl CompilerArgsInfo {
93
90
self . input_files . push ( flag. as_ref ( ) . to_string ( ) ) ;
94
91
95
92
// Assembly files
96
- lazy_static ! {
97
- static ref RE : Regex = Regex :: new( r"\.(s|S)$" ) . unwrap( ) ;
98
- }
99
- if RE . is_match ( flag. as_ref ( ) ) {
93
+ static RE : OnceLock < Regex > = OnceLock :: new ( ) ;
94
+ let re = RE . get_or_init ( || Regex :: new ( r"\.(s|S)$" ) . unwrap ( ) ) ;
95
+ if re. is_match ( flag. as_ref ( ) ) {
100
96
self . is_assembly = true ;
101
97
}
102
98
@@ -313,7 +309,7 @@ impl CompilerArgsInfo {
313
309
let mut offset = 1 ;
314
310
315
311
// Try to match the flag exactly
316
- if let Some ( arg_info) = ARG_EXACT_MATCH_MAP . get ( arg. as_str ( ) ) {
312
+ if let Some ( arg_info) = arg_exact_match_map ( ) . get ( arg. as_str ( ) ) {
317
313
// Consume more parameters
318
314
offset += self . consume_params ( i, arg. to_string ( ) , arg_info, & args) ;
319
315
} else if arg == "-Wl,--start-group" {
@@ -335,7 +331,7 @@ impl CompilerArgsInfo {
335
331
} else {
336
332
// Try to match a pattern
337
333
let mut matched = false ;
338
- for arg_pattern in ARG_PATTERNS . iter ( ) {
334
+ for arg_pattern in arg_patterns ( ) . iter ( ) {
339
335
let pattern = & arg_pattern. pattern ;
340
336
let arg_info = & arg_pattern. arg_info ;
341
337
if pattern. is_match ( arg. as_str ( ) ) {
@@ -435,7 +431,7 @@ impl CompilerArgsInfo {
435
431
436
432
let conditions = [
437
433
(
438
- RLLVM_CONFIG . is_configure_only ( ) ,
434
+ rllvm_config ( ) . is_configure_only ( ) ,
439
435
"we are in configure-only mode" ,
440
436
) ,
441
437
(
@@ -506,7 +502,7 @@ impl CompilerArgsInfo {
506
502
derive_object_and_bitcode_filepath ( & src_filepath, self . is_compile_only ) ?;
507
503
508
504
// Update the bitcode filepath, if the bitcode store path is provided
509
- if let Some ( bitcode_store_path) = RLLVM_CONFIG . bitcode_store_path ( ) {
505
+ if let Some ( bitcode_store_path) = rllvm_config ( ) . bitcode_store_path ( ) {
510
506
if bitcode_store_path. exists ( ) {
511
507
// Obtain a new bitcode filename based on the hash of the source filepath
512
508
if bitcode_filepath. file_name ( ) . is_some ( ) {
@@ -536,3 +532,45 @@ impl CompilerArgsInfo {
536
532
Ok ( artifacts)
537
533
}
538
534
}
535
+
536
+ #[ cfg( test) ]
537
+ mod tests {
538
+ use super :: CompilerArgsInfo ;
539
+
540
+ fn test_parsing < F > ( input : & str , check_func : F )
541
+ where
542
+ F : Fn ( & CompilerArgsInfo ) -> bool ,
543
+ {
544
+ let mut args_info = CompilerArgsInfo :: default ( ) ;
545
+ let args: Vec < & str > = input. split_ascii_whitespace ( ) . collect ( ) ;
546
+ let ret = args_info. parse_args ( & args) ;
547
+ assert ! ( ret. is_ok( ) ) ;
548
+ assert ! ( check_func( ret. unwrap( ) ) ) ;
549
+ }
550
+
551
+ fn test_parsing_lto_internal ( input : & str ) {
552
+ test_parsing ( input, |args| args. is_lto ( ) ) ;
553
+ }
554
+
555
+ #[ test]
556
+ fn test_parsing_lto ( ) {
557
+ let input = r#"-pthread -c -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -g -fdebug-prefix-map=/home/legend/makepkgs/python/src=/usr/src/debug -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -g -fdebug-prefix-map=/home/legend/makepkgs/python/src=/usr/src/debug -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -g -fdebug-prefix-map=/home/legend/makepkgs/python/src=/usr/src/debug -fno-semantic-interposition -flto -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -fprofile-instr-use=code.profclangd -I./Include/internal -I. -I./Include -D_FORTIFY_SOURCE=2 -D_FORTIFY_SOURCE=2 -fPIC -DPy_BUILD_CORE -DSOABI='"cpython-38-x86_64-linux-gnu"' -o Python/dynload_shlib.o ./Python/dynload_shlib.c"# ;
558
+ test_parsing_lto_internal ( input) ;
559
+
560
+ let input = r#"-pthread -c -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -g -fdebug-prefix-map=/home/legend/makepkgs/python/src=/usr/src/debug -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -g -fdebug-prefix-map=/home/legend/makepkgs/python/src=/usr/src/debug -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -g -fdebug-prefix-map=/home/legend/makepkgs/python/src=/usr/src/debug -fno-semantic-interposition -flto=thin -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -fprofile-instr-use=code.profclangd -I./Include/internal -I. -I./Include -D_FORTIFY_SOURCE=2 -D_FORTIFY_SOURCE=2 -fPIC -DPy_BUILD_CORE -DSOABI='"cpython-38-x86_64-linux-gnu"' -o Python/dynload_shlib.o ./Python/dynload_shlib.c"# ;
561
+ test_parsing_lto_internal ( input) ;
562
+ }
563
+
564
+ fn test_parsing_link_args_internal ( input : & str , expected : usize ) {
565
+ test_parsing ( input, |args| args. link_args ( ) . len ( ) == expected) ;
566
+ }
567
+
568
+ #[ test]
569
+ fn test_parsing_link_args ( ) {
570
+ let input = r#"-Wl,--fatal-warnings -Wl,--build-id=sha1 -fPIC -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,-z,defs -Wl,--as-needed -fuse-ld=lld -Wl,--icf=all -Wl,--color-diagnostics -flto=thin -Wl,--thinlto-jobs=8 -Wl,--thinlto-cache-dir=thinlto-cache -Wl,--thinlto-cache-policy,cache_size=10\%:cache_size_bytes=10g:cache_size_files=100000 -Wl,--lto-O0 -fwhole-program-vtables -Wl,--no-call-graph-profile-sort -m64 -Wl,-O2 -Wl,--gc-sections -Wl,--gdb-index -rdynamic -fsanitize=cfi-vcall -fsanitize=cfi-icall -pie -Wl,--disable-new-dtags -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -o "./brotli" -Wl,--start-group @"./brotli.rsp" -Wl,--end-group -latomic -ldl -lpthread -lrt"# ;
571
+ test_parsing_link_args_internal ( input, 32 ) ;
572
+
573
+ let input = r#"1.c 2.c 3.c 4.c 5.c -Wl,--start-group 7.o 8.o 9.o -Wl,--end-group 10.c 11.c 12.c 13.c"# ;
574
+ test_parsing_link_args_internal ( input, 5 ) ;
575
+ }
576
+ }
0 commit comments