1
- //! Script to invoke the bundled rust-lld with the correct flavor. The flavor is selected by
2
- //! feature.
1
+ //! Script to invoke the bundled rust-lld with the correct flavor.
3
2
//!
4
3
//! lld supports multiple command line interfaces. If `-flavor <flavor>` are passed as the first
5
4
//! two arguments the `<flavor>` command line interface is used to process the remaining arguments.
8
7
//! In Rust with `-Z gcc-ld=lld` we have gcc or clang invoke rust-lld. Since there is no way to
9
8
//! make gcc/clang pass `-flavor <flavor>` as the first two arguments in the linker invocation
10
9
//! and since Windows does not support symbolic links for files this wrapper is used in place of a
11
- //! symbolic link. It execs `../rust-lld -flavor ld` if the feature `ld` is enabled and
12
- //! `../rust-lld -flavor ld64` if `ld64` is enabled . On Windows it spawns a `..\rust-lld.exe`
10
+ //! symbolic link. It execs `../rust-lld -flavor <flavor>` by propagating the flavor argument
11
+ //! passed to the wrapper as the first two arguments . On Windows it spawns a `..\rust-lld.exe`
13
12
//! child process.
14
13
15
- #[ cfg( not( any( feature = "ld" , feature = "ld64" ) ) ) ]
16
- compile_error ! ( "One of the features ld and ld64 must be enabled." ) ;
17
-
18
- #[ cfg( all( feature = "ld" , feature = "ld64" ) ) ]
19
- compile_error ! ( "Only one of the feature ld or ld64 can be enabled." ) ;
20
-
21
- #[ cfg( feature = "ld" ) ]
22
- const FLAVOR : & str = "ld" ;
23
-
24
- #[ cfg( feature = "ld64" ) ]
25
- const FLAVOR : & str = "ld64" ;
26
-
27
- use std:: env;
28
14
use std:: fmt:: Display ;
29
15
use std:: path:: { Path , PathBuf } ;
30
- use std:: process;
16
+ use std:: { env , process} ;
31
17
32
- trait ResultExt < T , E > {
18
+ trait UnwrapOrExitWith < T > {
33
19
fn unwrap_or_exit_with ( self , context : & str ) -> T ;
34
20
}
35
21
36
- impl < T , E > ResultExt < T , E > for Result < T , E >
37
- where
38
- E : Display ,
39
- {
22
+ impl < T > UnwrapOrExitWith < T > for Option < T > {
40
23
fn unwrap_or_exit_with ( self , context : & str ) -> T {
41
- match self {
42
- Ok ( t) => t,
43
- Err ( e) => {
44
- eprintln ! ( "lld-wrapper: {}: {}" , context, e) ;
45
- process:: exit ( 1 ) ;
46
- }
47
- }
24
+ self . unwrap_or_else ( || {
25
+ eprintln ! ( "lld-wrapper: {}" , context) ;
26
+ process:: exit ( 1 ) ;
27
+ } )
48
28
}
49
29
}
50
30
51
- trait OptionExt < T > {
52
- fn unwrap_or_exit_with ( self , context : & str ) -> T ;
53
- }
54
-
55
- impl < T > OptionExt < T > for Option < T > {
31
+ impl < T , E : Display > UnwrapOrExitWith < T > for Result < T , E > {
56
32
fn unwrap_or_exit_with ( self , context : & str ) -> T {
57
- match self {
58
- Some ( t) => t,
59
- None => {
60
- eprintln ! ( "lld-wrapper: {}" , context) ;
61
- process:: exit ( 1 ) ;
62
- }
63
- }
33
+ self . unwrap_or_else ( |err| {
34
+ eprintln ! ( "lld-wrapper: {}: {}" , context, err) ;
35
+ process:: exit ( 1 ) ;
36
+ } )
64
37
}
65
38
}
66
39
@@ -81,14 +54,28 @@ fn get_rust_lld_path(current_exe_path: &Path) -> PathBuf {
81
54
}
82
55
83
56
/// Returns the command for invoking rust-lld with the correct flavor.
57
+ /// LLD only accepts the flavor argument at the first two arguments, so move it there.
84
58
///
85
59
/// Exits on error.
86
60
fn get_rust_lld_command ( current_exe_path : & Path ) -> process:: Command {
87
61
let rust_lld_path = get_rust_lld_path ( current_exe_path) ;
88
62
let mut command = process:: Command :: new ( rust_lld_path) ;
63
+
64
+ let mut flavor = None ;
65
+ let args = env:: args_os ( )
66
+ . skip ( 1 )
67
+ . filter ( |arg| match arg. to_str ( ) . and_then ( |s| s. strip_prefix ( "-rustc-lld-flavor=" ) ) {
68
+ Some ( suffix) => {
69
+ flavor = Some ( suffix. to_string ( ) ) ;
70
+ false
71
+ }
72
+ None => true ,
73
+ } )
74
+ . collect :: < Vec < _ > > ( ) ;
75
+
89
76
command. arg ( "-flavor" ) ;
90
- command. arg ( FLAVOR ) ;
91
- command. args ( env :: args_os ( ) . skip ( 1 ) ) ;
77
+ command. arg ( flavor . unwrap_or_exit_with ( "-rustc-lld-flavor=<flavor> is not passed" ) ) ;
78
+ command. args ( args ) ;
92
79
command
93
80
}
94
81
@@ -101,20 +88,14 @@ fn exec_lld(mut command: process::Command) {
101
88
102
89
#[ cfg( not( unix) ) ]
103
90
fn exec_lld ( mut command : process:: Command ) {
104
- // Windows has no exec(), spawn a child process and wait for it
91
+ // Windows has no exec(), spawn a child process and wait for it.
105
92
let exit_status = command. status ( ) . unwrap_or_exit_with ( "error running rust-lld child process" ) ;
106
- if !exit_status. success ( ) {
107
- match exit_status. code ( ) {
108
- Some ( code) => {
109
- // return the original lld exit code
110
- process:: exit ( code)
111
- }
112
- None => {
113
- eprintln ! ( "lld-wrapper: rust-lld child process exited with error: {}" , exit_status, ) ;
114
- process:: exit ( 1 ) ;
115
- }
116
- }
117
- }
93
+ let code = exit_status
94
+ . code ( )
95
+ . ok_or ( exit_status)
96
+ . unwrap_or_exit_with ( "rust-lld child process exited with error" ) ;
97
+ // Return the original lld exit code.
98
+ process:: exit ( code) ;
118
99
}
119
100
120
101
fn main ( ) {
0 commit comments