From c42f1218a0a7b3a5c84502f9cb4b123d65148f4c Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Fri, 3 May 2013 16:47:53 -0700 Subject: [PATCH] rustpkg: Handle sysroot more correctly In rustpkg, pass around sysroot; in rustpkg tests, set the sysroot manually so that tests can find libcore and such. With bonus metadata::filesearch refactoring to avoid copies. --- src/librustc/back/rpath.rs | 2 +- src/librustc/driver/driver.rs | 2 +- src/librustc/driver/session.rs | 2 +- src/librustc/metadata/filesearch.rs | 54 ++++++++++++++++------------ src/librustpkg/context.rs | 3 ++ src/librustpkg/path_util.rs | 6 +--- src/librustpkg/rustpkg.rc | 29 ++++++++------- src/librustpkg/tests.rs | 55 +++++++++++++++++++++++++---- src/librustpkg/util.rs | 5 +-- 9 files changed, 106 insertions(+), 52 deletions(-) diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index fab19b68174..fceff55abf8 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -40,7 +40,7 @@ pub fn get_rpath_flags(sess: session::Session, out_filename: &Path) // where rustrt is and we know every rust program needs it let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess)); - let rpaths = get_rpaths(os, &sysroot, output, libs, + let rpaths = get_rpaths(os, sysroot, output, libs, sess.opts.target_triple); rpaths_to_flags(rpaths) } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 5e5d0640d80..d968cf708d9 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -603,7 +603,7 @@ pub fn build_session_options(binary: @~str, link::output_type_bitcode } else { link::output_type_exe }; let sysroot_opt = getopts::opt_maybe_str(matches, ~"sysroot"); - let sysroot_opt = sysroot_opt.map(|m| Path(*m)); + let sysroot_opt = sysroot_opt.map(|m| @Path(*m)); let target_opt = getopts::opt_maybe_str(matches, ~"target"); let target_feature_opt = getopts::opt_maybe_str(matches, ~"target-feature"); let save_temps = getopts::opt_present(matches, ~"save-temps"); diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 237b03bc20f..04cf3ca64f9 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -125,7 +125,7 @@ pub struct options { output_type: back::link::output_type, addl_lib_search_paths: ~[Path], linker_args: ~[~str], - maybe_sysroot: Option, + maybe_sysroot: Option<@Path>, target_triple: ~str, target_feature: ~str, // User-specified cfg meta items. The compiler itself will add additional diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index c88d5437c84..ded0b314d44 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -20,41 +20,49 @@ pub fn pick_file(file: Path, path: &Path) -> Option { } pub trait FileSearch { - fn sysroot(&self) -> Path; - fn lib_search_paths(&self) -> ~[Path]; + fn sysroot(&self) -> @Path; + fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool); fn get_target_lib_path(&self) -> Path; fn get_target_lib_file_path(&self, file: &Path) -> Path; } -pub fn mk_filesearch(maybe_sysroot: &Option, +pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, target_triple: &str, addl_lib_search_paths: ~[Path]) -> @FileSearch { struct FileSearchImpl { - sysroot: Path, + sysroot: @Path, addl_lib_search_paths: ~[Path], target_triple: ~str } impl FileSearch for FileSearchImpl { - fn sysroot(&self) -> Path { /*bad*/copy self.sysroot } - fn lib_search_paths(&self) -> ~[Path] { - let mut paths = /*bad*/copy self.addl_lib_search_paths; + fn sysroot(&self) -> @Path { self.sysroot } + fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) { + debug!("filesearch: searching additional lib search paths"); + if !self.addl_lib_search_paths.each(f) { + return; + } - paths.push( - make_target_lib_path(&self.sysroot, - self.target_triple)); - match get_rustpkg_lib_path_nearest() { - result::Ok(ref p) => paths.push((/*bad*/copy *p)), - result::Err(_) => () + debug!("filesearch: searching target lib path"); + if !f(&make_target_lib_path(self.sysroot, + self.target_triple)) { + return; } - match get_rustpkg_lib_path() { - result::Ok(ref p) => paths.push((/*bad*/copy *p)), - result::Err(_) => () - } - paths + debug!("filesearch: searching rustpkg lib path nearest"); + if match get_rustpkg_lib_path_nearest() { + result::Ok(ref p) => f(p), + result::Err(_) => true + } { + return; + } + debug!("filesearch: searching rustpkg lib path"); + match get_rustpkg_lib_path() { + result::Ok(ref p) => f(p), + result::Err(_) => true + } } fn get_target_lib_path(&self) -> Path { - make_target_lib_path(&self.sysroot, self.target_triple) + make_target_lib_path(self.sysroot, self.target_triple) } fn get_target_lib_file_path(&self, file: &Path) -> Path { self.get_target_lib_path().push_rel(file) @@ -72,7 +80,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option, pub fn search(filesearch: @FileSearch, pick: pick) -> Option { let mut rslt = None; - for filesearch.lib_search_paths().each |lib_search_path| { + for filesearch.for_each_lib_search_path() |lib_search_path| { debug!("searching %s", lib_search_path.to_str()); for os::list_dir_path(lib_search_path).each |path| { debug!("testing %s", path.to_str()); @@ -108,10 +116,10 @@ fn get_or_default_sysroot() -> Path { } } -fn get_sysroot(maybe_sysroot: &Option) -> Path { +fn get_sysroot(maybe_sysroot: &Option<@Path>) -> @Path { match *maybe_sysroot { - option::Some(ref sr) => (/*bad*/copy *sr), - option::None => get_or_default_sysroot() + option::Some(sr) => sr, + option::None => @get_or_default_sysroot() } } diff --git a/src/librustpkg/context.rs b/src/librustpkg/context.rs index db036f44a18..348d828bded 100644 --- a/src/librustpkg/context.rs +++ b/src/librustpkg/context.rs @@ -13,6 +13,9 @@ use core::hashmap::HashMap; pub struct Ctx { + // Sysroot -- if this is None, uses rustc filesearch's + // idea of the default + sysroot_opt: Option<@Path>, // I'm not sure what this is for json: bool, // Cache of hashes of things already installed diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index 161cb75e9e5..d21fdcda7f7 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -29,11 +29,7 @@ pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; /// Creates a directory that is readable, writeable, /// and executable by the user. Returns true iff creation /// succeeded. -pub fn make_dir_rwx(p: &Path) -> bool { - use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; - - os::make_dir(p, u_rwx) -} +pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, u_rwx) } /// Replace all occurrences of '-' in the stem part of path with '_' /// This is because we treat rust-foo-bar-quux and rust_foo_bar_quux diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index cc74f464e0e..dd5806ba015 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -306,7 +306,7 @@ impl Ctx { // Find crates inside the workspace src.find_crates(); // Build it! - src.build(&build_dir, cfgs); + src.build(&build_dir, cfgs, self.sysroot_opt); } } @@ -506,6 +506,7 @@ pub fn main() { } Ctx { + sysroot_opt: None, // Currently, only tests override this json: json, dep_cache: @mut HashMap::new() }.run(cmd, args); @@ -648,6 +649,8 @@ impl PkgSrc { debug!("Checking dir: %s", dir.to_str()); + // tjc: Rather than erroring out, need to try downloading the + // contents of the path to a local directory (#5679) if !os::path_exists(&dir) { cond.raise((self.id, ~"missing package dir")); } @@ -744,18 +747,20 @@ impl PkgSrc { self.benchs.len()) } - fn build_crates(&self, dst_dir: &Path, - src_dir: &Path, - crates: &[Crate], - cfgs: ~[~str], - test: bool, crate_type: crate_type) { + fn build_crates(&self, + maybe_sysroot: Option<@Path>, + dst_dir: &Path, + src_dir: &Path, + crates: &[Crate], + cfgs: ~[~str], + test: bool, crate_type: crate_type) { for crates.each |&crate| { let path = &src_dir.push_rel(&crate.file).normalize(); util::note(fmt!("build_crates: compiling %s", path.to_str())); util::note(fmt!("build_crates: destination dir is %s", dst_dir.to_str())); - let result = util::compile_crate(None, self.id, path, + let result = util::compile_crate(maybe_sysroot, self.id, path, dst_dir, crate.flags, crate.cfgs + cfgs, @@ -769,15 +774,15 @@ impl PkgSrc { } } - fn build(&self, dst_dir: &Path, cfgs: ~[~str]) { + fn build(&self, dst_dir: &Path, cfgs: ~[~str], maybe_sysroot: Option<@Path>) { let dir = self.check_dir(); debug!("Building libs"); - self.build_crates(dst_dir, &dir, self.libs, cfgs, false, lib_crate); + self.build_crates(maybe_sysroot, dst_dir, &dir, self.libs, cfgs, false, lib_crate); debug!("Building mains"); - self.build_crates(dst_dir, &dir, self.mains, cfgs, false, bin_crate); + self.build_crates(maybe_sysroot, dst_dir, &dir, self.mains, cfgs, false, bin_crate); debug!("Building tests"); - self.build_crates(dst_dir, &dir, self.tests, cfgs, true, bin_crate); + self.build_crates(maybe_sysroot, dst_dir, &dir, self.tests, cfgs, true, bin_crate); debug!("Building benches"); - self.build_crates(dst_dir, &dir, self.benchs, cfgs, true, bin_crate); + self.build_crates(maybe_sysroot, dst_dir, &dir, self.benchs, cfgs, true, bin_crate); } } diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index f38fc88f727..486e2959e9e 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -20,8 +20,9 @@ use path_util::{target_executable_in_workspace, target_library_in_workspace, make_dir_rwx, u_rwx}; use core::os::mkdir_recursive; -fn fake_ctxt() -> Ctx { +fn fake_ctxt(sysroot_opt: Option<@Path>) -> Ctx { Ctx { + sysroot_opt: sysroot_opt, json: false, dep_cache: @mut HashMap::new() } @@ -34,6 +35,13 @@ fn fake_pkg() -> PkgId { } } +fn remote_pkg() -> PkgId { + PkgId { + path: Path(~"github.com/catamorphism/test-pkg"), + version: default_version() + } +} + fn writeFile(file_path: &Path, contents: ~str) { let out: @io::Writer = result::get(&io::file_writer(file_path, @@ -69,6 +77,15 @@ fn is_rwx(p: &Path) -> bool { } } +#[cfg(test)] +fn test_sysroot() -> Path { + // Totally gross hack but it's just for test cases. + // Infer the sysroot from the exe name and tack "stage2" + // onto it. (Did I mention it was a gross hack?) + let self_path = os::self_exe_path().expect("Couldn't get self_exe path"); + self_path.pop().push("stage2") +} + #[test] fn test_make_dir_rwx() { let temp = &os::tmpdir(); @@ -84,11 +101,9 @@ fn test_make_dir_rwx() { #[test] fn test_install_valid() { - use rustc::metadata::filesearch; - - let sysroot = filesearch::get_rustpkg_sysroot(); - debug!("sysroot = %s", sysroot.get().to_str()); - let ctxt = fake_ctxt(); + let sysroot = test_sysroot(); + debug!("sysroot = %s", sysroot.to_str()); + let ctxt = fake_ctxt(Some(@sysroot)); let temp_pkg_id = fake_pkg(); let temp_workspace = mk_temp_workspace(&temp_pkg_id.path); // should have test, bench, lib, and main @@ -114,7 +129,7 @@ fn test_install_invalid() { use conditions::nonexistent_package::cond; use cond1 = conditions::missing_pkg_files::cond; - let ctxt = fake_ctxt(); + let ctxt = fake_ctxt(None); let pkgid = fake_pkg(); let temp_workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir"); let mut error_occurred = false; @@ -130,3 +145,29 @@ fn test_install_invalid() { } assert!(error_occurred && error1_occurred); } + +#[test] +#[ignore(reason = "install from URL-fragment not yet implemented")] +fn test_install_url() { + let sysroot = test_sysroot(); + debug!("sysroot = %s", sysroot.to_str()); + let ctxt = fake_ctxt(Some(@sysroot)); + let temp_pkg_id = remote_pkg(); + let temp_workspace = mk_temp_workspace(&temp_pkg_id.path); + // should have test, bench, lib, and main + ctxt.install(&temp_workspace, temp_pkg_id); + // Check that all files exist + let exec = target_executable_in_workspace(temp_pkg_id, &temp_workspace); + debug!("exec = %s", exec.to_str()); + assert!(os::path_exists(&exec)); + assert!(is_rwx(&exec)); + let lib = target_library_in_workspace(temp_pkg_id, &temp_workspace); + debug!("lib = %s", lib.to_str()); + assert!(os::path_exists(&lib)); + assert!(is_rwx(&lib)); + // And that the test and bench executables aren't installed + assert!(!os::path_exists(&target_test_in_workspace(temp_pkg_id, &temp_workspace))); + let bench = target_bench_in_workspace(temp_pkg_id, &temp_workspace); + debug!("bench = %s", bench.to_str()); + assert!(!os::path_exists(&bench)); +} \ No newline at end of file diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 1b3d72bf6aa..0762fa4ad7f 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -435,7 +435,7 @@ pub fn add_pkg(pkg: &Pkg) -> bool { } // FIXME (#4432): Use workcache to only compile when needed -pub fn compile_input(sysroot: Option, +pub fn compile_input(sysroot: Option<@Path>, pkg_id: PkgId, in_file: &Path, out_dir: &Path, @@ -474,6 +474,7 @@ pub fn compile_input(sysroot: Option, out_file.to_str()); debug!("flags: %s", str::connect(flags, ~" ")); debug!("cfgs: %s", str::connect(cfgs, ~" ")); + debug!("compile_input's sysroot = %?", sysroot); let matches = getopts(~[~"-Z", ~"time-passes"] + if building_library { ~[~"--lib"] } @@ -587,7 +588,7 @@ fn add_attrs(c: ast::crate, new_attrs: ~[attribute]) -> @ast::crate { // Called by build_crates // FIXME (#4432): Use workcache to only compile when needed -pub fn compile_crate(sysroot: Option, pkg_id: PkgId, +pub fn compile_crate(sysroot: Option<@Path>, pkg_id: PkgId, crate: &Path, dir: &Path, flags: ~[~str], cfgs: ~[~str], opt: bool, test: bool, crate_type: crate_type) -> bool {