10
10
11
11
//! A helper class for dealing with static archives
12
12
13
- use super :: link:: { get_ar_prog} ;
14
- use driver:: session:: Session ;
15
- use metadata:: filesearch;
16
13
use llvm:: { ArchiveRef , llvm} ;
17
14
18
15
use libc;
@@ -24,22 +21,38 @@ use std::os;
24
21
use std:: raw;
25
22
use std:: str;
26
23
use syntax:: abi;
24
+ use ErrorHandler = syntax:: diagnostic:: Handler ;
27
25
28
26
pub static METADATA_FILENAME : & ' static str = "rust.metadata.bin" ;
29
27
28
+ pub struct ArchiveConfig < ' a > {
29
+ pub handler : & ' a ErrorHandler ,
30
+ pub dst : Path ,
31
+ pub lib_search_paths : Vec < Path > ,
32
+ pub os : abi:: Os ,
33
+ pub maybe_ar_prog : Option < String >
34
+ }
35
+
30
36
pub struct Archive < ' a > {
31
- sess : & ' a Session ,
37
+ handler : & ' a ErrorHandler ,
32
38
dst : Path ,
39
+ lib_search_paths : Vec < Path > ,
40
+ os : abi:: Os ,
41
+ maybe_ar_prog : Option < String >
33
42
}
34
43
35
44
pub struct ArchiveRO {
36
45
ptr : ArchiveRef ,
37
46
}
38
47
39
- fn run_ar ( sess : & Session , args : & str , cwd : Option < & Path > ,
48
+ fn run_ar ( handler : & ErrorHandler , maybe_ar_prog : & Option < String > ,
49
+ args : & str , cwd : Option < & Path > ,
40
50
paths : & [ & Path ] ) -> ProcessOutput {
41
- let ar = get_ar_prog ( sess) ;
42
- let mut cmd = Command :: new ( ar. as_slice ( ) ) ;
51
+ let ar = match * maybe_ar_prog {
52
+ Some ( ref ar) => ar. as_slice ( ) ,
53
+ None => "ar"
54
+ } ;
55
+ let mut cmd = Command :: new ( ar) ;
43
56
44
57
cmd. arg ( args) . args ( paths) ;
45
58
debug ! ( "{}" , cmd) ;
@@ -56,42 +69,55 @@ fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>,
56
69
Ok ( prog) => {
57
70
let o = prog. wait_with_output ( ) . unwrap ( ) ;
58
71
if !o. status . success ( ) {
59
- sess . err ( format ! ( "{} failed with: {}" ,
72
+ handler . err ( format ! ( "{} failed with: {}" ,
60
73
cmd,
61
74
o. status) . as_slice ( ) ) ;
62
- sess . note ( format ! ( "stdout ---\n {}" ,
75
+ handler . note ( format ! ( "stdout ---\n {}" ,
63
76
str :: from_utf8( o. output
64
77
. as_slice( ) ) . unwrap( ) )
65
78
. as_slice ( ) ) ;
66
- sess . note ( format ! ( "stderr ---\n {}" ,
79
+ handler . note ( format ! ( "stderr ---\n {}" ,
67
80
str :: from_utf8( o. error
68
81
. as_slice( ) ) . unwrap( ) )
69
82
. as_slice ( ) ) ;
70
- sess . abort_if_errors ( ) ;
83
+ handler . abort_if_errors ( ) ;
71
84
}
72
85
o
73
86
} ,
74
87
Err ( e) => {
75
- sess . err ( format ! ( "could not exec `{}`: {}" , ar. as_slice( ) ,
88
+ handler . err ( format ! ( "could not exec `{}`: {}" , ar. as_slice( ) ,
76
89
e) . as_slice ( ) ) ;
77
- sess . abort_if_errors ( ) ;
90
+ handler . abort_if_errors ( ) ;
78
91
fail ! ( "rustc::back::archive::run_ar() should not reach this point" ) ;
79
92
}
80
93
}
81
94
}
82
95
83
96
impl < ' a > Archive < ' a > {
84
97
/// Initializes a new static archive with the given object file
85
- pub fn create < ' b > ( sess : & ' a Session , dst : & ' b Path ,
86
- initial_object : & ' b Path ) -> Archive < ' a > {
87
- run_ar ( sess, "crus" , None , [ dst, initial_object] ) ;
88
- Archive { sess : sess, dst : dst. clone ( ) }
98
+ pub fn create < ' b > ( config : ArchiveConfig < ' a > , initial_object : & ' b Path ) -> Archive < ' a > {
99
+ let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config;
100
+ run_ar ( handler, & maybe_ar_prog, "crus" , None , [ & dst, initial_object] ) ;
101
+ Archive {
102
+ handler : handler,
103
+ dst : dst,
104
+ lib_search_paths : lib_search_paths,
105
+ os : os,
106
+ maybe_ar_prog : maybe_ar_prog
107
+ }
89
108
}
90
109
91
110
/// Opens an existing static archive
92
- pub fn open ( sess : & ' a Session , dst : Path ) -> Archive < ' a > {
111
+ pub fn open ( config : ArchiveConfig < ' a > ) -> Archive < ' a > {
112
+ let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config;
93
113
assert ! ( dst. exists( ) ) ;
94
- Archive { sess : sess, dst : dst }
114
+ Archive {
115
+ handler : handler,
116
+ dst : dst,
117
+ lib_search_paths : lib_search_paths,
118
+ os : os,
119
+ maybe_ar_prog : maybe_ar_prog
120
+ }
95
121
}
96
122
97
123
/// Adds all of the contents of a native library to this archive. This will
@@ -120,22 +146,22 @@ impl<'a> Archive<'a> {
120
146
/// Adds an arbitrary file to this archive
121
147
pub fn add_file ( & mut self , file : & Path , has_symbols : bool ) {
122
148
let cmd = if has_symbols { "r" } else { "rS" } ;
123
- run_ar ( self . sess , cmd, None , [ & self . dst , file] ) ;
149
+ run_ar ( self . handler , & self . maybe_ar_prog , cmd, None , [ & self . dst , file] ) ;
124
150
}
125
151
126
152
/// Removes a file from this archive
127
153
pub fn remove_file ( & mut self , file : & str ) {
128
- run_ar ( self . sess , "d" , None , [ & self . dst , & Path :: new ( file) ] ) ;
154
+ run_ar ( self . handler , & self . maybe_ar_prog , "d" , None , [ & self . dst , & Path :: new ( file) ] ) ;
129
155
}
130
156
131
157
/// Updates all symbols in the archive (runs 'ar s' over it)
132
158
pub fn update_symbols ( & mut self ) {
133
- run_ar ( self . sess , "s" , None , [ & self . dst ] ) ;
159
+ run_ar ( self . handler , & self . maybe_ar_prog , "s" , None , [ & self . dst ] ) ;
134
160
}
135
161
136
162
/// Lists all files in an archive
137
163
pub fn files ( & self ) -> Vec < String > {
138
- let output = run_ar ( self . sess , "t" , None , [ & self . dst ] ) ;
164
+ let output = run_ar ( self . handler , & self . maybe_ar_prog , "t" , None , [ & self . dst ] ) ;
139
165
let output = str:: from_utf8 ( output. output . as_slice ( ) ) . unwrap ( ) ;
140
166
// use lines_any because windows delimits output with `\r\n` instead of
141
167
// just `\n`
@@ -148,7 +174,7 @@ impl<'a> Archive<'a> {
148
174
149
175
// First, extract the contents of the archive to a temporary directory
150
176
let archive = os:: make_absolute ( archive) ;
151
- run_ar ( self . sess , "x" , Some ( loc. path ( ) ) , [ & archive] ) ;
177
+ run_ar ( self . handler , & self . maybe_ar_prog , "x" , Some ( loc. path ( ) ) , [ & archive] ) ;
152
178
153
179
// Next, we must rename all of the inputs to "guaranteed unique names".
154
180
// The reason for this is that archives are keyed off the name of the
@@ -184,23 +210,20 @@ impl<'a> Archive<'a> {
184
210
// Finally, add all the renamed files to this archive
185
211
let mut args = vec ! ( & self . dst) ;
186
212
args. extend ( inputs. iter ( ) ) ;
187
- run_ar ( self . sess , "r" , None , args. as_slice ( ) ) ;
213
+ run_ar ( self . handler , & self . maybe_ar_prog , "r" , None , args. as_slice ( ) ) ;
188
214
Ok ( ( ) )
189
215
}
190
216
191
217
fn find_library ( & self , name : & str ) -> Path {
192
- let ( osprefix, osext) = match self . sess . targ_cfg . os {
218
+ let ( osprefix, osext) = match self . os {
193
219
abi:: OsWin32 => ( "" , "lib" ) , _ => ( "lib" , "a" ) ,
194
220
} ;
195
221
// On Windows, static libraries sometimes show up as libfoo.a and other
196
222
// times show up as foo.lib
197
223
let oslibname = format ! ( "{}{}.{}" , osprefix, name, osext) ;
198
224
let unixlibname = format ! ( "lib{}.a" , name) ;
199
225
200
- let mut rustpath = filesearch:: rust_path ( ) ;
201
- rustpath. push ( self . sess . target_filesearch ( ) . get_lib_path ( ) ) ;
202
- let search = self . sess . opts . addl_lib_search_paths . borrow ( ) ;
203
- for path in search. iter ( ) . chain ( rustpath. iter ( ) ) {
226
+ for path in self . lib_search_paths . iter ( ) {
204
227
debug ! ( "looking for {} inside {}" , name, path. display( ) ) ;
205
228
let test = path. join ( oslibname. as_slice ( ) ) ;
206
229
if test. exists ( ) { return test }
@@ -209,7 +232,7 @@ impl<'a> Archive<'a> {
209
232
if test. exists ( ) { return test }
210
233
}
211
234
}
212
- self . sess . fatal ( format ! ( "could not find native static library `{}`, \
235
+ self . handler . fatal ( format ! ( "could not find native static library `{}`, \
213
236
perhaps an -L flag is missing?",
214
237
name) . as_slice ( ) ) ;
215
238
}
0 commit comments