@@ -25,18 +25,29 @@ pub fn create_tmp_dir(test_name: &str) -> PathBuf {
25
25
tmpdir
26
26
}
27
27
28
- fn run_llvm_ar ( object_paths : & [ PathBuf ] , archive_path : & Path , archive_kind : ArchiveKind ) {
28
+ fn run_llvm_ar (
29
+ object_paths : & [ PathBuf ] ,
30
+ archive_path : & Path ,
31
+ archive_kind : ArchiveKind ,
32
+ thin : bool ,
33
+ ) {
29
34
let ar_path = cargo_binutils:: Tool :: Ar . path ( ) . unwrap ( ) ;
30
35
36
+ let mut command = Command :: new ( ar_path) ;
37
+
31
38
let format_arg = match archive_kind {
32
39
ArchiveKind :: Gnu => "gnu" ,
33
40
ArchiveKind :: Darwin => "darwin" ,
34
41
ArchiveKind :: AixBig => "bigarchive" ,
35
42
_ => panic ! ( "unsupported archive kind: {:?}" , archive_kind) ,
36
43
} ;
44
+ command. arg ( format ! ( "--format={}" , format_arg) ) ;
37
45
38
- let output = Command :: new ( ar_path)
39
- . arg ( format ! ( "--format={}" , format_arg) )
46
+ if thin {
47
+ command. arg ( "--thin" ) ;
48
+ }
49
+
50
+ let output = command
40
51
. arg ( "rcs" )
41
52
. arg ( archive_path)
42
53
. args ( object_paths)
@@ -55,6 +66,7 @@ pub fn create_archive_with_llvm_ar<'a>(
55
66
tmpdir : & Path ,
56
67
archive_kind : ArchiveKind ,
57
68
input_objects : impl IntoIterator < Item = ( & ' static str , & ' a [ u8 ] ) > ,
69
+ thin : bool ,
58
70
) -> Vec < u8 > {
59
71
let archive_file_path = tmpdir. join ( "output_llvm_ar.a" ) ;
60
72
@@ -70,7 +82,7 @@ pub fn create_archive_with_llvm_ar<'a>(
70
82
} )
71
83
. collect :: < Vec < _ > > ( ) ;
72
84
73
- run_llvm_ar ( & input_file_paths, & archive_file_path, archive_kind) ;
85
+ run_llvm_ar ( & input_file_paths, & archive_file_path, archive_kind, thin ) ;
74
86
fs:: read ( archive_file_path) . unwrap ( )
75
87
}
76
88
@@ -80,24 +92,37 @@ pub fn create_archive_with_ar_archive_writer<'a>(
80
92
tmpdir : & Path ,
81
93
archive_kind : ArchiveKind ,
82
94
input_objects : impl IntoIterator < Item = ( & ' static str , & ' a [ u8 ] ) > ,
95
+ thin : bool ,
83
96
) -> Vec < u8 > {
84
97
let members = input_objects
85
98
. into_iter ( )
86
- . map ( |( name, bytes) | NewArchiveMember {
87
- buf : Box :: new ( bytes) as Box < dyn AsRef < [ u8 ] > > ,
88
- get_symbols : ar_archive_writer:: get_native_object_symbols,
89
- member_name : name
90
- . rsplit_once ( '/' )
91
- . map_or ( name, |( _, filename) | filename)
92
- . to_string ( ) ,
93
- mtime : 0 ,
94
- uid : 0 ,
95
- gid : 0 ,
96
- perms : 0o644 ,
99
+ . map ( |( name, bytes) | {
100
+ let member_name = if thin {
101
+ // Thin archives use the full path to the object file.
102
+ tmpdir
103
+ . join ( name)
104
+ . to_string_lossy ( )
105
+ . replace ( std:: path:: MAIN_SEPARATOR , "/" )
106
+ } else {
107
+ // Non-thin archives use the file name only.
108
+ name. rsplit_once ( '/' )
109
+ . map_or ( name, |( _, filename) | filename)
110
+ . to_string ( )
111
+ } ;
112
+
113
+ NewArchiveMember {
114
+ buf : Box :: new ( bytes) as Box < dyn AsRef < [ u8 ] > > ,
115
+ get_symbols : ar_archive_writer:: get_native_object_symbols,
116
+ member_name,
117
+ mtime : 0 ,
118
+ uid : 0 ,
119
+ gid : 0 ,
120
+ perms : 0o644 ,
121
+ }
97
122
} )
98
123
. collect :: < Vec < _ > > ( ) ;
99
124
let mut output_bytes = Cursor :: new ( Vec :: new ( ) ) ;
100
- ar_archive_writer:: write_archive_to_stream ( & mut output_bytes, & members, archive_kind, false )
125
+ ar_archive_writer:: write_archive_to_stream ( & mut output_bytes, & members, archive_kind, thin )
101
126
. unwrap ( ) ;
102
127
103
128
let output_archive_bytes = output_bytes. into_inner ( ) ;
@@ -112,58 +137,88 @@ pub fn generate_archive_and_compare<F>(test_name: &str, generate_objects: F)
112
137
where
113
138
F : Fn ( Architecture , Endianness , BinaryFormat ) -> Vec < ( & ' static str , Vec < u8 > ) > ,
114
139
{
115
- for ( architecture, endianness, binary_format, archive_kind) in [
116
- // Elf + GNU
140
+ for ( architecture, endianness, binary_format, archive_kind, thin) in [
141
+ // Elf + GNU + non-thin
142
+ (
143
+ Architecture :: X86_64 ,
144
+ Endianness :: Little ,
145
+ BinaryFormat :: Elf ,
146
+ ArchiveKind :: Gnu ,
147
+ false ,
148
+ ) ,
149
+ (
150
+ Architecture :: I386 ,
151
+ Endianness :: Little ,
152
+ BinaryFormat :: Elf ,
153
+ ArchiveKind :: Gnu ,
154
+ false ,
155
+ ) ,
156
+ (
157
+ Architecture :: Aarch64 ,
158
+ Endianness :: Little ,
159
+ BinaryFormat :: Elf ,
160
+ ArchiveKind :: Gnu ,
161
+ false ,
162
+ ) ,
163
+ // Elf + GNU + thin
117
164
(
118
165
Architecture :: X86_64 ,
119
166
Endianness :: Little ,
120
167
BinaryFormat :: Elf ,
121
168
ArchiveKind :: Gnu ,
169
+ true ,
122
170
) ,
123
171
(
124
172
Architecture :: I386 ,
125
173
Endianness :: Little ,
126
174
BinaryFormat :: Elf ,
127
175
ArchiveKind :: Gnu ,
176
+ true ,
128
177
) ,
129
178
(
130
179
Architecture :: Aarch64 ,
131
180
Endianness :: Little ,
132
181
BinaryFormat :: Elf ,
133
182
ArchiveKind :: Gnu ,
183
+ true ,
134
184
) ,
135
185
// AIX Big
136
186
(
137
187
Architecture :: PowerPc64 ,
138
188
Endianness :: Big ,
139
189
BinaryFormat :: Elf ,
140
190
ArchiveKind :: AixBig ,
191
+ false ,
141
192
) ,
142
193
// PE + GNU
143
194
(
144
195
Architecture :: X86_64 ,
145
196
Endianness :: Little ,
146
197
BinaryFormat :: Coff ,
147
198
ArchiveKind :: Gnu ,
199
+ false ,
148
200
) ,
149
201
(
150
202
Architecture :: I386 ,
151
203
Endianness :: Little ,
152
204
BinaryFormat :: Coff ,
153
205
ArchiveKind :: Gnu ,
206
+ false ,
154
207
) ,
155
208
// MachO
156
209
(
157
210
Architecture :: X86_64 ,
158
211
Endianness :: Little ,
159
212
BinaryFormat :: MachO ,
160
213
ArchiveKind :: Darwin ,
214
+ false ,
161
215
) ,
162
216
(
163
217
Architecture :: Aarch64 ,
164
218
Endianness :: Little ,
165
219
BinaryFormat :: MachO ,
166
220
ArchiveKind :: Darwin ,
221
+ false ,
167
222
) ,
168
223
] {
169
224
let tmpdir = create_tmp_dir ( test_name) ;
@@ -174,18 +229,20 @@ where
174
229
input_objects
175
230
. iter ( )
176
231
. map ( |( name, bytes) | ( * name, bytes. as_slice ( ) ) ) ,
232
+ thin,
177
233
) ;
178
234
let ar_archive_writer_archive = create_archive_with_ar_archive_writer (
179
235
& tmpdir,
180
236
archive_kind,
181
237
input_objects
182
238
. iter ( )
183
239
. map ( |( name, bytes) | ( * name, bytes. as_slice ( ) ) ) ,
240
+ thin,
184
241
) ;
185
242
186
243
assert_eq ! (
187
244
llvm_ar_archive, ar_archive_writer_archive,
188
- "Archives differ for architecture: {architecture:?}, binary_format: {binary_format:?}, archive_kind: {archive_kind:?}" ,
245
+ "Archives differ for architecture: {architecture:?}, binary_format: {binary_format:?}, archive_kind: {archive_kind:?}, thin: {thin} " ,
189
246
) ;
190
247
}
191
248
}
0 commit comments