]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Invert some rpath dependencies
authorBrian Anderson <banderson@mozilla.com>
Sun, 6 Jul 2014 21:08:09 +0000 (14:08 -0700)
committerBrian Anderson <banderson@mozilla.com>
Mon, 14 Jul 2014 19:27:07 +0000 (12:27 -0700)
src/librustc/back/link.rs
src/librustc/back/rpath.rs

index 2112e8d822d38c2deabdb3be92fa1ea02923b8c8..e08c071ff4e6249b8dbbf704d6b2b6c9a090f532 100644 (file)
@@ -10,6 +10,7 @@
 
 use super::archive::{Archive, METADATA_FILENAME};
 use super::rpath;
+use super::rpath::RPathConfig;
 use super::svh::Svh;
 use driver::driver::{CrateTranslation, OutputFilenames, Input, FileInput};
 use driver::config::NoDebugInfo;
@@ -1385,7 +1386,24 @@ fn link_args(cmd: &mut Command,
     // where extern libraries might live, based on the
     // addl_lib_search_paths
     if sess.opts.cg.rpath {
-        cmd.args(rpath::get_rpath_flags(sess, out_filename).as_slice());
+        let sysroot = sess.sysroot();
+        let target_triple = sess.opts.target_triple.as_slice();
+        let get_install_prefix_lib_path = || {
+            let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
+            let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
+            let mut path = Path::new(install_prefix);
+            path.push(&tlib);
+
+            path
+        };
+        let rpath_config = RPathConfig {
+            os: sess.targ_cfg.os,
+            used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
+            out_filename: out_filename.clone(),
+            get_install_prefix_lib_path: get_install_prefix_lib_path,
+            realpath: ::util::fs::realpath
+        };
+        cmd.args(rpath::get_rpath_flags(rpath_config).as_slice());
     }
 
     // compiler-rt contains implementations of low-level LLVM helpers. This is
index a458cf22a5bdc3c545b2be4ab43899333c92e3e3..6a133d8619abcd446f096fa7ea98e2cb9705c374 100644 (file)
@@ -9,30 +9,30 @@
 // except according to those terms.
 
 
-use driver::session::Session;
-use metadata::cstore;
-use metadata::filesearch;
-use util::fs;
-
 use std::collections::HashSet;
 use std::os;
+use std::io::IoError;
 use syntax::abi;
-
-fn not_win32(os: abi::Os) -> bool {
-  os != abi::OsWin32
+use syntax::ast;
+
+pub struct RPathConfig<'a> {
+    pub os: abi::Os,
+    pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
+    pub out_filename: Path,
+    pub get_install_prefix_lib_path: ||:'a -> Path,
+    pub realpath: |&Path|:'a -> Result<Path, IoError>
 }
 
-pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<String> {
-    let os = sess.targ_cfg.os;
+pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> {
 
     // No rpath on windows
-    if os == abi::OsWin32 {
+    if config.os == abi::OsWin32 {
         return Vec::new();
     }
 
     let mut flags = Vec::new();
 
-    if sess.targ_cfg.os == abi::OsFreebsd {
+    if config.os == abi::OsFreebsd {
         flags.push_all(["-Wl,-rpath,/usr/local/lib/gcc46".to_string(),
                         "-Wl,-rpath,/usr/local/lib/gcc44".to_string(),
                         "-Wl,-z,origin".to_string()]);
@@ -40,23 +40,17 @@ pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<String> {
 
     debug!("preparing the RPATH!");
 
-    let sysroot = sess.sysroot();
-    let output = out_filename;
-    let libs = sess.cstore.get_used_crates(cstore::RequireDynamic);
+    let libs = config.used_crates.clone();
     let libs = libs.move_iter().filter_map(|(_, l)| {
         l.map(|p| p.clone())
     }).collect::<Vec<_>>();
 
-    let rpaths = get_rpaths(os,
-                            sysroot,
-                            output,
-                            libs.as_slice(),
-                            sess.opts.target_triple.as_slice());
+    let rpaths = get_rpaths(config, libs.as_slice());
     flags.push_all(rpaths_to_flags(rpaths.as_slice()).as_slice());
     flags
 }
 
-pub fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
+fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
     let mut ret = Vec::new();
     for rpath in rpaths.iter() {
         ret.push(format!("-Wl,-rpath,{}", (*rpath).as_slice()));
@@ -64,26 +58,21 @@ pub fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
     return ret;
 }
 
-fn get_rpaths(os: abi::Os,
-              sysroot: &Path,
-              output: &Path,
-              libs: &[Path],
-              target_triple: &str) -> Vec<String> {
-    debug!("sysroot: {}", sysroot.display());
-    debug!("output: {}", output.display());
+fn get_rpaths(mut config: RPathConfig,
+              libs: &[Path]) -> Vec<String> {
+    debug!("output: {}", config.out_filename.display());
     debug!("libs:");
     for libpath in libs.iter() {
         debug!("    {}", libpath.display());
     }
-    debug!("target_triple: {}", target_triple);
 
     // Use relative paths to the libraries. Binaries can be moved
     // as long as they maintain the relative relationship to the
     // crates they depend on.
-    let rel_rpaths = get_rpaths_relative_to_output(os, output, libs);
+    let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs);
 
     // And a final backup rpath to the global library location.
-    let fallback_rpaths = vec!(get_install_prefix_rpath(sysroot, target_triple));
+    let fallback_rpaths = vec!(get_install_prefix_rpath(config));
 
     fn log_rpaths(desc: &str, rpaths: &[String]) {
         debug!("{} rpaths:", desc);
@@ -103,31 +92,28 @@ fn log_rpaths(desc: &str, rpaths: &[String]) {
     return rpaths;
 }
 
-fn get_rpaths_relative_to_output(os: abi::Os,
-                                 output: &Path,
+fn get_rpaths_relative_to_output(config: &mut RPathConfig,
                                  libs: &[Path]) -> Vec<String> {
-    libs.iter().map(|a| get_rpath_relative_to_output(os, output, a)).collect()
+    libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
 }
 
-pub fn get_rpath_relative_to_output(os: abi::Os,
-                                    output: &Path,
-                                    lib: &Path)
-                                 -> String {
+fn get_rpath_relative_to_output(config: &mut RPathConfig,
+                                lib: &Path) -> String {
     use std::os;
 
-    assert!(not_win32(os));
+    assert!(config.os != abi::OsWin32);
 
     // Mac doesn't appear to support $ORIGIN
-    let prefix = match os {
+    let prefix = match config.os {
         abi::OsAndroid | abi::OsLinux | abi::OsFreebsd
                           => "$ORIGIN",
         abi::OsMacos => "@loader_path",
         abi::OsWin32 | abi::OsiOS => unreachable!()
     };
 
-    let mut lib = fs::realpath(&os::make_absolute(lib)).unwrap();
+    let mut lib = (config.realpath)(&os::make_absolute(lib)).unwrap();
     lib.pop();
-    let mut output = fs::realpath(&os::make_absolute(output)).unwrap();
+    let mut output = (config.realpath)(&os::make_absolute(&config.out_filename)).unwrap();
     output.pop();
     let relative = lib.path_relative_from(&output);
     let relative = relative.expect("could not create rpath relative to output");
@@ -137,18 +123,14 @@ pub fn get_rpath_relative_to_output(os: abi::Os,
             relative.as_str().expect("non-utf8 component in path"))
 }
 
-pub fn get_install_prefix_rpath(sysroot: &Path, target_triple: &str) -> String {
-    let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
-
-    let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
-    let mut path = Path::new(install_prefix);
-    path.push(&tlib);
+fn get_install_prefix_rpath(config: RPathConfig) -> String {
+    let path = (config.get_install_prefix_lib_path)();
     let path = os::make_absolute(&path);
     // FIXME (#9639): This needs to handle non-utf8 paths
     path.as_str().expect("non-utf8 component in rpath").to_string()
 }
 
-pub fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
+fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
     let mut set = HashSet::new();
     let mut minimized = Vec::new();
     for rpath in rpaths.iter() {
@@ -161,10 +143,9 @@ pub fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
 
 #[cfg(unix, test)]
 mod test {
-    use back::rpath::get_install_prefix_rpath;
-    use back::rpath::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
+    use super::{RPathConfig};
+    use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
     use syntax::abi;
-    use metadata::filesearch;
 
     #[test]
     fn test_rpaths_to_flags() {
@@ -177,27 +158,6 @@ fn test_rpaths_to_flags() {
                         "-Wl,-rpath,path2".to_string()));
     }
 
-    #[test]
-    fn test_prefix_rpath() {
-        let sysroot = filesearch::get_or_default_sysroot();
-        let res = get_install_prefix_rpath(&sysroot, "triple");
-        let mut d = Path::new((option_env!("CFG_PREFIX")).expect("CFG_PREFIX"));
-        d.push("lib");
-        d.push(filesearch::rustlibdir());
-        d.push("triple/lib");
-        debug!("test_prefix_path: {} vs. {}",
-               res,
-               d.display());
-        assert!(res.as_bytes().ends_with(d.as_vec()));
-    }
-
-    #[test]
-    fn test_prefix_rpath_abs() {
-        let sysroot = filesearch::get_or_default_sysroot();
-        let res = get_install_prefix_rpath(&sysroot, "triple");
-        assert!(Path::new(res).is_absolute());
-    }
-
     #[test]
     fn test_minimize1() {
         let res = minimize_rpaths([
@@ -237,28 +197,42 @@ fn test_minimize2() {
     #[cfg(target_os = "linux")]
     #[cfg(target_os = "android")]
     fn test_rpath_relative() {
-      let o = abi::OsLinux;
-      let res = get_rpath_relative_to_output(o,
-            &Path::new("bin/rustc"), &Path::new("lib/libstd.so"));
-      assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+        let config = &mut RPathConfig {
+            os: abi::OsLinux,
+            used_crates: Vec::new(),
+            out_filename: Path::new("bin/rustc"),
+            get_install_prefix_lib_path: || fail!(),
+            realpath: |p| Ok(p.clone())
+        };
+        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
+        assert_eq!(res.as_slice(), "$ORIGIN/../lib");
     }
 
     #[test]
     #[cfg(target_os = "freebsd")]
     fn test_rpath_relative() {
-        let o = abi::OsFreebsd;
-        let res = get_rpath_relative_to_output(o,
-            &Path::new("bin/rustc"), &Path::new("lib/libstd.so"));
+        let config = &mut RPathConfig {
+            os: abi::OsFreebsd,
+            used_crates: Vec::new(),
+            out_filename: Path::new("bin/rustc"),
+            get_install_prefix_lib_path: || fail!(),
+            realpath: |p| Ok(p.clone())
+        };
+        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
         assert_eq!(res.as_slice(), "$ORIGIN/../lib");
     }
 
     #[test]
     #[cfg(target_os = "macos")]
     fn test_rpath_relative() {
-        let o = abi::OsMacos;
-        let res = get_rpath_relative_to_output(o,
-                                               &Path::new("bin/rustc"),
-                                               &Path::new("lib/libstd.so"));
+        let config = &mut RPathConfig {
+            os: abi::OsMacos,
+            used_crates: Vec::new(),
+            out_filename: Path::new("bin/rustc"),
+            get_install_prefix_lib_path: || fail!(),
+            realpath: |p| p.clone()
+        };
+        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
         assert_eq!(res.as_slice(), "@loader_path/../lib");
     }
 }