1+ use std:: borrow:: Borrow ;
2+ use std:: fs;
13use std:: path:: Path ;
24
5+ use ar_archive_writer:: { COFFShortExport , MachineTypes } ;
36use rustc_codegen_ssa:: back:: archive:: {
4- ArArchiveBuilder , ArchiveBuilder , ArchiveBuilderBuilder , DEFAULT_OBJECT_READER ,
7+ create_mingw_dll_import_lib, ArArchiveBuilder , ArchiveBuilder , ArchiveBuilderBuilder ,
8+ DEFAULT_OBJECT_READER ,
59} ;
10+ use rustc_codegen_ssa:: common:: is_mingw_gnu_toolchain;
611use rustc_session:: Session ;
712
813pub ( crate ) struct ArArchiveBuilderBuilder ;
@@ -15,10 +20,74 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
1520 fn create_dll_import_lib (
1621 & self ,
1722 sess : & Session ,
18- _lib_name : & str ,
19- _import_name_and_ordinal_vector : Vec < ( String , Option < u16 > ) > ,
20- _output_path : & Path ,
23+ lib_name : & str ,
24+ import_name_and_ordinal_vector : Vec < ( String , Option < u16 > ) > ,
25+ output_path : & Path ,
2126 ) {
22- sess. dcx ( ) . fatal ( "raw-dylib is not yet supported by rustc_codegen_cranelift" ) ;
27+ if is_mingw_gnu_toolchain ( & sess. target ) {
28+ // The binutils linker used on -windows-gnu targets cannot read the import
29+ // libraries generated by LLVM: in our attempts, the linker produced an .EXE
30+ // that loaded but crashed with an AV upon calling one of the imported
31+ // functions. Therefore, use binutils to create the import library instead,
32+ // by writing a .DEF file to the temp dir and calling binutils's dlltool.
33+ create_mingw_dll_import_lib (
34+ sess,
35+ lib_name,
36+ import_name_and_ordinal_vector,
37+ output_path,
38+ ) ;
39+ } else {
40+ let mut file =
41+ match fs:: OpenOptions :: new ( ) . write ( true ) . create_new ( true ) . open ( & output_path) {
42+ Ok ( file) => file,
43+ Err ( error) => {
44+ sess. dcx ( ) . fatal ( format ! (
45+ "failed to create import library file `{path}`: {error}" ,
46+ path = output_path. display( ) ,
47+ ) ) ;
48+ }
49+ } ;
50+
51+ let machine = match sess. target . arch . borrow ( ) {
52+ "x86" => MachineTypes :: I386 ,
53+ "x86_64" => MachineTypes :: AMD64 ,
54+ "arm" => MachineTypes :: ARMNT ,
55+ "aarch64" => MachineTypes :: ARM64 ,
56+ _ => {
57+ sess. dcx ( ) . fatal ( format ! (
58+ "unsupported target architecture `{arch}`" ,
59+ arch = sess. target. arch,
60+ ) ) ;
61+ }
62+ } ;
63+
64+ let exports = import_name_and_ordinal_vector
65+ . iter ( )
66+ . map ( |( name, ordinal) | COFFShortExport {
67+ name : name. to_string ( ) ,
68+ ext_name : None ,
69+ symbol_name : None ,
70+ alias_target : None ,
71+ ordinal : ordinal. unwrap_or ( 0 ) ,
72+ noname : ordinal. is_some ( ) ,
73+ data : false ,
74+ private : false ,
75+ constant : false ,
76+ } )
77+ . collect :: < Vec < _ > > ( ) ;
78+
79+ if let Err ( error) = ar_archive_writer:: write_import_library (
80+ & mut file,
81+ lib_name,
82+ & exports,
83+ machine,
84+ !sess. target . is_like_msvc ,
85+ ) {
86+ sess. dcx ( ) . fatal ( format ! (
87+ "failed to create import library `{path}`: `{error}`" ,
88+ path = output_path. display( ) ,
89+ ) ) ;
90+ }
91+ }
2392 }
2493}
0 commit comments