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,17 +5,13 @@ use std::path::{Path, PathBuf};
|
|||
use std::{io, mem, ptr, str};
|
||||
|
||||
use rustc_codegen_ssa::back::archive::{
|
||||
create_mingw_dll_import_lib, try_extract_macho_fat_archive, ArArchiveBuilder,
|
||||
ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind,
|
||||
DEFAULT_OBJECT_READER,
|
||||
try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder,
|
||||
ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER,
|
||||
};
|
||||
use rustc_codegen_ssa::common;
|
||||
use rustc_session::Session;
|
||||
use tracing::trace;
|
||||
|
||||
use crate::errors::ErrorCreatingImportLibrary;
|
||||
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
||||
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
|
||||
use crate::llvm::{self, ArchiveKind};
|
||||
|
||||
/// Helper for adding many files to an archive.
|
||||
#[must_use = "must call build() to finish building the archive"]
|
||||
|
@ -44,18 +40,6 @@ fn is_relevant_child(c: &Child<'_>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Map machine type strings to values of LLVM's MachineTypes enum.
|
||||
fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
|
||||
match cpu {
|
||||
"x86_64" => LLVMMachineType::AMD64,
|
||||
"x86" => LLVMMachineType::I386,
|
||||
"aarch64" => LLVMMachineType::ARM64,
|
||||
"arm64ec" => LLVMMachineType::ARM64EC,
|
||||
"arm" => LLVMMachineType::ARM,
|
||||
_ => panic!("unsupported cpu type {cpu}"),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
|
||||
fn add_archive(
|
||||
&mut self,
|
||||
|
@ -116,78 +100,6 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
|||
Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
|
||||
}
|
||||
}
|
||||
|
||||
fn create_dll_import_lib(
|
||||
&self,
|
||||
sess: &Session,
|
||||
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 {
|
||||
// we've checked for \0 characters in the library name already
|
||||
let dll_name_z = CString::new(lib_name).unwrap();
|
||||
|
||||
let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
|
||||
|
||||
trace!("invoking LLVMRustWriteImportLibrary");
|
||||
trace!(" dll_name {:#?}", dll_name_z);
|
||||
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 cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
|
||||
import_name_and_ordinal_vector
|
||||
.into_iter()
|
||||
.map(|(name, ordinal)| (CString::new(name).unwrap(), ordinal))
|
||||
.collect();
|
||||
|
||||
let ffi_exports: Vec<LLVMRustCOFFShortExport> = cstring_import_name_and_ordinal_vector
|
||||
.iter()
|
||||
.map(|(name_z, ordinal)| LLVMRustCOFFShortExport::new(name_z.as_ptr(), *ordinal))
|
||||
.collect();
|
||||
let result = unsafe {
|
||||
crate::llvm::LLVMRustWriteImportLibrary(
|
||||
dll_name_z.as_ptr(),
|
||||
output_path_z.as_ptr(),
|
||||
ffi_exports.as_ptr(),
|
||||
ffi_exports.len(),
|
||||
llvm_machine_type(&sess.target.arch) as u16,
|
||||
!sess.target.is_like_msvc,
|
||||
)
|
||||
};
|
||||
|
||||
if result == crate::llvm::LLVMRustResult::Failure {
|
||||
sess.dcx().emit_fatal(ErrorCreatingImportLibrary {
|
||||
lib_name,
|
||||
error: llvm::last_error().unwrap_or("unknown LLVM error".to_string()),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
|
||||
|
|
|
@ -39,13 +39,6 @@ pub(crate) enum PossibleFeature<'a> {
|
|||
None,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_error_creating_import_library)]
|
||||
pub(crate) struct ErrorCreatingImportLibrary<'a> {
|
||||
pub lib_name: &'a str,
|
||||
pub error: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_symbol_already_defined)]
|
||||
pub(crate) struct SymbolAlreadyDefined<'a> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue