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.
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()
}
position_independent_executables: true,
pre_link_args: vec!(
),
+ archive_format: "bsd".to_string(),
.. Default::default()
}
"-Wl,--as-needed".to_string(),
),
position_independent_executables: true,
+ archive_format: "bsd".to_string(),
.. Default::default()
}
}
executables: true,
morestack: true,
has_rpath: true,
+ archive_format: "bsd".to_string(),
.. Default::default()
}
"-Wl,--as-needed".to_string(),
),
position_independent_executables: true,
+ archive_format: "bsd".to_string(),
.. Default::default()
}
}
"-Wl,--as-needed".to_string(),
),
position_independent_executables: true,
+ archive_format: "bsd".to_string(),
.. Default::default()
}
}
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)
}
}
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 {}
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;
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;
/// 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());
}
}
- 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();
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() {
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();
}
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;
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());