Skip to content

Implement LTO #10812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions src/librustc/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use std::str;
use extra::tempfile::TempDir;
use syntax::abi;

pub static METADATA_FILENAME: &'static str = "metadata";

pub struct Archive {
priv sess: Session,
priv dst: Path,
Expand All @@ -40,7 +42,8 @@ fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
}
let o = Process::new(ar, args.as_slice(), opts).finish_with_output();
if !o.status.success() {
sess.err(format!("{} failed with: {}", ar, o.status));
sess.err(format!("{} {} failed with: {}", ar, args.connect(" "),
o.status));
sess.note(format!("stdout ---\n{}", str::from_utf8(o.output)));
sess.note(format!("stderr ---\n{}", str::from_utf8(o.error)));
sess.abort_if_errors();
Expand Down Expand Up @@ -81,17 +84,40 @@ impl Archive {
/// search in the relevant locations for a library named `name`.
pub fn add_native_library(&mut self, name: &str) {
let location = self.find_library(name);
self.add_archive(&location, name);
self.add_archive(&location, name, []);
}

/// Adds all of the contents of the rlib at the specified path to this
/// archive.
pub fn add_rlib(&mut self, rlib: &Path) {
let name = rlib.filename_str().unwrap().split('-').next().unwrap();
self.add_archive(rlib, name);
///
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
/// then the object file also isn't added.
pub fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool) {
let object = format!("{}.o", name);
let bytecode = format!("{}.bc", name);
let mut ignore = ~[METADATA_FILENAME, bytecode.as_slice()];
if lto {
ignore.push(object.as_slice());
}
self.add_archive(rlib, name, ignore);
}

fn add_archive(&mut self, archive: &Path, name: &str) {
/// Adds an arbitrary file to this archive
pub fn add_file(&mut self, file: &Path) {
run_ar(self.sess, "r", None, [&self.dst, file]);
}

/// Removes a file from this archive
pub fn remove_file(&mut self, file: &str) {
run_ar(self.sess, "d", None, [&self.dst, &Path::new(file)]);
}

pub fn files(&self) -> ~[~str] {
let output = run_ar(self.sess, "t", None, [&self.dst]);
str::from_utf8(output.output).lines().map(|s| s.to_owned()).collect()
}

fn add_archive(&mut self, archive: &Path, name: &str, skip: &[&str]) {
let loc = TempDir::new("rsar").unwrap();

// First, extract the contents of the archive to a temporary directory
Expand All @@ -102,10 +128,17 @@ impl Archive {
// The reason for this is that archives are keyed off the name of the
// files, so if two files have the same name they will override one
// another in the archive (bad).
//
// We skip any files explicitly desired for skipping, and we also skip
// all SYMDEF files as these are just magical placeholders which get
// re-created when we make a new archive anyway.
let files = fs::readdir(loc.path());
let mut inputs = ~[];
for file in files.iter() {
let filename = file.filename_str().unwrap();
if skip.iter().any(|s| *s == filename) { continue }
if filename.contains(".SYMDEF") { continue }

let filename = format!("r-{}-{}", name, filename);
let new_filename = file.with_filename(filename);
fs::rename(file, &new_filename);
Expand Down
Loading