1 // A module for searching for libraries
2 // FIXME: I'm not happy how this module turned out. Should probably
3 // just be folded into cstore.
10 import std::generic_os;
17 export relative_target_lib_path;
18 export get_cargo_root;
20 type pick<T> = block(path: fs::path) -> option::t<T>;
22 fn pick_file(file: fs::path, path: fs::path) -> option::t<fs::path> {
23 if fs::basename(path) == file { option::some(path) }
27 type filesearch = obj {
28 fn sysroot() -> fs::path;
29 fn lib_search_paths() -> [fs::path];
30 fn get_target_lib_path() -> fs::path;
31 fn get_target_lib_file_path(file: fs::path) -> fs::path;
34 fn mk_filesearch(maybe_sysroot: option::t<fs::path>,
36 addl_lib_search_paths: [fs::path]) -> filesearch {
37 obj filesearch_impl(sysroot: fs::path,
38 addl_lib_search_paths: [fs::path],
40 fn sysroot() -> fs::path { sysroot }
41 fn lib_search_paths() -> [fs::path] {
43 + [make_target_lib_path(sysroot, target_triple)]
44 + alt get_cargo_lib_path() {
50 fn get_target_lib_path() -> fs::path {
51 make_target_lib_path(sysroot, target_triple)
54 fn get_target_lib_file_path(file: fs::path) -> fs::path {
55 fs::connect(self.get_target_lib_path(), file)
59 let sysroot = get_sysroot(maybe_sysroot);
60 #debug("using sysroot = %s", sysroot);
61 ret filesearch_impl(sysroot, addl_lib_search_paths, target_triple);
64 // FIXME #1001: This can't be an obj method
65 fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option::t<T> {
66 for lib_search_path in filesearch.lib_search_paths() {
67 #debug("searching %s", lib_search_path);
68 for path in fs::list_dir(lib_search_path) {
69 #debug("testing %s", path);
70 let maybe_picked = pick(path);
71 if option::is_some(maybe_picked) {
72 #debug("picked %s", path);
75 #debug("rejected %s", path);
82 fn relative_target_lib_path(target_triple: str) -> [fs::path] {
83 ["lib", "rustc", target_triple, "lib"]
86 fn make_target_lib_path(sysroot: fs::path,
87 target_triple: str) -> fs::path {
88 let path = [sysroot] + relative_target_lib_path(target_triple);
89 check vec::is_not_empty(path);
90 let path = fs::connect_many(path);
94 fn get_default_sysroot() -> fs::path {
95 alt os::get_exe_path() {
96 option::some(p) { fs::normalize(fs::connect(p, "..")) }
98 fail "can't determine value for sysroot";
103 fn get_sysroot(maybe_sysroot: option::t<fs::path>) -> fs::path {
105 option::some(sr) { sr }
106 option::none. { get_default_sysroot() }
110 fn get_cargo_root() -> result::t<fs::path, str> {
111 alt generic_os::getenv("CARGO_ROOT") {
112 some(_p) { result::ok(_p) }
114 alt generic_os::getenv("HOME") {
115 some(_q) { result::ok(fs::connect(_q, ".cargo")) }
116 none. { result::err("no CARGO_ROOT or HOME") }
122 fn get_cargo_lib_path() -> result::t<fs::path, str> {
123 result::chain(get_cargo_root()) { |p|
124 result::ok(fs::connect(p, "lib"))