Skip to content

Commit 74e1981

Browse files
committed
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.
1 parent 7f0e733 commit 74e1981

File tree

10 files changed

+52
-15
lines changed

10 files changed

+52
-15
lines changed

src/librustc_back/target/apple_base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions {
2323
has_rpath: true,
2424
dll_prefix: "lib".to_string(),
2525
dll_suffix: ".dylib".to_string(),
26+
archive_format: "bsd".to_string(),
2627
pre_link_args: Vec::new(),
2728
.. Default::default()
2829
}

src/librustc_back/target/bitrig_base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub fn opts() -> TargetOptions {
2222
position_independent_executables: true,
2323
pre_link_args: vec!(
2424
),
25+
archive_format: "bsd".to_string(),
2526

2627
.. Default::default()
2728
}

src/librustc_back/target/dragonfly_base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn opts() -> TargetOptions {
2929
"-Wl,--as-needed".to_string(),
3030
),
3131
position_independent_executables: true,
32+
archive_format: "bsd".to_string(),
3233
.. Default::default()
3334
}
3435
}

src/librustc_back/target/freebsd_base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub fn opts() -> TargetOptions {
1818
executables: true,
1919
morestack: true,
2020
has_rpath: true,
21+
archive_format: "bsd".to_string(),
2122

2223
.. Default::default()
2324
}

src/librustc_back/target/netbsd_base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
2727
"-Wl,--as-needed".to_string(),
2828
),
2929
position_independent_executables: true,
30+
archive_format: "bsd".to_string(),
3031
.. Default::default()
3132
}
3233
}

src/librustc_back/target/openbsd_base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
2727
"-Wl,--as-needed".to_string(),
2828
),
2929
position_independent_executables: true,
30+
archive_format: "bsd".to_string(),
3031
.. Default::default()
3132
}
3233
}

src/librustc_llvm/archive_ro.rs

+3
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ impl<'a> Child<'a> {
118118
unsafe {
119119
let mut data_len = 0;
120120
let data_ptr = ::LLVMRustArchiveChildData(self.ptr, &mut data_len);
121+
if data_ptr.is_null() {
122+
panic!("failed to read data from archive child");
123+
}
121124
slice::from_raw_parts(data_ptr as *const u8, data_len as usize)
122125
}
123126
}

src/librustc_llvm/lib.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,15 @@ pub enum DiagnosticKind {
452452
DK_OptimizationFailure,
453453
}
454454

455+
#[repr(C)]
456+
#[derive(Copy, Clone)]
457+
pub enum ArchiveKind {
458+
K_GNU,
459+
K_MIPS64,
460+
K_BSD,
461+
K_COFF,
462+
}
463+
455464
// Opaque pointer types
456465
#[allow(missing_copy_implementations)]
457466
pub enum Module_opaque {}
@@ -2119,7 +2128,8 @@ extern {
21192128
pub fn LLVMRustWriteArchive(Dst: *const c_char,
21202129
NumMembers: size_t,
21212130
Members: *const RustArchiveMemberRef,
2122-
WriteSymbtab: bool) -> c_int;
2131+
WriteSymbtab: bool,
2132+
Kind: ArchiveKind) -> c_int;
21232133
pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
21242134
Name: *const c_char,
21252135
Child: ArchiveChildRef) -> RustArchiveMemberRef;

src/librustc_trans/back/archive.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::str;
2222

