Always use ar_archive_writer for import libs
This commit is contained in:
parent
27b93da8de
commit
0156eb57a1
10 changed files with 100 additions and 190 deletions
|
@ -5,7 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
ar_archive_writer = "0.3.3"
|
||||
ar_archive_writer = "0.4.0"
|
||||
arrayvec = { version = "0.7", default-features = false }
|
||||
bitflags = "2.4.1"
|
||||
cc = "1.0.90"
|
||||
|
|
|
@ -32,6 +32,9 @@ codegen_ssa_dlltool_fail_import_library =
|
|||
codegen_ssa_error_calling_dlltool =
|
||||
Error calling dlltool '{$dlltool_path}': {$error}
|
||||
|
||||
codegen_ssa_error_creating_import_library =
|
||||
Error creating import library for {$lib_name}: {$error}
|
||||
|
||||
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
|
||||
|
||||
codegen_ssa_error_writing_def_file =
|
||||
|
|
|
@ -5,7 +5,9 @@ use std::fs::{self, File};
|
|||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use ar_archive_writer::{write_archive_to_stream, ArchiveKind, NewArchiveMember};
|
||||
use ar_archive_writer::{
|
||||
write_archive_to_stream, ArchiveKind, COFFShortExport, MachineTypes, NewArchiveMember,
|
||||
};
|
||||
pub use ar_archive_writer::{ObjectReader, DEFAULT_OBJECT_READER};
|
||||
use object::read::archive::ArchiveFile;
|
||||
use object::read::macho::FatArch;
|
||||
|
@ -14,11 +16,15 @@ use rustc_data_structures::memmap::Mmap;
|
|||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use tempfile::Builder as TempFileBuilder;
|
||||
use tracing::trace;
|
||||
|
||||
use super::metadata::search_for_section;
|
||||
use crate::common;
|
||||
// Re-exporting for rustc_codegen_llvm::back::archive
|
||||
pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind};
|
||||
use crate::errors::{DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorWritingDEFFile};
|
||||
use crate::errors::{
|
||||
DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile,
|
||||
};
|
||||
|
||||
pub trait ArchiveBuilderBuilder {
|
||||
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a>;
|
||||
|
@ -34,7 +40,81 @@ pub trait ArchiveBuilderBuilder {
|
|||
lib_name: &str,
|
||||
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
||||
output_path: &Path,
|
||||
);
|
||||
) {
|
||||
if common::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 {
|
||||
trace!("creating import library");
|
||||
trace!(" dll_name {:#?}", lib_name);
|
||||
trace!(" output_path {}", output_path.display());
|
||||
trace!(
|
||||
" import names: {}",
|
||||
import_name_and_ordinal_vector
|
||||
.iter()
|
||||
.map(|(name, _ordinal)| name.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
);
|
||||
|
||||
// All import names are Rust identifiers and therefore cannot contain \0 characters.
|
||||
// FIXME: when support for #[link_name] is implemented, ensure that the import names
|
||||
// still don't contain any \0 characters. Also need to check that the names don't
|
||||
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
|
||||
// in definition files.
|
||||
|
||||
let mut file = match fs::File::create_new(&output_path) {
|
||||
Ok(file) => file,
|
||||
Err(error) => sess
|
||||
.dcx()
|
||||
.emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }),
|
||||
};
|
||||
|
||||
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<_>>();
|
||||
let machine = match &*sess.target.arch {
|
||||
"x86_64" => MachineTypes::AMD64,
|
||||
"x86" => MachineTypes::I386,
|
||||
"aarch64" => MachineTypes::ARM64,
|
||||
"arm64ec" => MachineTypes::ARM64EC,
|
||||
"arm" => MachineTypes::ARMNT,
|
||||
cpu => panic!("unsupported cpu type {cpu}"),
|
||||
};
|
||||
|
||||
if let Err(error) = ar_archive_writer::write_import_library(
|
||||
&mut file,
|
||||
lib_name,
|
||||
&exports,
|
||||
machine,
|
||||
!sess.target.is_like_msvc,
|
||||
/*comdat=*/ false,
|
||||
) {
|
||||
sess.dcx()
|
||||
.emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_bundled_libs<'a>(
|
||||
&'a self,
|
||||
|
|
|
@ -1060,3 +1060,10 @@ pub struct CompilerBuiltinsCannotCall {
|
|||
pub caller: String,
|
||||
pub callee: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_error_creating_import_library)]
|
||||
pub(crate) struct ErrorCreatingImportLibrary<'a> {
|
||||
pub lib_name: &'a str,
|
||||
pub error: String,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue