@@ -14,25 +14,29 @@ struct ArchiveConfig<'a> {
14
14
pub lib_search_paths : Vec < PathBuf > ,
15
15
}
16
16
17
+ enum ArchiveEntry {
18
+ FromArchive { archive_index : usize , entry_index : usize } ,
19
+ File ( File ) ,
20
+ }
21
+
17
22
pub struct ArArchiveBuilder < ' a > {
18
23
config : ArchiveConfig < ' a > ,
19
- src_archive : Option < ar:: Archive < File > > ,
20
- src_entries : HashMap < String , usize > ,
21
- builder : ar:: Builder < File > ,
24
+ src_archives : Vec < ar:: Archive < File > > ,
25
+ entries : HashMap < String , ArchiveEntry > ,
22
26
update_symbols : bool ,
23
27
}
24
28
25
29
impl < ' a > ArchiveBuilder < ' a > for ArArchiveBuilder < ' a > {
26
30
fn new ( sess : & ' a Session , output : & Path , input : Option < & Path > ) -> Self {
27
31
use rustc_codegen_ssa:: back:: link:: archive_search_paths;
28
- let cfg = ArchiveConfig {
32
+ let config = ArchiveConfig {
29
33
sess,
30
34
dst : output. to_path_buf ( ) ,
31
35
src : input. map ( |p| p. to_path_buf ( ) ) ,
32
36
lib_search_paths : archive_search_paths ( sess) ,
33
37
} ;
34
38
35
- let ( src_archive , src_entries ) = if let Some ( src) = & cfg . src {
39
+ let ( src_archives , entries ) = if let Some ( src) = & config . src {
36
40
let mut archive = ar:: Archive :: new ( File :: open ( src) . unwrap ( ) ) ;
37
41
let mut entries = HashMap :: new ( ) ;
38
42
@@ -41,41 +45,41 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
41
45
let entry = entry. unwrap ( ) ;
42
46
entries. insert (
43
47
String :: from_utf8 ( entry. header ( ) . identifier ( ) . to_vec ( ) ) . unwrap ( ) ,
44
- i ,
48
+ ArchiveEntry :: FromArchive { archive_index : 0 , entry_index : i } ,
45
49
) ;
46
50
i += 1 ;
47
51
}
48
52
49
- ( Some ( archive) , entries)
53
+ ( vec ! [ archive] , entries)
50
54
} else {
51
- ( None , HashMap :: new ( ) )
55
+ ( vec ! [ ] , HashMap :: new ( ) )
52
56
} ;
53
57
54
- let builder = ar:: Builder :: new ( File :: create ( & cfg. dst ) . unwrap ( ) ) ;
55
-
56
58
ArArchiveBuilder {
57
- config : cfg,
58
- src_archive,
59
- src_entries,
60
- builder,
59
+ config,
60
+ src_archives,
61
+ entries,
61
62
update_symbols : false ,
62
63
}
63
64
}
64
65
65
66
fn src_files ( & mut self ) -> Vec < String > {
66
- self . src_entries . keys ( ) . cloned ( ) . collect ( )
67
+ self . entries . keys ( ) . cloned ( ) . collect ( )
67
68
}
68
69
69
70
fn remove_file ( & mut self , name : & str ) {
70
- let file = self . src_entries . remove ( name) ;
71
+ let file = self . entries . remove ( name) ;
71
72
assert ! (
72
73
file. is_some( ) ,
73
74
"Tried to remove file not existing in src archive" ,
74
75
) ;
75
76
}
76
77
77
78
fn add_file ( & mut self , file : & Path ) {
78
- self . builder . append_path ( file) . unwrap ( ) ;
79
+ self . entries . insert (
80
+ file. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ,
81
+ ArchiveEntry :: File ( File :: open ( file) . unwrap ( ) ) ,
82
+ ) ;
79
83
}
80
84
81
85
fn add_native_library ( & mut self , name : & str ) {
@@ -115,23 +119,30 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
115
119
}
116
120
117
121
fn build ( mut self ) {
118
- // Add files from original archive
119
- if let Some ( mut src_archive) = self . src_archive {
120
- for ( _entry_name, entry_idx) in self . src_entries . into_iter ( ) {
121
- let entry = src_archive. jump_to_entry ( entry_idx) . unwrap ( ) ;
122
- let orig_header = entry. header ( ) ;
123
- let mut header =
124
- ar:: Header :: new ( orig_header. identifier ( ) . to_vec ( ) , orig_header. size ( ) ) ;
125
- header. set_mtime ( orig_header. mtime ( ) ) ;
126
- header. set_uid ( orig_header. uid ( ) ) ;
127
- header. set_gid ( orig_header. gid ( ) ) ;
128
- header. set_mode ( orig_header. mode ( ) ) ;
129
- self . builder . append ( & header, entry) . unwrap ( ) ;
122
+ let mut builder = ar:: Builder :: new ( File :: create ( & self . config . dst ) . unwrap ( ) ) ;
123
+
124
+ // Add all files
125
+ for ( entry_name, entry) in self . entries . into_iter ( ) {
126
+ match entry {
127
+ ArchiveEntry :: FromArchive { archive_index, entry_index } => {
128
+ let entry = self . src_archives [ archive_index] . jump_to_entry ( entry_index) . unwrap ( ) ;
129
+ let orig_header = entry. header ( ) ;
130
+ let mut header =
131
+ ar:: Header :: new ( orig_header. identifier ( ) . to_vec ( ) , orig_header. size ( ) ) ;
132
+ header. set_mtime ( orig_header. mtime ( ) ) ;
133
+ header. set_uid ( orig_header. uid ( ) ) ;
134
+ header. set_gid ( orig_header. gid ( ) ) ;
135
+ header. set_mode ( orig_header. mode ( ) ) ;
136
+ builder. append ( & header, entry) . unwrap ( ) ;
137
+ }
138
+ ArchiveEntry :: File ( mut file) => {
139
+ builder. append_file ( entry_name. as_bytes ( ) , & mut file) . unwrap ( ) ;
140
+ }
130
141
}
131
142
}
132
143
133
144
// Finalize archive
134
- std:: mem:: drop ( self . builder ) ;
145
+ std:: mem:: drop ( builder) ;
135
146
136
147
// Run ranlib to be able to link the archive
137
148
let status = std:: process:: Command :: new ( "ranlib" )
@@ -151,22 +162,22 @@ impl<'a> ArArchiveBuilder<'a> {
151
162
where F : FnMut ( & str ) -> bool + ' static
152
163
{
153
164
let mut archive = ar:: Archive :: new ( std:: fs:: File :: open ( archive) ?) ;
154
- while let Some ( entry) = archive. next_entry ( ) {
155
- let entry = entry?;
156
- let orig_header = entry. header ( ) ;
165
+ let archive_index = self . src_archives . len ( ) ;
157
166
158
- if skip ( std:: str:: from_utf8 ( orig_header. identifier ( ) ) . unwrap ( ) ) {
159
- continue ;
167
+ let mut i = 0 ;
168
+ while let Some ( entry) = archive. next_entry ( ) {
169
+ let entry = entry. unwrap ( ) ;
170
+ let file_name = String :: from_utf8 ( entry. header ( ) . identifier ( ) . to_vec ( ) ) . unwrap ( ) ;
171
+ if !skip ( & file_name) {
172
+ self . entries . insert (
173
+ file_name,
174
+ ArchiveEntry :: FromArchive { archive_index, entry_index : i } ,
175
+ ) ;
160
176
}
161
-
162
- let mut header =
163
- ar:: Header :: new ( orig_header. identifier ( ) . to_vec ( ) , orig_header. size ( ) ) ;
164
- header. set_mtime ( orig_header. mtime ( ) ) ;
165
- header. set_uid ( orig_header. uid ( ) ) ;
166
- header. set_gid ( orig_header. gid ( ) ) ;
167
- header. set_mode ( orig_header. mode ( ) ) ;
168
- self . builder . append ( & header, entry) . unwrap ( ) ;
177
+ i += 1 ;
169
178
}
179
+
180
+ self . src_archives . push ( archive) ;
170
181
Ok ( ( ) )
171
182
}
172
183
}
0 commit comments