From 8b4601e08eb0ac54f4c8c12b4dd762b89248abca Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 4 Oct 2011 20:07:18 -0700 Subject: [PATCH] Figure out the relative path from output to each crate --- src/comp/back/rpath.rs | 77 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/src/comp/back/rpath.rs b/src/comp/back/rpath.rs index 1ced0de2fde2..214be55f4e0e 100644 --- a/src/comp/back/rpath.rs +++ b/src/comp/back/rpath.rs @@ -1,10 +1,13 @@ import std::os; import std::fs; +import std::os_fs; import std::vec; +import std::map; +import std::str; +import std::uint; import metadata::cstore; import driver::session; import util::filesearch; -import std::map; export get_rpath_flags, test; @@ -70,18 +73,44 @@ fn get_rpaths_relative_to_output(cwd: fs::path, vec::map(bind get_rpath_relative_to_output(cwd, output, _), libs) } -fn get_rpath_relative_to_output(_cwd: fs::path, - _output: fs::path, - _lib: fs::path) -> str { - fail; - /*get_relative_to( +fn get_rpath_relative_to_output(cwd: fs::path, + output: fs::path, + lib: fs::path) -> str { + "$ORIGIN" + fs::path_sep() + get_relative_to( get_absolute(cwd, output), - get_absolute(cwd, lib))*/ + get_absolute(cwd, lib)) } // Find the relative path from one file to another -fn get_relative_to(_abs1: fs::path, _abs2: fs::path) -> fs::path { - fail; +fn get_relative_to(abs1: fs::path, abs2: fs::path) -> fs::path { + assert fs::path_is_absolute(abs1); + assert fs::path_is_absolute(abs2); + let normal1 = fs::normalize(abs1); + let normal2 = fs::normalize(abs2); + let split1 = str::split(normal1, os_fs::path_sep as u8); + let split2 = str::split(normal2, os_fs::path_sep as u8); + let len1 = vec::len(split1); + let len2 = vec::len(split2); + assert len1 > 0u; + assert len2 > 0u; + + let max_common_path = uint::min(len1, len2) - 1u; + let start_idx = 0u; + while start_idx < max_common_path + && split1[start_idx] == split2[start_idx] { + start_idx += 1u; + } + + let path = []; + + for each _ in uint::range(start_idx, len1 - 1u) { + path += [".."]; + } + + path += vec::slice(split2, start_idx, len2 - 1u); + + check vec::is_not_empty(path); + ret fs::connect_many(path); } fn get_absolute_rpaths(cwd: fs::path, libs: [fs::path]) -> [str] { @@ -159,7 +188,6 @@ mod test { } #[test] - #[ignore] fn test_relative_to1() { let p1 = "/usr/bin/rustc"; let p2 = "/usr/lib/mylib"; @@ -168,7 +196,6 @@ mod test { } #[test] - #[ignore] fn test_relative_to2() { let p1 = "/usr/bin/rustc"; let p2 = "/usr/bin/../lib/mylib"; @@ -177,7 +204,6 @@ mod test { } #[test] - #[ignore] fn test_relative_to3() { let p1 = "/usr/bin/whatever/rustc"; let p2 = "/usr/lib/whatever/mylib"; @@ -186,7 +212,6 @@ mod test { } #[test] - #[ignore] fn test_relative_to4() { let p1 = "/usr/bin/whatever/../rustc"; let p2 = "/usr/lib/whatever/mylib"; @@ -195,11 +220,33 @@ mod test { } #[test] - #[ignore] fn test_relative_to5() { let p1 = "/usr/bin/whatever/../rustc"; let p2 = "/usr/lib/whatever/../mylib"; let res = get_relative_to(p1, p2); - assert res == "../lib/whatever"; + assert res == "../lib"; + } + + #[test] + fn test_relative_to6() { + let p1 = "/1"; + let p2 = "/2/3"; + let res = get_relative_to(p1, p2); + assert res == "2"; + } + + #[test] + fn test_relative_to7() { + let p1 = "/1/2"; + let p2 = "/3"; + let res = get_relative_to(p1, p2); + assert res == ".."; + } + + #[test] + fn test_rpath_relative() { + let res = get_rpath_relative_to_output( + "/usr", "bin/rustc", "lib/libstd.so"); + assert res == "$ORIGIN/../lib"; } }