1
+ use std:: borrow:: Borrow ;
2
+ use std:: fs;
1
3
use std:: path:: Path ;
2
4
5
+ use ar_archive_writer:: { COFFShortExport , MachineTypes } ;
3
6
use 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 ,
5
9
} ;
10
+ use rustc_codegen_ssa:: common:: is_mingw_gnu_toolchain;
6
11
use rustc_session:: Session ;
7
12
8
13
pub ( crate ) struct ArArchiveBuilderBuilder ;
@@ -15,10 +20,74 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
15
20
fn create_dll_import_lib (
16
21
& self ,
17
22
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 ,
21
26
) {
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
+ }
23
92
}
24
93
}
0 commit comments