2011-10-03 15:54:13 -05:00
|
|
|
// A module for searching for libraries
|
2011-10-04 17:23:32 -05:00
|
|
|
// FIXME: I'm not happy how this module turned out. Should probably
|
|
|
|
// just be folded into cstore.
|
2011-10-03 15:54:13 -05:00
|
|
|
|
2012-02-09 08:30:19 -06:00
|
|
|
import std::{fs, os, generic_os};
|
2011-10-03 14:46:22 -05:00
|
|
|
|
|
|
|
export filesearch;
|
|
|
|
export mk_filesearch;
|
2011-10-03 15:54:13 -05:00
|
|
|
export pick;
|
2011-10-03 16:45:38 -05:00
|
|
|
export pick_file;
|
2011-10-03 15:54:13 -05:00
|
|
|
export search;
|
2011-10-04 17:23:32 -05:00
|
|
|
export relative_target_lib_path;
|
2012-01-05 18:03:28 -06:00
|
|
|
export get_cargo_root;
|
2012-02-05 03:30:03 -06:00
|
|
|
export get_cargo_root_nearest;
|
2012-01-10 19:45:03 -06:00
|
|
|
export libdir;
|
2011-10-03 15:54:13 -05:00
|
|
|
|
2012-01-31 19:05:20 -06:00
|
|
|
type pick<T> = fn(path: fs::path) -> option<T>;
|
2011-10-03 14:46:22 -05:00
|
|
|
|
2012-01-31 19:05:20 -06:00
|
|
|
fn pick_file(file: fs::path, path: fs::path) -> option<fs::path> {
|
2011-10-03 16:45:38 -05:00
|
|
|
if fs::basename(path) == file { option::some(path) }
|
|
|
|
else { option::none }
|
|
|
|
}
|
|
|
|
|
2012-01-13 02:32:05 -06:00
|
|
|
iface filesearch {
|
2011-10-03 14:46:22 -05:00
|
|
|
fn sysroot() -> fs::path;
|
|
|
|
fn lib_search_paths() -> [fs::path];
|
|
|
|
fn get_target_lib_path() -> fs::path;
|
|
|
|
fn get_target_lib_file_path(file: fs::path) -> fs::path;
|
2012-01-13 02:32:05 -06:00
|
|
|
}
|
2011-10-03 14:46:22 -05:00
|
|
|
|
2012-01-31 19:05:20 -06:00
|
|
|
fn mk_filesearch(maybe_sysroot: option<fs::path>,
|
2011-10-03 14:46:22 -05:00
|
|
|
target_triple: str,
|
|
|
|
addl_lib_search_paths: [fs::path]) -> filesearch {
|
2012-01-13 02:32:05 -06:00
|
|
|
type filesearch_impl = {sysroot: fs::path,
|
|
|
|
addl_lib_search_paths: [fs::path],
|
|
|
|
target_triple: str};
|
|
|
|
impl of filesearch for filesearch_impl {
|
|
|
|
fn sysroot() -> fs::path { self.sysroot }
|
2011-10-03 14:46:22 -05:00
|
|
|
fn lib_search_paths() -> [fs::path] {
|
2012-01-13 02:32:05 -06:00
|
|
|
self.addl_lib_search_paths
|
|
|
|
+ [make_target_lib_path(self.sysroot, self.target_triple)]
|
2012-02-05 03:30:03 -06:00
|
|
|
+ alt get_cargo_lib_path_nearest() {
|
|
|
|
result::ok(p) { [p] }
|
|
|
|
result::err(p) { [] }
|
|
|
|
}
|
2012-01-05 18:03:28 -06:00
|
|
|
+ alt get_cargo_lib_path() {
|
|
|
|
result::ok(p) { [p] }
|
|
|
|
result::err(p) { [] }
|
|
|
|
}
|
2011-10-03 14:46:22 -05:00
|
|
|
}
|
|
|
|
fn get_target_lib_path() -> fs::path {
|
2012-01-13 02:32:05 -06:00
|
|
|
make_target_lib_path(self.sysroot, self.target_triple)
|
2011-10-03 14:46:22 -05:00
|
|
|
}
|
|
|
|
fn get_target_lib_file_path(file: fs::path) -> fs::path {
|
|
|
|
fs::connect(self.get_target_lib_path(), file)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-04 16:14:36 -05:00
|
|
|
let sysroot = get_sysroot(maybe_sysroot);
|
2011-12-22 16:42:52 -06:00
|
|
|
#debug("using sysroot = %s", sysroot);
|
2012-01-13 02:32:05 -06:00
|
|
|
{sysroot: sysroot,
|
|
|
|
addl_lib_search_paths: addl_lib_search_paths,
|
|
|
|
target_triple: target_triple} as filesearch
|
2011-10-03 14:46:22 -05:00
|
|
|
}
|
|
|
|
|
2011-10-03 15:54:13 -05:00
|
|
|
// FIXME #1001: This can't be an obj method
|
2012-01-31 19:05:20 -06:00
|
|
|
fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> {
|
2011-10-03 15:54:13 -05:00
|
|
|
for lib_search_path in filesearch.lib_search_paths() {
|
2011-12-22 16:42:52 -06:00
|
|
|
#debug("searching %s", lib_search_path);
|
2011-10-03 15:54:13 -05:00
|
|
|
for path in fs::list_dir(lib_search_path) {
|
2011-12-22 16:42:52 -06:00
|
|
|
#debug("testing %s", path);
|
2011-10-03 15:54:13 -05:00
|
|
|
let maybe_picked = pick(path);
|
|
|
|
if option::is_some(maybe_picked) {
|
2011-12-22 16:42:52 -06:00
|
|
|
#debug("picked %s", path);
|
2011-10-03 15:54:13 -05:00
|
|
|
ret maybe_picked;
|
|
|
|
} else {
|
2011-12-22 16:42:52 -06:00
|
|
|
#debug("rejected %s", path);
|
2011-10-03 15:54:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret option::none;
|
|
|
|
}
|
|
|
|
|
2011-10-04 17:23:32 -05:00
|
|
|
fn relative_target_lib_path(target_triple: str) -> [fs::path] {
|
2012-01-10 19:45:03 -06:00
|
|
|
[libdir(), "rustc", target_triple, libdir()]
|
2011-10-04 17:23:32 -05:00
|
|
|
}
|
|
|
|
|
2011-10-03 14:46:22 -05:00
|
|
|
fn make_target_lib_path(sysroot: fs::path,
|
|
|
|
target_triple: str) -> fs::path {
|
2011-10-04 17:23:32 -05:00
|
|
|
let path = [sysroot] + relative_target_lib_path(target_triple);
|
2011-10-03 14:46:22 -05:00
|
|
|
check vec::is_not_empty(path);
|
|
|
|
let path = fs::connect_many(path);
|
|
|
|
ret path;
|
|
|
|
}
|
|
|
|
|
2011-10-04 16:14:36 -05:00
|
|
|
fn get_default_sysroot() -> fs::path {
|
|
|
|
alt os::get_exe_path() {
|
2011-10-05 00:40:38 -05:00
|
|
|
option::some(p) { fs::normalize(fs::connect(p, "..")) }
|
2012-01-19 00:37:22 -06:00
|
|
|
option::none {
|
2011-10-04 16:14:36 -05:00
|
|
|
fail "can't determine value for sysroot";
|
|
|
|
}
|
|
|
|
}
|
2011-10-03 14:46:22 -05:00
|
|
|
}
|
|
|
|
|
2012-01-31 19:05:20 -06:00
|
|
|
fn get_sysroot(maybe_sysroot: option<fs::path>) -> fs::path {
|
2011-10-03 14:46:22 -05:00
|
|
|
alt maybe_sysroot {
|
|
|
|
option::some(sr) { sr }
|
2012-01-19 00:37:22 -06:00
|
|
|
option::none { get_default_sysroot() }
|
2011-10-03 14:46:22 -05:00
|
|
|
}
|
2011-11-10 10:41:42 -06:00
|
|
|
}
|
2012-01-05 18:03:28 -06:00
|
|
|
|
|
|
|
fn get_cargo_root() -> result::t<fs::path, str> {
|
|
|
|
alt generic_os::getenv("CARGO_ROOT") {
|
|
|
|
some(_p) { result::ok(_p) }
|
2012-01-19 00:37:22 -06:00
|
|
|
none {
|
2012-01-06 18:38:08 -06:00
|
|
|
alt fs::homedir() {
|
|
|
|
some(_q) { result::ok(fs::connect(_q, ".cargo")) }
|
2012-01-19 00:37:22 -06:00
|
|
|
none { result::err("no CARGO_ROOT or home directory") }
|
2012-01-06 18:38:08 -06:00
|
|
|
}
|
2012-01-05 18:03:28 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-05 03:30:03 -06:00
|
|
|
fn get_cargo_root_nearest() -> result::t<fs::path, str> {
|
|
|
|
result::chain(get_cargo_root()) { |p|
|
|
|
|
let cwd = os::getcwd();
|
|
|
|
let dirname = fs::dirname(cwd);
|
|
|
|
let dirpath = fs::split(dirname);
|
|
|
|
let cwd_cargo = fs::connect(cwd, ".cargo");
|
|
|
|
let par_cargo = fs::connect(dirname, ".cargo");
|
|
|
|
|
|
|
|
// FIXME: this duplicates lib path
|
|
|
|
if cwd_cargo == p {
|
|
|
|
ret result::ok(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
while vec::is_not_empty(dirpath) && par_cargo != p {
|
|
|
|
if fs::path_is_dir(par_cargo) {
|
|
|
|
ret result::ok(par_cargo);
|
|
|
|
}
|
|
|
|
vec::pop(dirpath);
|
|
|
|
dirname = fs::dirname(dirname);
|
|
|
|
par_cargo = fs::connect(dirname, ".cargo");
|
|
|
|
}
|
|
|
|
|
|
|
|
result::ok(cwd_cargo)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-05 18:03:28 -06:00
|
|
|
fn get_cargo_lib_path() -> result::t<fs::path, str> {
|
|
|
|
result::chain(get_cargo_root()) { |p|
|
2012-01-10 19:45:03 -06:00
|
|
|
result::ok(fs::connect(p, libdir()))
|
2012-01-05 18:03:28 -06:00
|
|
|
}
|
2012-01-10 19:45:03 -06:00
|
|
|
}
|
|
|
|
|
2012-02-05 03:30:03 -06:00
|
|
|
fn get_cargo_lib_path_nearest() -> result::t<fs::path, str> {
|
|
|
|
result::chain(get_cargo_root_nearest()) { |p|
|
|
|
|
result::ok(fs::connect(p, libdir()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-10 19:45:03 -06:00
|
|
|
// The name of the directory rustc expects libraries to be located.
|
|
|
|
// On Unix should be "lib", on windows "bin"
|
|
|
|
fn libdir() -> str {
|
|
|
|
let libdir = #env("CFG_LIBDIR");
|
|
|
|
if str::is_empty(libdir) {
|
|
|
|
fail "rustc compiled without CFG_LIBDIR environment variable";
|
|
|
|
}
|
|
|
|
libdir
|
|
|
|
}
|