2024-08-02 20:53:09 +00:00
|
|
|
use std::borrow::Borrow;
|
|
|
|
use std::fs;
|
2024-07-25 19:53:17 +00:00
|
|
|
use std::path::Path;
|
2018-11-09 17:38:30 +00:00
|
|
|
|
2024-08-02 20:53:09 +00:00
|
|
|
use ar_archive_writer::{COFFShortExport, MachineTypes};
|
2022-05-28 10:43:51 +00:00
|
|
|
use rustc_codegen_ssa::back::archive::{
|
2024-08-02 20:53:09 +00:00
|
|
|
create_mingw_dll_import_lib, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
|
|
|
|
DEFAULT_OBJECT_READER,
|
2022-05-28 10:43:51 +00:00
|
|
|
};
|
2024-08-02 20:53:09 +00:00
|
|
|
use rustc_codegen_ssa::common::is_mingw_gnu_toolchain;
|
2020-08-28 10:10:48 +00:00
|
|
|
use rustc_session::Session;
|
2019-04-01 17:34:26 +00:00
|
|
|
|
2022-07-28 09:07:49 +00:00
|
|
|
pub(crate) struct ArArchiveBuilderBuilder;
|
|
|
|
|
|
|
|
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
|
2024-02-26 14:37:04 +00:00
|
|
|
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
|
2024-04-16 18:31:43 +00:00
|
|
|
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
|
2022-07-28 09:07:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn create_dll_import_lib(
|
|
|
|
&self,
|
2024-07-13 18:39:03 +00:00
|
|
|
sess: &Session,
|
2024-08-02 20:53:09 +00:00
|
|
|
lib_name: &str,
|
|
|
|
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
|
|
|
output_path: &Path,
|
2024-07-25 19:53:17 +00:00
|
|
|
) {
|
2024-08-02 20:53:09 +00:00
|
|
|
if is_mingw_gnu_toolchain(&sess.target) {
|
|
|
|
// The binutils linker used on -windows-gnu targets cannot read the import
|
|
|
|
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
|
|
|
// that loaded but crashed with an AV upon calling one of the imported
|
|
|
|
// functions. Therefore, use binutils to create the import library instead,
|
|
|
|
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
|
|
|
create_mingw_dll_import_lib(
|
|
|
|
sess,
|
|
|
|
lib_name,
|
|
|
|
import_name_and_ordinal_vector,
|
|
|
|
output_path,
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
let mut file =
|
|
|
|
match fs::OpenOptions::new().write(true).create_new(true).open(&output_path) {
|
|
|
|
Ok(file) => file,
|
|
|
|
Err(error) => {
|
|
|
|
sess.dcx().fatal(format!(
|
|
|
|
"failed to create import library file `{path}`: {error}",
|
|
|
|
path = output_path.display(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let machine = match sess.target.arch.borrow() {
|
|
|
|
"x86" => MachineTypes::I386,
|
|
|
|
"x86_64" => MachineTypes::AMD64,
|
|
|
|
"arm" => MachineTypes::ARMNT,
|
|
|
|
"aarch64" => MachineTypes::ARM64,
|
|
|
|
_ => {
|
|
|
|
sess.dcx().fatal(format!(
|
|
|
|
"unsupported target architecture `{arch}`",
|
|
|
|
arch = sess.target.arch,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let exports = import_name_and_ordinal_vector
|
|
|
|
.iter()
|
|
|
|
.map(|(name, ordinal)| COFFShortExport {
|
|
|
|
name: name.to_string(),
|
|
|
|
ext_name: None,
|
|
|
|
symbol_name: None,
|
|
|
|
alias_target: None,
|
|
|
|
ordinal: ordinal.unwrap_or(0),
|
|
|
|
noname: ordinal.is_some(),
|
|
|
|
data: false,
|
|
|
|
private: false,
|
|
|
|
constant: false,
|
|
|
|
})
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
if let Err(error) = ar_archive_writer::write_import_library(
|
|
|
|
&mut file,
|
|
|
|
lib_name,
|
|
|
|
&exports,
|
|
|
|
machine,
|
|
|
|
!sess.target.is_like_msvc,
|
|
|
|
) {
|
|
|
|
sess.dcx().fatal(format!(
|
|
|
|
"failed to create import library `{path}`: `{error}`",
|
|
|
|
path = output_path.display(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
2018-11-09 17:38:30 +00:00
|
|
|
}
|
|
|
|
}
|