Skip to content

Commit

Permalink
trans: Add kind to writeArchive
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alexcrichton committed Jul 17, 2015
1 parent 7f0e733 commit 74e1981
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/librustc_back/target/apple_base.rs
Expand Up @@ -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()
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/bitrig_base.rs
Expand Up @@ -22,6 +22,7 @@ pub fn opts() -> TargetOptions {
position_independent_executables: true,
pre_link_args: vec!(
),
archive_format: "bsd".to_string(),

.. Default::default()
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/dragonfly_base.rs
Expand Up @@ -29,6 +29,7 @@ pub fn opts() -> TargetOptions {
"-Wl,--as-needed".to_string(),
),
position_independent_executables: true,
archive_format: "bsd".to_string(),
.. Default::default()
}
}
1 change: 1 addition & 0 deletions src/librustc_back/target/freebsd_base.rs
Expand Up @@ -18,6 +18,7 @@ pub fn opts() -> TargetOptions {
executables: true,
morestack: true,
has_rpath: true,
archive_format: "bsd".to_string(),

.. Default::default()
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/netbsd_base.rs
Expand Up @@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
"-Wl,--as-needed".to_string(),
),
position_independent_executables: true,
archive_format: "bsd".to_string(),
.. Default::default()
}
}
1 change: 1 addition & 0 deletions src/librustc_back/target/openbsd_base.rs
Expand Up @@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
"-Wl,--as-needed".to_string(),
),
position_independent_executables: true,
archive_format: "bsd".to_string(),
.. Default::default()
}
}
3 changes: 3 additions & 0 deletions src/librustc_llvm/archive_ro.rs
Expand Up @@ -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)
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/librustc_llvm/lib.rs
Expand Up @@ -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 {}
Expand Down Expand Up @@ -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;
Expand Down
29 changes: 18 additions & 11 deletions src/librustc_trans/back/archive.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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() {
Expand Down
17 changes: 14 additions & 3 deletions src/rustllvm/ArchiveWrapper.cpp
Expand Up @@ -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();
}
Expand All @@ -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;

Expand All @@ -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());
Expand Down

0 comments on commit 74e1981

Please sign in to comment.