about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-12 17:45:45 -0700
committerbors <bors@rust-lang.org>2013-09-12 17:45:45 -0700
commit19c07352319e1953bdff52618a540dd915a0abbd (patch)
tree6d8d70a2d6ca411843add72b11040fe0e83f88b6
parent761ae0035731ebc5c9e42b331fa86fb0385ad9f1 (diff)
parent91e64d04072110235e504e6151ddf861214b1f14 (diff)
downloadrust-19c07352319e1953bdff52618a540dd915a0abbd.tar.gz
rust-19c07352319e1953bdff52618a540dd915a0abbd.zip
auto merge of #9132 : catamorphism/rust/rustpkg-recursive-deps, r=catamorphism,metajack
r? @metajack ...recursive dependencies

Closes #8524
-rw-r--r--src/librustpkg/path_util.rs4
-rw-r--r--src/librustpkg/rustpkg.rs2
-rw-r--r--src/librustpkg/tests.rs22
-rw-r--r--src/librustpkg/util.rs30
4 files changed, 48 insertions, 10 deletions
diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs
index d3789ec5adf..7155233cd37 100644
--- a/src/librustpkg/path_util.rs
+++ b/src/librustpkg/path_util.rs
@@ -55,6 +55,10 @@ pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
 pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path,
 // Returns the directory it was actually found in
              workspace_to_src_dir: &fn(&Path) -> Path) -> Option<Path> {
+    if !os::path_is_dir(workspace) {
+        return None;
+    }
+
     let src_dir = workspace_to_src_dir(workspace);
 
     let mut found = None;
diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs
index 03eb4e93842..8212e3e2799 100644
--- a/src/librustpkg/rustpkg.rs
+++ b/src/librustpkg/rustpkg.rs
@@ -33,7 +33,7 @@ use rustc::metadata::filesearch::rust_path;
 use extra::{getopts};
 use syntax::{ast, diagnostic};
 use util::*;
-use messages::*;
+use messages::{error, warn, note};
 use path_util::build_pkg_id_in_workspace;
 use path_util::{U_RWX, in_rust_path};
 use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace};
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index cef422be77a..bf80dc14166 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -1581,6 +1581,28 @@ fn pkgid_pointing_to_subdir() {
     assert_executable_exists(&workspace, "testpkg");
 }
 
+fn test_recursive_deps() {
+    let a_id = PkgId::new("a");
+    let b_id = PkgId::new("b");
+    let c_id = PkgId::new("c");
+    let b_workspace = create_local_package_with_dep(&b_id, &c_id);
+    writeFile(&b_workspace.push("src").push("c-0.1").push("lib.rs"),
+               "pub fn g() {}");
+    let a_workspace = create_local_package(&a_id);
+    writeFile(&a_workspace.push("src").push("a-0.1").push("main.rs"),
+               "extern mod b; use b::f; fn main() { f(); }");
+    writeFile(&b_workspace.push("src").push("b-0.1").push("lib.rs"),
+               "extern mod c; use c::g; pub fn f() { g(); }");
+    let environment = Some(~[(~"RUST_PATH", b_workspace.to_str())]);
+    debug!("RUST_PATH=%s", b_workspace.to_str());
+    command_line_test_with_env([~"install", ~"a"],
+                               &a_workspace,
+                               environment);
+    assert_lib_exists(&a_workspace, &Path("a"), NoVersion);
+    assert_lib_exists(&b_workspace, &Path("b"), NoVersion);
+    assert_lib_exists(&b_workspace, &Path("c"), NoVersion);
+}
+
 /// Returns true if p exists and is executable
 fn is_executable(p: &Path) -> bool {
     use std::libc::consts::os::posix88::{S_IXUSR};
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 15fc7d37621..708d50bb537 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -22,7 +22,9 @@ use rustc::driver::session::{lib_crate, bin_crate};
 use context::{in_target, StopBefore, Link, Assemble, BuildContext};
 use package_id::PkgId;
 use package_source::PkgSrc;
-use path_util::{installed_library_in_workspace, U_RWX};
+use workspace::pkg_parent_workspaces;
+use path_util::{installed_library_in_workspace, U_RWX, rust_path};
+use messages::error;
 
 pub use target::{OutputType, Main, Lib, Bench, Test};
 use workcache_support::{digest_file_with_date, digest_only_date};
@@ -243,9 +245,7 @@ pub fn compile_input(context: &BuildContext,
     let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
     crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
 
-    // Not really right. Should search other workspaces too, and the installed
-    // database (which doesn't exist yet)
-    find_and_install_dependencies(context, sess, exec, workspace, crate,
+    find_and_install_dependencies(context, pkg_id, sess, exec, crate,
                                   |p| {
                                       debug!("a dependency: %s", p.to_str());
                                       // Pass the directory containing a dependency
@@ -362,13 +362,15 @@ pub fn compile_crate(ctxt: &BuildContext,
 /// Collect all `extern mod` directives in `c`, then
 /// try to install their targets, failing if any target
 /// can't be found.
-pub fn find_and_install_dependencies(ctxt: &BuildContext,
+pub fn find_and_install_dependencies(context: &BuildContext,
+                                     parent: &PkgId,
                                      sess: session::Session,
                                      exec: &mut workcache::Exec,
-                                     workspace: &Path,
                                      c: &ast::Crate,
                                      save: @fn(Path)
                                      ) {
+    use conditions::nonexistent_package::cond;
+
     do c.each_view_item() |vi: &ast::view_item| {
         debug!("A view item!");
         match vi.node {
@@ -379,7 +381,7 @@ pub fn find_and_install_dependencies(ctxt: &BuildContext,
                     None => sess.str_of(lib_ident)
                 };
                 debug!("Finding and installing... %s", lib_name);
-                match installed_library_in_workspace(&Path(lib_name), &ctxt.sysroot()) {
+                match installed_library_in_workspace(&Path(lib_name), &context.sysroot()) {
                     Some(ref installed_path) => {
                         debug!("It exists: %s", installed_path.to_str());
                         // Say that [path for c] has a discovered dependency on
@@ -397,8 +399,18 @@ pub fn find_and_install_dependencies(ctxt: &BuildContext,
                                lib_name.to_str());
                         // Try to install it
                         let pkg_id = PkgId::new(lib_name);
+                        let workspaces = pkg_parent_workspaces(&context.context, &pkg_id);
+                        let dep_workspace = if workspaces.is_empty() {
+                            error(fmt!("Couldn't find package %s, which is needed by %s, \
+                                            in any of the workspaces in the RUST_PATH (%?)",
+                                            lib_name, parent.to_str(), rust_path()));
+                            cond.raise((pkg_id.clone(), ~"Dependency not found"))
+                        }
+                        else {
+                            workspaces[0]
+                        };
                         let (outputs_disc, inputs_disc) =
-                            ctxt.install(PkgSrc::new(workspace.clone(), false, pkg_id));
+                            context.install(PkgSrc::new(dep_workspace.clone(), false, pkg_id));
                         debug!("Installed %s, returned %? dependencies and \
                                %? transitive dependencies",
                                lib_name, outputs_disc.len(), inputs_disc.len());
@@ -423,7 +435,7 @@ pub fn find_and_install_dependencies(ctxt: &BuildContext,
                         // Also, add an additional search path
                         debug!("Adding additional search path: %s", lib_name);
                         let installed_library =
-                            installed_library_in_workspace(&Path(lib_name), workspace)
+                            installed_library_in_workspace(&Path(lib_name), &dep_workspace)
                                 .expect( fmt!("rustpkg failed to install dependency %s",
                                               lib_name));
                         let install_dir = installed_library.pop();