2323
use libc;
2424
use llvm::archive_ro::{ArchiveRO, Child};
25-
use llvm;
25+
use llvm::{self, ArchiveKind};
2626
use rustc::metadata::loader::METADATA_FILENAME;
2727
use rustc::session::Session;
2828
use rustc_back::tempdir::TempDir;
@@ -208,28 +208,34 @@ impl<'a> ArchiveBuilder<'a> {
208208
/// Combine the provided files, rlibs, and native libraries into a single
209209
/// `Archive`.
210210
pub fn build(&mut self) {
211-
let res = if self.using_llvm() {
212-
self.build_with_llvm()
213-
} else {
214-
self.build_with_ar_cmd()
211+
let res = match self.llvm_archive_kind() {
212+
Some(kind) => self.build_with_llvm(kind),
213+
None => self.build_with_ar_cmd(),
215214
};
216215
if let Err(e) = res {
217216
self.config.sess.fatal(&format!("failed to build archive: {}", e));
218217
}
219218
}
220219

221-
pub fn using_llvm(&self) -> bool {
220+
pub fn llvm_archive_kind(&self) -> Option<ArchiveKind> {
222221
if unsafe { llvm::LLVMVersionMinor() < 7 } {
223-
return false
222+
return None
224223
}
225224

226225
// Currently LLVM only supports writing archives in the 'gnu' format.
227226
match &self.config.sess.target.target.options.archive_format[..] {
228-
"gnu" => true,
229-
_ => false,
227+
"gnu" => Some(ArchiveKind::K_GNU),
228+
"mips64" => Some(ArchiveKind::K_MIPS64),
229+
"bsd" => Some(ArchiveKind::K_BSD),
230+
"coff" => Some(ArchiveKind::K_COFF),
231+
_ => None,
230232
}
231233
}
232234

235+
pub fn using_llvm(&self) -> bool {
236+
self.llvm_archive_kind().is_some()
237+
}
238+
233239
fn build_with_ar_cmd(&mut self) -> io::Result<()> {
234240
let removals = mem::replace(&mut self.removals, Vec::new());
235241
let additions = mem::replace(&mut self.additions, Vec::new());
@@ -425,7 +431,7 @@ impl<'a> ArchiveBuilder<'a> {
425431
}
426432
}
427433

428-
fn build_with_llvm(&mut self) -> io::Result<()> {
434+
fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
429435
let mut archives = Vec::new();
430436
let mut strings = Vec::new();
431437
let mut members = Vec::new();
@@ -482,7 +488,8 @@ impl<'a> ArchiveBuilder<'a> {
482488
let r = llvm::LLVMRustWriteArchive(dst.as_ptr(),
483489
members.len() as libc::size_t,
484490
members.as_ptr(),
485-
self.should_update_symbols);
491+
self.should_update_symbols,
492+
kind);
486493
let ret = if r != 0 {
487494
let err = llvm::LLVMRustGetLastError();
488495
let msg = if err.is_null() {

src/rustllvm/ArchiveWrapper.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,17 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
120120

121121
extern "C" const char*
122122
LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
123-
StringRef buf = child->getBuffer();
123+
StringRef buf;
124+
#if LLVM_VERSION_MINOR >= 7
125+
ErrorOr<StringRef> buf_or_err = child->getBuffer();
126+
if (buf_or_err.getError()) {
127+
LLVMRustSetLastError(buf_or_err.getError().message().c_str());
128+
return NULL;
129+
}
130+
buf = buf_or_err.get();
131+
#else
132+
buf = child->getBuffer();
133+
#endif
124134
*size = buf.size();
125135
return buf.data();
126136
}
@@ -144,7 +154,8 @@ extern "C" int
144154
LLVMRustWriteArchive(char *Dst,
145155
size_t NumMembers,
146156
const LLVMRustArchiveMember **NewMembers,
147-
bool WriteSymbtab) {
157+
bool WriteSymbtab,
158+
Archive::Kind Kind) {
148159
#if LLVM_VERSION_MINOR >= 7
149160
std::vector<NewArchiveIterator> Members;
150161

@@ -157,7 +168,7 @@ LLVMRustWriteArchive(char *Dst,
157168
Members.push_back(NewArchiveIterator(Member->child, Member->name));
158169
}
159170
}
160-
auto pair = writeArchive(Dst, Members, WriteSymbtab);
171+
auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, false);
161172
if (!pair.second)
162173
return 0;
163174
LLVMRustSetLastError(pair.second.message().c_str());

0 commit comments

Comments
 (0)