]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Invert some archive deps
authorBrian Anderson <banderson@mozilla.com>
Mon, 7 Jul 2014 03:46:00 +0000 (20:46 -0700)
committerBrian Anderson <banderson@mozilla.com>
Mon, 14 Jul 2014 19:27:07 +0000 (12:27 -0700)
src/librustc/back/archive.rs
src/librustc/back/link.rs

index 8acb610db3f597419a2f309dbe27c39442912b9e..ac457f208dd05b4720a37d42f4b40bdb1e057180 100644 (file)
@@ -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;
 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 @@ pub fn add_rlib(&mut self, rlib: &Path, name: &str,
     /// 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 @@ fn add_archive(&mut self, archive: &Path, name: &str,
 
         // 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 @@ fn add_archive(&mut self, archive: &Path, name: &str,
         // 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 @@ fn find_library(&self, name: &str) -> Path {
         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 @@ fn find_library(&self, name: &str) -> Path {
                 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());
     }
index e08c071ff4e6249b8dbbf704d6b2b6c9a090f532..a552f5421505523f47ae5bc6f7ad46d03252e7ec 100644 (file)
@@ -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 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_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
                         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")) {