trans: Add kind to writeArchive
Updates our LLVM bindings to be able to write out multiple kinds of archives. This commit also enables using LLVM instead of the system ar on all current targets.
This commit is contained in:
parent
7f0e733f1d
commit
74e198126b
10 changed files with 52 additions and 15 deletions
|
|
@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions {
|
|||
has_rpath: true,
|
||||
dll_prefix: "lib".to_string(),
|
||||
dll_suffix: ".dylib".to_string(),
|
||||
archive_format: "bsd".to_string(),
|
||||
pre_link_args: Vec::new(),
|
||||
.. Default::default()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ pub fn opts() -> TargetOptions {
|
|||
position_independent_executables: true,
|
||||
pre_link_args: vec!(
|
||||
),
|
||||
archive_format: "bsd".to_string(),
|
||||
|
||||
.. Default::default()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ pub fn opts() -> TargetOptions {
|
|||
"-Wl,--as-needed".to_string(),
|
||||
),
|
||||
position_independent_executables: true,
|
||||
archive_format: "bsd".to_string(),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ pub fn opts() -> TargetOptions {
|
|||
executables: true,
|
||||
morestack: true,
|
||||
has_rpath: true,
|
||||
archive_format: "bsd".to_string(),
|
||||
|
||||
.. Default::default()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
|
|||
"-Wl,--as-needed".to_string(),
|
||||
),
|
||||
position_independent_executables: true,
|
||||
archive_format: "bsd".to_string(),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
|
|||
"-Wl,--as-needed".to_string(),
|
||||
),
|
||||
position_independent_executables: true,
|
||||
archive_format: "bsd".to_string(),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ impl<'a> Child<'a> {
|
|||
unsafe {
|
||||
let mut data_len = 0;
|
||||
let data_ptr = ::LLVMRustArchiveChildData(self.ptr, &mut data_len);
|
||||
if data_ptr.is_null() {
|
||||
panic!("failed to read data from archive child");
|
||||
}
|
||||
slice::from_raw_parts(data_ptr as *const u8, data_len as usize)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -452,6 +452,15 @@ pub enum DiagnosticKind {
|
|||
DK_OptimizationFailure,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ArchiveKind {
|
||||
K_GNU,
|
||||
K_MIPS64,
|
||||
K_BSD,
|
||||
K_COFF,
|
||||
}
|
||||
|
||||
// Opaque pointer types
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Module_opaque {}
|
||||
|
|
@ -2119,7 +2128,8 @@ extern {
|
|||
pub fn LLVMRustWriteArchive(Dst: *const c_char,
|
||||
NumMembers: size_t,
|
||||
Members: *const RustArchiveMemberRef,
|
||||
WriteSymbtab: bool) -> c_int;
|
||||
WriteSymbtab: bool,
|
||||
Kind: ArchiveKind) -> c_int;
|
||||
pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
|
||||
Name: *const c_char,
|
||||
Child: ArchiveChildRef) -> RustArchiveMemberRef;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use std::str;
|
|||
|
||||
use libc;
|
||||
use llvm::archive_ro::{ArchiveRO, Child};
|
||||
use llvm;
|
||||
use llvm::{self, ArchiveKind};
|
||||
use rustc::metadata::loader::METADATA_FILENAME;
|
||||
use rustc::session::Session;
|
||||
use rustc_back::tempdir::TempDir;
|
||||
|
|
@ -208,28 +208,34 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
/// Combine the provided files, rlibs, and native libraries into a single
|
||||
/// `Archive`.
|
||||
pub fn build(&mut self) {
|
||||
let res = if self.using_llvm() {
|
||||
self.build_with_llvm()
|
||||
} else {
|
||||
self.build_with_ar_cmd()
|
||||
let res = match self.llvm_archive_kind() {
|
||||
Some(kind) => self.build_with_llvm(kind),
|
||||
None => self.build_with_ar_cmd(),
|
||||
};
|
||||
if let Err(e) = res {
|
||||
self.config.sess.fatal(&format!("failed to build archive: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn using_llvm(&self) -> bool {
|
||||
pub fn llvm_archive_kind(&self) -> Option<ArchiveKind> {
|
||||
if unsafe { llvm::LLVMVersionMinor() < 7 } {
|
||||
return false
|
||||
return None
|
||||
}
|
||||
|
||||
// Currently LLVM only supports writing archives in the 'gnu' format.
|
||||
match &self.config.sess.target.target.options.archive_format[..] {
|
||||
"gnu" => true,
|
||||
_ => false,
|
||||
"gnu" => Some(ArchiveKind::K_GNU),
|
||||
"mips64" => Some(ArchiveKind::K_MIPS64),
|
||||
"bsd" => Some(ArchiveKind::K_BSD),
|
||||
"coff" => Some(ArchiveKind::K_COFF),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn using_llvm(&self) -> bool {
|
||||
self.llvm_archive_kind().is_some()
|
||||
}
|
||||
|
||||
fn build_with_ar_cmd(&mut self) -> io::Result<()> {
|
||||
let removals = mem::replace(&mut self.removals, Vec::new());
|
||||
let additions = mem::replace(&mut self.additions, Vec::new());
|
||||
|
|
@ -425,7 +431,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_with_llvm(&mut self) -> io::Result<()> {
|
||||
fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
|
||||
let mut archives = Vec::new();
|
||||
let mut strings = Vec::new();
|
||||
let mut members = Vec::new();
|
||||
|
|
@ -482,7 +488,8 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
let r = llvm::LLVMRustWriteArchive(dst.as_ptr(),
|
||||
members.len() as libc::size_t,
|
||||
members.as_ptr(),
|
||||
self.should_update_symbols);
|
||||
self.should_update_symbols,
|
||||
kind);
|
||||
let ret = if r != 0 {
|
||||
let err = llvm::LLVMRustGetLastError();
|
||||
let msg = if err.is_null() {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,17 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
|
|||
|
||||
extern "C" const char*
|
||||
LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
|
||||
StringRef buf = child->getBuffer();
|
||||
StringRef buf;
|
||||
#if LLVM_VERSION_MINOR >= 7
|
||||
ErrorOr<StringRef> buf_or_err = child->getBuffer();
|
||||
if (buf_or_err.getError()) {
|
||||
LLVMRustSetLastError(buf_or_err.getError().message().c_str());
|
||||
return NULL;
|
||||
}
|
||||
buf = buf_or_err.get();
|
||||
#else
|
||||
buf = child->getBuffer();
|
||||
#endif
|
||||
*size = buf.size();
|
||||
return buf.data();
|
||||
}
|
||||
|
|
@ -144,7 +154,8 @@ extern "C" int
|
|||
LLVMRustWriteArchive(char *Dst,
|
||||
size_t NumMembers,
|
||||
const LLVMRustArchiveMember **NewMembers,
|
||||
bool WriteSymbtab) {
|
||||
bool WriteSymbtab,
|
||||
Archive::Kind Kind) {
|
||||
#if LLVM_VERSION_MINOR >= 7
|
||||
std::vector<NewArchiveIterator> Members;
|
||||
|
||||
|
|
@ -157,7 +168,7 @@ LLVMRustWriteArchive(char *Dst,
|
|||
Members.push_back(NewArchiveIterator(Member->child, Member->name));
|
||||
}
|
||||
}
|
||||
auto pair = writeArchive(Dst, Members, WriteSymbtab);
|
||||
auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, false);
|
||||
if (!pair.second)
|
||||
return 0;
|
||||
LLVMRustSetLastError(pair.second.message().c_str());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue