diff options
| author | Brian Anderson <banderson@mozilla.com> | 2014-07-06 20:46:00 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2014-07-14 12:27:07 -0700 |
| commit | 7f6a66f77ef362059328524d54b6b987322d2c36 (patch) | |
| tree | f3655753a1c62a216e34e29f2c4ff028dc8a24d3 | |
| parent | 930abc156789db6ee897a68f02fac6af682cca5b (diff) | |
| download | rust-7f6a66f77ef362059328524d54b6b987322d2c36.tar.gz rust-7f6a66f77ef362059328524d54b6b987322d2c36.zip | |
rustc: Invert some archive deps
| -rw-r--r-- | src/librustc/back/archive.rs | 85 | ||||
| -rw-r--r-- | src/librustc/back/link.rs | 34 |
2 files changed, 85 insertions, 34 deletions
diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs index 8acb610db3f..ac457f208dd 100644 --- a/src/librustc/back/archive.rs +++ b/src/librustc/back/archive.rs @@ -10,9 +10,6 @@ //! A helper class for dealing with static archives -use super::link::{get_ar_prog}; -use driver::session::Session; -use metadata::filesearch; use llvm::{ArchiveRef, llvm}; use libc; @@ -24,22 +21,38 @@ use std::os; use std::raw; use std::str; use syntax::abi; +use ErrorHandler = syntax::diagnostic::Handler; pub static METADATA_FILENAME: &'static str = "rust.metadata.bin"; +pub struct ArchiveConfig<'a> { + pub handler: &'a ErrorHandler, + pub dst: Path, + pub lib_search_paths: Vec<Path>, + pub os: abi::Os, + pub maybe_ar_prog: Option<String> +} + pub struct Archive<'a> { - sess: &'a Session, + handler: &'a ErrorHandler, dst: Path, + lib_search_paths: Vec<Path>, + os: abi::Os, + maybe_ar_prog: Option<String> } pub struct ArchiveRO { ptr: ArchiveRef, } -fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>, +fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>, + args: &str, cwd: Option<&Path>, paths: &[&Path]) -> ProcessOutput { - let ar = get_ar_prog(sess); - let mut cmd = Command::new(ar.as_slice()); + let ar = match *maybe_ar_prog { + Some(ref ar) => ar.as_slice(), + None => "ar" + }; + let mut cmd = Command::new(ar); cmd.arg(args).args(paths); debug!("{}", cmd); @@ -56,25 +69,25 @@ fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>, Ok(prog) => { let o = prog.wait_with_output().unwrap(); if !o.status.success() { - sess.err(format!("{} failed with: {}", + handler.err(format!("{} failed with: {}", cmd, o.status).as_slice()); - sess.note(format!("stdout ---\n{}", + handler.note(format!("stdout ---\n{}", str::from_utf8(o.output .as_slice()).unwrap()) .as_slice()); - sess.note(format!("stderr ---\n{}", + handler.note(format!("stderr ---\n{}", str::from_utf8(o.error .as_slice()).unwrap()) .as_slice()); - sess.abort_if_errors(); + handler.abort_if_errors(); } o }, Err(e) => { - sess.err(format!("could not exec `{}`: {}", ar.as_slice(), + handler.err(format!("could not exec `{}`: {}", ar.as_slice(), e).as_slice()); - sess.abort_if_errors(); + handler.abort_if_errors(); fail!("rustc::back::archive::run_ar() should not reach this point"); } } @@ -82,16 +95,29 @@ fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>, impl<'a> Archive<'a> { /// Initializes a new static archive with the given object file - pub fn create<'b>(sess: &'a Session, dst: &'b Path, - initial_object: &'b Path) -> Archive<'a> { - run_ar(sess, "crus", None, [dst, initial_object]); - Archive { sess: sess, dst: dst.clone() } + pub fn create<'b>(config: ArchiveConfig<'a>, initial_object: &'b Path) -> Archive<'a> { + let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config; + run_ar(handler, &maybe_ar_prog, "crus", None, [&dst, initial_object]); + Archive { + handler: handler, + dst: dst, + lib_search_paths: lib_search_paths, + os: os, + maybe_ar_prog: maybe_ar_prog + } } /// Opens an existing static archive - pub fn open(sess: &'a Session, dst: Path) -> Archive<'a> { + pub fn open(config: ArchiveConfig<'a>) -> Archive<'a> { + let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config; assert!(dst.exists()); - Archive { sess: sess, dst: dst } + Archive { + handler: handler, + dst: dst, + lib_search_paths: lib_search_paths, + os: os, + maybe_ar_prog: maybe_ar_prog + } } /// Adds all of the contents of a native library to this archive. This will @@ -120,22 +146,22 @@ impl<'a> Archive<'a> { /// Adds an arbitrary file to this archive pub fn add_file(&mut self, file: &Path, has_symbols: bool) { let cmd = if has_symbols {"r"} else {"rS"}; - run_ar(self.sess, cmd, None, [&self.dst, file]); + run_ar(self.handler, &self.maybe_ar_prog, cmd, 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)]); + run_ar(self.handler, &self.maybe_ar_prog, "d", None, [&self.dst, &Path::new(file)]); } /// Updates all symbols in the archive (runs 'ar s' over it) pub fn update_symbols(&mut self) { - run_ar(self.sess, "s", None, [&self.dst]); + run_ar(self.handler, &self.maybe_ar_prog, "s", None, [&self.dst]); } /// Lists all files in an archive pub fn files(&self) -> Vec<String> { - let output = run_ar(self.sess, "t", None, [&self.dst]); + let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, [&self.dst]); let output = str::from_utf8(output.output.as_slice()).unwrap(); // use lines_any because windows delimits output with `\r\n` instead of // just `\n` @@ -148,7 +174,7 @@ impl<'a> Archive<'a> { // First, extract the contents of the archive to a temporary directory let archive = os::make_absolute(archive); - run_ar(self.sess, "x", Some(loc.path()), [&archive]); + run_ar(self.handler, &self.maybe_ar_prog, "x", Some(loc.path()), [&archive]); // Next, we must rename all of the inputs to "guaranteed unique names". // The reason for this is that archives are keyed off the name of the @@ -184,12 +210,12 @@ impl<'a> Archive<'a> { // Finally, add all the renamed files to this archive let mut args = vec!(&self.dst); args.extend(inputs.iter()); - run_ar(self.sess, "r", None, args.as_slice()); + run_ar(self.handler, &self.maybe_ar_prog, "r", None, args.as_slice()); Ok(()) } fn find_library(&self, name: &str) -> Path { - let (osprefix, osext) = match self.sess.targ_cfg.os { + let (osprefix, osext) = match self.os { abi::OsWin32 => ("", "lib"), _ => ("lib", "a"), }; // On Windows, static libraries sometimes show up as libfoo.a and other @@ -197,10 +223,7 @@ impl<'a> Archive<'a> { let oslibname = format!("{}{}.{}", osprefix, name, osext); let unixlibname = format!("lib{}.a", name); - let mut rustpath = filesearch::rust_path(); - rustpath.push(self.sess.target_filesearch().get_lib_path()); - let search = self.sess.opts.addl_lib_search_paths.borrow(); - for path in search.iter().chain(rustpath.iter()) { + for path in self.lib_search_paths.iter() { debug!("looking for {} inside {}", name, path.display()); let test = path.join(oslibname.as_slice()); if test.exists() { return test } @@ -209,7 +232,7 @@ impl<'a> Archive<'a> { if test.exists() { return test } } } - self.sess.fatal(format!("could not find native static library `{}`, \ + self.handler.fatal(format!("could not find native static library `{}`, \ perhaps an -L flag is missing?", name).as_slice()); } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index e08c071ff4e..a552f542150 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::archive::{Archive, METADATA_FILENAME}; +use super::archive::{Archive, ArchiveConfig, METADATA_FILENAME}; use super::rpath; use super::rpath::RPathConfig; use super::svh::Svh; @@ -29,6 +29,7 @@ use util::sha2::{Digest, Sha256}; use std::c_str::{ToCStr, CString}; use std::char; +use std::collections::HashSet; use std::io::{fs, TempDir, Command}; use std::io; use std::ptr; @@ -962,6 +963,17 @@ fn link_binary_output(sess: &Session, out_filename } +fn archive_search_paths(sess: &Session) -> Vec<Path> { + let mut rustpath = filesearch::rust_path(); + rustpath.push(sess.target_filesearch().get_lib_path()); + // FIXME: Addl lib search paths are an unordered HashSet? + // Shouldn't this search be done in some order? + let addl_lib_paths: HashSet<Path> = sess.opts.addl_lib_search_paths.borrow().clone(); + let mut search: Vec<Path> = addl_lib_paths.move_iter().collect(); + search.push_all(rustpath.as_slice()); + return search; +} + // Create an 'rlib' // // An rlib in its current incarnation is essentially a renamed .a file. The @@ -972,7 +984,15 @@ fn link_rlib<'a>(sess: &'a Session, trans: Option<&CrateTranslation>, // None == no metadata/bytecode obj_filename: &Path, out_filename: &Path) -> Archive<'a> { - let mut a = Archive::create(sess, out_filename, obj_filename); + let handler = &sess.diagnostic().handler; + let config = ArchiveConfig { + handler: handler, + dst: out_filename.clone(), + lib_search_paths: archive_search_paths(sess), + os: sess.targ_cfg.os, + maybe_ar_prog: sess.opts.cg.ar.clone() + }; + let mut a = Archive::create(config, obj_filename); for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() { match kind { @@ -1561,7 +1581,15 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, sess.abort_if_errors(); } } - let mut archive = Archive::open(sess, dst.clone()); + let handler = &sess.diagnostic().handler; + let config = ArchiveConfig { + handler: handler, + dst: dst.clone(), + lib_search_paths: archive_search_paths(sess), + os: sess.targ_cfg.os, + maybe_ar_prog: sess.opts.cg.ar.clone() + }; + let mut archive = Archive::open(config); archive.remove_file(format!("{}.o", name).as_slice()); let files = archive.files(); if files.iter().any(|s| s.as_slice().ends_with(".o")) { |
