1- use std:: fs:: File ;
21use std:: path:: { Path , PathBuf } ;
32
4- use crate :: errors :: RanlibFailure ;
5-
6- use rustc_codegen_ssa :: back :: archive :: { ArchiveBuilder , ArchiveBuilderBuilder } ;
3+ use rustc_codegen_ssa :: back :: archive :: {
4+ get_native_object_symbols , ArArchiveBuilder , ArchiveBuilder , ArchiveBuilderBuilder ,
5+ } ;
76use rustc_session:: Session ;
87
98use rustc_session:: cstore:: DllImport ;
109
11- struct ArchiveConfig < ' a > {
12- sess : & ' a Session ,
13- use_native_ar : bool ,
14- use_gnu_style_archive : bool ,
15- }
16-
17- #[ derive( Debug ) ]
18- enum ArchiveEntry {
19- FromArchive {
20- archive_index : usize ,
21- entry_index : usize ,
22- } ,
23- File ( PathBuf ) ,
24- }
25-
26- pub struct ArArchiveBuilderBuilder ;
10+ pub ( crate ) struct ArArchiveBuilderBuilder ;
2711
2812impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
2913 fn new_archive_builder < ' a > ( & self , sess : & ' a Session ) -> Box < dyn ArchiveBuilder < ' a > + ' a > {
30- let config = ArchiveConfig {
31- sess,
32- use_native_ar : false ,
33- // FIXME test for linux and System V derivatives instead
34- use_gnu_style_archive : sess. target . options . archive_format == "gnu" ,
35- } ;
36-
37- Box :: new ( ArArchiveBuilder {
38- config,
39- src_archives : vec ! [ ] ,
40- entries : vec ! [ ] ,
41- } )
14+ Box :: new ( ArArchiveBuilder :: new ( sess, get_native_object_symbols) )
4215 }
4316
4417 fn create_dll_import_lib (
@@ -49,144 +22,6 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
4922 _tmpdir : & Path ,
5023 _is_direct_dependency : bool ,
5124 ) -> PathBuf {
52- unimplemented ! ( ) ;
53- }
54- }
55-
56- pub struct ArArchiveBuilder < ' a > {
57- config : ArchiveConfig < ' a > ,
58- src_archives : Vec < ( PathBuf , ar:: Archive < File > ) > ,
59- // Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
60- // the end of an archive for linkers to not get confused.
61- entries : Vec < ( String , ArchiveEntry ) > ,
62- }
63-
64- impl < ' a > ArchiveBuilder < ' a > for ArArchiveBuilder < ' a > {
65- fn add_file ( & mut self , file : & Path ) {
66- self . entries . push ( (
67- file. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ,
68- ArchiveEntry :: File ( file. to_owned ( ) ) ,
69- ) ) ;
70- }
71-
72- fn add_archive (
73- & mut self ,
74- archive_path : & Path ,
75- mut skip : Box < dyn FnMut ( & str ) -> bool + ' static > ,
76- ) -> std:: io:: Result < ( ) > {
77- let mut archive = ar:: Archive :: new ( std:: fs:: File :: open ( & archive_path) ?) ;
78- let archive_index = self . src_archives . len ( ) ;
79-
80- let mut i = 0 ;
81- while let Some ( entry) = archive. next_entry ( ) {
82- let entry = entry?;
83- let file_name = String :: from_utf8 ( entry. header ( ) . identifier ( ) . to_vec ( ) )
84- . map_err ( |err| std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidData , err) ) ?;
85- if !skip ( & file_name) {
86- self . entries
87- . push ( ( file_name, ArchiveEntry :: FromArchive { archive_index, entry_index : i } ) ) ;
88- }
89- i += 1 ;
90- }
91-
92- self . src_archives . push ( ( archive_path. to_owned ( ) , archive) ) ;
93- Ok ( ( ) )
94- }
95-
96- fn build ( mut self : Box < Self > , output : & Path ) -> bool {
97- use std:: process:: Command ;
98-
99- fn add_file_using_ar ( archive : & Path , file : & Path ) {
100- Command :: new ( "ar" )
101- . arg ( "r" ) // add or replace file
102- . arg ( "-c" ) // silence created file message
103- . arg ( archive)
104- . arg ( & file)
105- . status ( )
106- . unwrap ( ) ;
107- }
108-
109- enum BuilderKind < ' a > {
110- Bsd ( ar:: Builder < File > ) ,
111- Gnu ( ar:: GnuBuilder < File > ) ,
112- NativeAr ( & ' a Path ) ,
113- }
114-
115- let mut builder = if self . config . use_native_ar {
116- BuilderKind :: NativeAr ( output)
117- } else if self . config . use_gnu_style_archive {
118- BuilderKind :: Gnu ( ar:: GnuBuilder :: new (
119- File :: create ( output) . unwrap ( ) ,
120- self . entries
121- . iter ( )
122- . map ( |( name, _) | name. as_bytes ( ) . to_vec ( ) )
123- . collect ( ) ,
124- ) )
125- } else {
126- BuilderKind :: Bsd ( ar:: Builder :: new ( File :: create ( output) . unwrap ( ) ) )
127- } ;
128-
129- let any_members = !self . entries . is_empty ( ) ;
130-
131- // Add all files
132- for ( entry_name, entry) in self . entries . into_iter ( ) {
133- match entry {
134- ArchiveEntry :: FromArchive {
135- archive_index,
136- entry_index,
137- } => {
138- let ( ref src_archive_path, ref mut src_archive) =
139- self . src_archives [ archive_index] ;
140- let entry = src_archive. jump_to_entry ( entry_index) . unwrap ( ) ;
141- let header = entry. header ( ) . clone ( ) ;
142-
143- match builder {
144- BuilderKind :: Bsd ( ref mut builder) => {
145- builder. append ( & header, entry) . unwrap ( )
146- }
147- BuilderKind :: Gnu ( ref mut builder) => {
148- builder. append ( & header, entry) . unwrap ( )
149- }
150- BuilderKind :: NativeAr ( archive_file) => {
151- Command :: new ( "ar" )
152- . arg ( "x" )
153- . arg ( src_archive_path)
154- . arg ( & entry_name)
155- . status ( )
156- . unwrap ( ) ;
157- add_file_using_ar ( archive_file, Path :: new ( & entry_name) ) ;
158- std:: fs:: remove_file ( entry_name) . unwrap ( ) ;
159- }
160- }
161- }
162- ArchiveEntry :: File ( file) =>
163- match builder {
164- BuilderKind :: Bsd ( ref mut builder) => {
165- builder
166- . append_file ( entry_name. as_bytes ( ) , & mut File :: open ( file) . expect ( "file for bsd builder" ) )
167- . unwrap ( )
168- } ,
169- BuilderKind :: Gnu ( ref mut builder) => {
170- builder
171- . append_file ( entry_name. as_bytes ( ) , & mut File :: open ( & file) . expect ( & format ! ( "file {:?} for gnu builder" , file) ) )
172- . unwrap ( )
173- } ,
174- BuilderKind :: NativeAr ( archive_file) => add_file_using_ar ( archive_file, & file) ,
175- } ,
176- }
177- }
178-
179- // Finalize archive
180- std:: mem:: drop ( builder) ;
181-
182- // Run ranlib to be able to link the archive
183- let status =
184- std:: process:: Command :: new ( "ranlib" ) . arg ( output) . status ( ) . expect ( "Couldn't run ranlib" ) ;
185-
186- if !status. success ( ) {
187- self . config . sess . emit_fatal ( RanlibFailure :: new ( status. code ( ) ) ) ;
188- }
189-
190- any_members
25+ unimplemented ! ( "creating dll imports is not yet supported" ) ;
19126 }
19227}
0 commit comments