]> git.lizzy.rs Git - rust.git/commitdiff
rustpkg: Support arbitrary dependencies in the install API
authorTim Chevalier <chevalier@alum.wellesley.edu>
Tue, 1 Oct 2013 05:39:50 +0000 (22:39 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Wed, 23 Oct 2013 03:41:29 +0000 (20:41 -0700)
api::install_pkg now accepts an argument that's a list of
(kind, path) dependency pairs. This allows custom package scripts to
declare C dependencies, as is demonstrated in
rustpkg::tests::test_c_dependency_ok.

Closes #6403

16 files changed:
mk/tests.mk
src/librustpkg/api.rs
src/librustpkg/conditions.rs
src/librustpkg/context.rs
src/librustpkg/package_source.rs
src/librustpkg/path_util.rs
src/librustpkg/rustpkg.rs
src/librustpkg/target.rs
src/librustpkg/tests.rs
src/librustpkg/testsuite/pass/src/c-dependencies/bar.rs [new file with mode: 0644]
src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs [new file with mode: 0644]
src/librustpkg/testsuite/pass/src/c-dependencies/lib.rs [new file with mode: 0644]
src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs [new file with mode: 0644]
src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs
src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs
src/librustpkg/util.rs

index c06c234e951d023780ec416e50563cb599ef8284..d6fc5ecb8e5af118f5f23269823aff546ed1a7b3 100644 (file)
@@ -370,6 +370,7 @@ $(3)/stage$(1)/test/rustpkgtest-$(2)$$(X_$(2)):                                     \
                $$(SREQ$(1)_T_$(2)_H_$(3)) \
                $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \
                $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2)) \
+               $$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(2)) \
                $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$$(X_$(2)) \
                $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(2))
        @$$(call E, compile_and_link: $$@)
index 1f5802927a641d1f96c23f46a5cc86b3c397c9e1..c67b6f52c7e399cff7bed8dd1fa44f91dfbf408c 100644 (file)
 use crate::*;
 use package_id::*;
 use package_source::*;
+use path_util::{platform_library_name, target_build_dir};
 use target::*;
 use version::Version;
+use workspace::pkg_parent_workspaces;
 use workcache_support::*;
+pub use path_util::default_workspace;
 
 pub use source_control::{safe_git_clone, git_clone_url};
 
-use std::os;
+use std::{os, run};
 use extra::arc::{Arc,RWArc};
 use extra::workcache;
 use extra::workcache::{Database, Logger, FreshnessMap};
 use extra::treemap::TreeMap;
 
+// A little sad -- duplicated from rustc::back::*
+#[cfg(target_arch = "arm")]
+fn cc_args() -> ~[~str] { ~[~"-marm"] }
+#[cfg(target_arch = "mips")]
+fn cc_args() -> ~[~str] { ~[] }
+#[cfg(target_arch = "x86")]
+fn cc_args() -> ~[~str] { ~[~"-m32"] }
+#[cfg(target_arch = "x86_64")]
+fn cc_args() -> ~[~str] { ~[~"-m64"] }
+
 /// Convenience functions intended for calling from pkg.rs
 /// p is where to put the cache file for dependencies
-pub fn default_context(p: Path) -> BuildContext {
-    new_default_context(new_workcache_context(&p), p)
+pub fn default_context(sysroot: Path, p: Path) -> BuildContext {
+    new_default_context(new_workcache_context(&p), sysroot)
 }
 
 pub fn new_default_context(c: workcache::Context, p: Path) -> BuildContext {
@@ -68,7 +81,7 @@ pub fn new_workcache_context(p: &Path) -> workcache::Context {
 
 pub fn build_lib(sysroot: Path, root: Path, name: ~str, version: Version,
                  lib: Path) {
-    let cx = default_context(sysroot);
+    let cx = default_context(sysroot, root.clone());
     let pkg_src = PkgSrc {
         source_workspace: root.clone(),
         build_in_destination: false,
@@ -81,12 +94,12 @@ pub fn build_lib(sysroot: Path, root: Path, name: ~str, version: Version,
         tests: ~[],
         benchs: ~[]
     };
-    pkg_src.build(&cx, ~[]);
+    pkg_src.build(&cx, ~[], []);
 }
 
 pub fn build_exe(sysroot: Path, root: Path, name: ~str, version: Version,
                  main: Path) {
-    let cx = default_context(sysroot);
+    let cx = default_context(sysroot, root.clone());
     let pkg_src = PkgSrc {
         source_workspace: root.clone(),
         build_in_destination: false,
@@ -100,13 +113,76 @@ pub fn build_exe(sysroot: Path, root: Path, name: ~str, version: Version,
         benchs: ~[]
     };
 
-    pkg_src.build(&cx, ~[]);
+    pkg_src.build(&cx, ~[], []);
 }
 
-pub fn install_pkg(sysroot: Path, workspace: Path, name: ~str, version: Version) {
-    let cx = default_context(sysroot);
+pub fn install_pkg(cx: &BuildContext,
+                   workspace: Path,
+                   name: ~str,
+                   version: Version,
+                   // For now, these inputs are assumed to be inputs to each of the crates
+                   more_inputs: ~[(~str, Path)]) { // pairs of Kind and Path
     let pkgid = PkgId{ version: version, ..PkgId::new(name)};
-    cx.install(PkgSrc::new(workspace.clone(), workspace, false, pkgid), &Everything);
+    cx.install(PkgSrc::new(workspace.clone(), workspace, false, pkgid),
+               &WhatToBuild{ build_type: Inferred,
+                             inputs_to_discover: more_inputs,
+                             sources: Everything });
+}
+
+/// Builds an arbitrary library whose short name is `output`,
+/// by invoking `tool` with arguments `args` plus "-o %s", where %s
+/// is the platform-specific library name for `output`.
+/// Returns that platform-specific name.
+pub fn build_library_in_workspace(exec: &mut workcache::Exec,
+                                  context: &mut Context,
+                                  package_name: &str,
+                                  tool: &str,
+                                  flags: &[~str],
+                                  paths: &[~str],
+                                  output: &str) -> ~str {
+    use command_failed = conditions::command_failed::cond;
+
+    let workspace = my_workspace(context, package_name);
+    let workspace_build_dir = target_build_dir(&workspace);
+    let out_name = workspace_build_dir.join_many([package_name.to_str(),
+                                                  platform_library_name(output)]);
+    // make paths absolute
+    let pkgid = PkgId::new(package_name);
+    let absolute_paths = paths.map(|s| {
+            let whatever = workspace.join_many([~"src",
+                                pkgid.to_str(),
+                                s.to_owned()]);
+            whatever.as_str().unwrap().to_owned()
+        });
+
+    let cc_args = cc_args();
+
+    let all_args = flags + absolute_paths + cc_args +
+         ~[~"-o", out_name.as_str().unwrap().to_owned()];
+    let exit_code = run::process_status(tool, all_args);
+    if exit_code != 0 {
+        command_failed.raise((tool.to_owned(), all_args, exit_code))
+    }
+    else {
+        let out_name_str = out_name.as_str().unwrap().to_owned();
+        exec.discover_output("binary",
+                             out_name_str,
+                             digest_only_date(&out_name));
+        context.add_library_path(out_name.dir_path());
+        out_name_str
+    }
+}
+
+pub fn my_workspace(context: &Context, package_name: &str) -> Path {
+    use bad_pkg_id     = conditions::bad_pkg_id::cond;
+
+    // (this assumes no particular version is requested)
+    let pkgid = PkgId::new(package_name);
+    let workspaces = pkg_parent_workspaces(context, &pkgid);
+    if workspaces.is_empty() {
+        bad_pkg_id.raise((Path::new(package_name), package_name.to_owned()));
+    }
+    workspaces[0]
 }
 
 fn mk_crate(p: Path) -> Crate {
index 19b310b45061777a839c978b73c7b98e4fa3eee4..046ba405dbb842c655e55501b573df6f4b6080e9 100644 (file)
@@ -54,3 +54,9 @@
 condition! {
     pub git_checkout_failed: (~str, Path) -> ();
 }
+
+condition! {
+    // str is output of applying the command (first component)
+    // to the args (second component)
+    pub command_failed: (~str, ~[~str], int) -> ~str;
+}
index 3f1f2a1f59d5210b6734dc193b5fc97c0bb514bb..72197219fc5aecd477c1e20c249f7cc44dad8866 100644 (file)
@@ -54,6 +54,15 @@ pub fn flag_strs(&self) -> ~[~str] {
     pub fn compile_upto(&self) -> StopBefore {
         self.context.compile_upto()
     }
+
+    pub fn add_library_path(&mut self, p: Path) {
+        debug!("Adding library path: {}", p.display());
+        self.context.add_library_path(p);
+    }
+
+    pub fn additional_library_paths(&self) -> ~[Path] {
+        self.context.rustc_flags.additional_library_paths.clone()
+    }
 }
 
 /*
@@ -85,6 +94,9 @@ pub struct RustcFlags {
     target: Option<~str>,
     // Target CPU (defaults to rustc's default target CPU)
     target_cpu: Option<~str>,
+    // Additional library directories, which get passed with the -L flag
+    // This can't be set with a rustpkg flag, only from package scripts
+    additional_library_paths: ~[Path],
     // Any -Z features
     experimental_features: Option<~[~str]>
 }
@@ -99,6 +111,7 @@ fn clone(&self) -> RustcFlags {
             save_temps: self.save_temps,
             target: self.target.clone(),
             target_cpu: self.target_cpu.clone(),
+            additional_library_paths: self.additional_library_paths.clone(),
             experimental_features: self.experimental_features.clone()
         }
     }
@@ -148,6 +161,10 @@ pub fn flag_strs(&self) -> ~[~str] {
     pub fn compile_upto(&self) -> StopBefore {
         self.rustc_flags.compile_upto
     }
+
+    pub fn add_library_path(&mut self, p: Path) {
+        self.rustc_flags.additional_library_paths.push(p);
+    }
 }
 
 /// We assume that if ../../rustc exists, then we're running
@@ -210,6 +227,7 @@ pub fn default() -> RustcFlags {
             save_temps: false,
             target: None,
             target_cpu: None,
+            additional_library_paths: ~[],
             experimental_features: None
         }
     }
index 68d2d9662e3458237bc652c9a3016d1378eb18b8..17ba79862e0cab0966fba99bafdc378348ed0f63 100644 (file)
@@ -23,7 +23,7 @@
 use path_util::{target_build_dir, versionize, dir_has_crate_file};
 use util::{compile_crate, DepMap};
 use workcache_support;
-use workcache_support::crate_tag;
+use workcache_support::{digest_only_date, digest_file_with_date, crate_tag};
 use extra::workcache;
 use extra::treemap::TreeMap;
 
@@ -390,7 +390,8 @@ fn build_crates(&self,
                     deps: &mut DepMap,
                     crates: &[Crate],
                     cfgs: &[~str],
-                    what: OutputType) {
+                    what: OutputType,
+                    inputs_to_discover: &[(~str, Path)]) {
         for crate in crates.iter() {
             let path = self.start_dir.join(&crate.file);
             debug!("build_crates: compiling {}", path.display());
@@ -408,7 +409,19 @@ fn build_crates(&self,
                 let sub_dir = self.build_workspace().clone();
                 let sub_flags = crate.flags.clone();
                 let sub_deps = deps.clone();
+                let inputs = inputs_to_discover.map(|&(ref k, ref p)|
+                                                    (k.clone(), p.as_str().unwrap().to_owned()));
                 do prep.exec |exec| {
+                    for &(ref kind, ref p) in inputs.iter() {
+                        let pth = Path::new(p.clone());
+                        exec.discover_input(*kind, *p, if *kind == ~"file" {
+                                digest_file_with_date(&pth)
+                            } else if *kind == ~"binary" {
+                                digest_only_date(&Path::new(p.clone()))
+                            } else {
+                                fail!("Bad kind in build_crates")
+                            });
+                    }
                     let result = compile_crate(&subcx,
                                                exec,
                                                &id,
@@ -452,22 +465,43 @@ pub fn build(&self,
                  build_context: &BuildContext,
                  // DepMap is a map from str (crate name) to (kind, name) --
                  // it tracks discovered dependencies per-crate
-                 cfgs: ~[~str]) -> DepMap {
+                 cfgs: ~[~str],
+                 inputs_to_discover: &[(~str, Path)]) -> DepMap {
         let mut deps = TreeMap::new();
-
         let libs = self.libs.clone();
         let mains = self.mains.clone();
         let tests = self.tests.clone();
         let benchs = self.benchs.clone();
         debug!("Building libs in {}, destination = {}",
-               self.source_workspace.display(), self.build_workspace().display());
-        self.build_crates(build_context, &mut deps, libs, cfgs, Lib);
+               self.destination_workspace.display(),
+               self.destination_workspace.display());
+        self.build_crates(build_context,
+                          &mut deps,
+                          libs,
+                          cfgs,
+                          Lib,
+                          inputs_to_discover);
         debug!("Building mains");
-        self.build_crates(build_context, &mut deps, mains, cfgs, Main);
+        self.build_crates(build_context,
+                          &mut deps,
+                          mains,
+                          cfgs,
+                          Main,
+                          inputs_to_discover);
         debug!("Building tests");
-        self.build_crates(build_context, &mut deps, tests, cfgs, Test);
+        self.build_crates(build_context,
+                          &mut deps,
+                          tests,
+                          cfgs,
+                          Test,
+                          inputs_to_discover);
         debug!("Building benches");
-        self.build_crates(build_context, &mut deps, benchs, cfgs, Bench);
+        self.build_crates(build_context,
+                          &mut deps,
+                          benchs,
+                          cfgs,
+                          Bench,
+                          inputs_to_discover);
         deps
     }
 
index c47c89d777b483080d123d42933c97ba7447daa4..a48ef23115ccf71c3ebe832cc646270cae4e75cf 100644 (file)
@@ -461,7 +461,6 @@ pub fn versionize(p: &Path, v: &Version) -> Path {
     p.with_filename(q)
 }
 
-
 #[cfg(target_os = "win32")]
 pub fn chmod_read_only(p: &Path) -> bool {
     #[fixed_stack_segment];
@@ -483,3 +482,6 @@ pub fn chmod_read_only(p: &Path) -> bool {
     }
 }
 
+pub fn platform_library_name(s: &str) -> ~str {
+    format!("{}{}{}", os::consts::DLL_PREFIX, s, os::consts::DLL_SUFFIX)
+}
index 6c55f7af0c06a2c79d74f59628791f6f5427f745..37a5a2ea711329b9b369a17178dc467b7476fd20 100644 (file)
@@ -33,7 +33,6 @@
 use rustc::metadata::filesearch::rust_path;
 use extra::{getopts};
 use syntax::{ast, diagnostic};
-use util::*;
 use messages::{error, warn, note};
 use path_util::{build_pkg_id_in_workspace, built_test_in_workspace};
 use path_util::{U_RWX, in_rust_path};
                        LLVMAssemble, LLVMCompileBitcode};
 use package_id::PkgId;
 use package_source::PkgSrc;
-use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench, Tests};
+use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench};
+use target::{Tests, MaybeCustom, Inferred, JustOne};
 use workcache_support::digest_only_date;
 use exit_codes::{COPY_FAILED_CODE, BAD_FLAG_CODE};
 
 pub mod api;
 mod conditions;
-mod context;
+pub mod context;
 mod crate;
-mod exit_codes;
+pub mod exit_codes;
 mod installed_packages;
 mod messages;
 mod package_id;
@@ -67,7 +67,7 @@
 #[cfg(test)]
 mod tests;
 mod util;
-mod version;
+pub mod version;
 pub mod workcache_support;
 mod workspace;
 
@@ -96,7 +96,7 @@ impl<'self> PkgScript<'self> {
     /// Given the path name for a package script
     /// and a package ID, parse the package script into
     /// a PkgScript that we can then execute
-    fn parse<'a>(sysroot: @Path,
+    fn parse<'a>(sysroot: Path,
                  script: Path,
                  workspace: &Path,
                  id: &'a PkgId) -> PkgScript<'a> {
@@ -107,7 +107,7 @@ fn parse<'a>(sysroot: @Path,
         debug!("pkgscript parse: {}", sysroot.display());
         let options = @session::options {
             binary: binary,
-            maybe_sysroot: Some(sysroot),
+            maybe_sysroot: Some(@sysroot),
             crate_type: session::bin_crate,
             .. (*session::basic_options()).clone()
         };
@@ -132,12 +132,7 @@ fn parse<'a>(sysroot: @Path,
         }
     }
 
-    /// Run the contents of this package script, where <what>
-    /// is the command to pass to it (e.g., "build", "clean", "install")
-    /// Returns a pair of an exit code and list of configs (obtained by
-    /// calling the package script's configs() function if it exists
-    fn run_custom(&mut self, exec: &mut workcache::Exec,
-                  sysroot: &Path) -> (~[~str], ExitCode) {
+    fn build_custom(&mut self, exec: &mut workcache::Exec) -> ~str {
         let sess = self.sess;
 
         debug!("Working directory = {}", self.build_dir.display());
@@ -152,17 +147,28 @@ fn run_custom(&mut self, exec: &mut workcache::Exec,
                                        &self.build_dir,
                                        sess,
                                        crate);
-        debug!("Running program: {} {} {}", exe.display(),
-               sysroot.display(), "install");
         // Discover the output
         // FIXME (#9639): This needs to handle non-utf8 paths
-        exec.discover_output("binary", exe.as_str().unwrap(), digest_only_date(&exe));
+        // Discover the output
+        exec.discover_output("binary", exe.as_str().unwrap().to_owned(), digest_only_date(&exe));
+        exe.as_str().unwrap().to_owned()
+    }
+
+
+    /// Run the contents of this package script, where <what>
+    /// is the command to pass to it (e.g., "build", "clean", "install")
+    /// Returns a pair of an exit code and list of configs (obtained by
+    /// calling the package script's configs() function if it exists
+    fn run_custom(exe: &Path, sysroot: &Path) -> (~[~str], int) {
+        debug!("Running program: {} {} {}", exe.as_str().unwrap().to_owned(),
+               sysroot.display(), "install");
         // FIXME #7401 should support commands besides `install`
         // FIXME (#9639): This needs to handle non-utf8 paths
         let status = run::process_status(exe.as_str().unwrap(),
                                          [sysroot.as_str().unwrap().to_owned(), ~"install"]);
         if status != 0 {
-            return (~[], status);
+            debug!("run_custom: first pkg command failed with {:?}", status);
+            (~[], status)
         }
         else {
             debug!("Running program (configs): {} {} {}",
@@ -170,6 +176,7 @@ fn run_custom(&mut self, exec: &mut workcache::Exec,
             // FIXME (#9639): This needs to handle non-utf8 paths
             let output = run::process_output(exe.as_str().unwrap(),
                                              [sysroot.as_str().unwrap().to_owned(), ~"configs"]);
+            debug!("run_custom: second pkg command did {:?}", output.status);
             // Run the configs() function to get the configs
             let cfgs = str::from_utf8_slice(output.output).word_iter()
                 .map(|w| w.to_owned()).collect();
@@ -263,7 +270,7 @@ fn run(&self, cmd: &str, args: ~[~str]) {
         let cwd = os::getcwd();
         match cmd {
             "build" => {
-                self.build_args(args, &Everything);
+                self.build_args(args, &WhatToBuild::new(MaybeCustom, Everything));
             }
             "clean" => {
                 if args.len() < 1 {
@@ -301,12 +308,14 @@ fn run(&self, cmd: &str, args: ~[~str]) {
                             let inferred_pkgid =
                                 PkgId::new(cwd.filename_str().unwrap());
                             self.install(PkgSrc::new(cwd, default_workspace(),
-                                                     true, inferred_pkgid), &Everything);
+                                                     true, inferred_pkgid),
+                                         &WhatToBuild::new(MaybeCustom, Everything));
                         }
                         None  => { usage::install(); return; }
                         Some((ws, pkgid))                => {
                             let pkg_src = PkgSrc::new(ws.clone(), ws.clone(), false, pkgid);
-                            self.install(pkg_src, &Everything);
+                            self.install(pkg_src, &WhatToBuild::new(MaybeCustom,
+                                                                    Everything));
                       }
                   }
                 }
@@ -320,7 +329,7 @@ fn run(&self, cmd: &str, args: ~[~str]) {
                     if workspaces.is_empty() {
                         let d = default_workspace();
                         let src = PkgSrc::new(d.clone(), d, false, pkgid.clone());
-                        self.install(src, &Everything);
+                        self.install(src, &WhatToBuild::new(MaybeCustom, Everything));
                     }
                     else {
                         for workspace in workspaces.iter() {
@@ -331,7 +340,7 @@ fn run(&self, cmd: &str, args: ~[~str]) {
                                                   dest,
                                                   self.context.use_rust_path_hack,
                                                   pkgid.clone());
-                            self.install(src, &Everything);
+                            self.install(src, &WhatToBuild::new(MaybeCustom, Everything));
                         };
                     }
                 }
@@ -354,7 +363,8 @@ fn run(&self, cmd: &str, args: ~[~str]) {
             }
             "test" => {
                 // Build the test executable
-                let maybe_id_and_workspace = self.build_args(args, &Tests);
+                let maybe_id_and_workspace = self.build_args(args,
+                                                             &WhatToBuild::new(MaybeCustom, Tests));
                 match maybe_id_and_workspace {
                     Some((pkg_id, workspace)) => {
                         // Assuming it's built, run the tests
@@ -420,6 +430,7 @@ fn build(&self, pkg_src: &mut PkgSrc, what_to_build: &WhatToBuild) {
                 pkgid = {} pkgsrc start_dir = {}", workspace.display(),
                in_rust_path(&workspace), is_git_dir(&workspace.join(&pkgid.path)),
                pkgid.to_str(), pkg_src.start_dir.display());
+        debug!("build: what to build = {:?}", what_to_build);
 
         // If workspace isn't in the RUST_PATH, and it's a git repo,
         // then clone it into the first entry in RUST_PATH, and repeat
@@ -448,27 +459,27 @@ fn build(&self, pkg_src: &mut PkgSrc, what_to_build: &WhatToBuild) {
         debug!("Package source directory = {}", pkg_src.to_str());
         let opt = pkg_src.package_script_option();
         debug!("Calling pkg_script_option on {:?}", opt);
-        let cfgs = match pkg_src.package_script_option() {
-            Some(package_script_path) => {
+        let cfgs = match (pkg_src.package_script_option(), what_to_build.build_type) {
+            (Some(package_script_path), MaybeCustom)  => {
                 let sysroot = self.sysroot_to_use();
-                // FIXME (#9639): This needs to handle non-utf8 paths
-                let pkg_script_path_str = package_script_path.as_str().unwrap();
-                let (cfgs, hook_result) =
-                    do self.workcache_context.with_prep(pkg_script_path_str) |prep| {
-                    let sub_sysroot = sysroot.clone();
-                    let package_script_path_clone = package_script_path.clone();
-                    let sub_ws = workspace.clone();
-                    let sub_id = pkgid.clone();
-                    declare_package_script_dependency(prep, &*pkg_src);
+                // Build the package script if needed
+                let script_build = format!("build_package_script({})",
+                                           package_script_path.display());
+                let pkg_exe = do self.workcache_context.with_prep(script_build) |prep| {
+                    let subsysroot = sysroot.clone();
+                    let psp = package_script_path.clone();
+                    let ws = workspace.clone();
+                    let pid = pkgid.clone();
                     do prep.exec |exec| {
-                        let mut pscript = PkgScript::parse(@sub_sysroot.clone(),
-                                                          package_script_path_clone.clone(),
-                                                          &sub_ws,
-                                                          &sub_id);
-
-                        pscript.run_custom(exec, &sub_sysroot)
+                        let mut pscript = PkgScript::parse(subsysroot.clone(),
+                                                           psp.clone(),
+                                                           &ws,
+                                                           &pid);
+                        pscript.build_custom(exec)
                     }
                 };
+                // We always *run* the package script
+                let (cfgs, hook_result) = PkgScript::run_custom(&Path::new(pkg_exe), &sysroot);
                 debug!("Command return code = {:?}", hook_result);
                 if hook_result != 0 {
                     fail!("Error running custom build command")
@@ -477,7 +488,11 @@ fn build(&self, pkg_src: &mut PkgSrc, what_to_build: &WhatToBuild) {
                 // otherwise, the package script succeeded
                 cfgs
             }
-            None => {
+            (Some(_), Inferred) => {
+                debug!("There is a package script, but we're ignoring it");
+                ~[]
+            }
+            (None, _) => {
                 debug!("No package script, continuing");
                 ~[]
             }
@@ -486,13 +501,13 @@ fn build(&self, pkg_src: &mut PkgSrc, what_to_build: &WhatToBuild) {
         // If there was a package script, it should have finished
         // the build already. Otherwise...
         if !custom {
-            match what_to_build {
+            match what_to_build.sources {
                 // Find crates inside the workspace
-                &Everything => pkg_src.find_crates(),
+                Everything => pkg_src.find_crates(),
                 // Find only tests
-                &Tests => pkg_src.find_crates_with_filter(|s| { is_test(&Path::new(s)) }),
+                Tests => pkg_src.find_crates_with_filter(|s| { is_test(&Path::new(s)) }),
                 // Don't infer any crates -- just build the one that was requested
-                &JustOne(ref p) => {
+                JustOne(ref p) => {
                     // We expect that p is relative to the package source's start directory,
                     // so check that assumption
                     debug!("JustOne: p = {}", p.display());
@@ -512,7 +527,7 @@ fn build(&self, pkg_src: &mut PkgSrc, what_to_build: &WhatToBuild) {
                 }
             }
             // Build it!
-            pkg_src.build(self, cfgs);
+            pkg_src.build(self, cfgs, []);
         }
     }
 
@@ -551,6 +566,8 @@ fn install(&self, mut pkg_src: PkgSrc, what: &WhatToBuild) -> (~[Path], ~[(~str,
         // just means inferring all the crates in it, then building each one.
         self.build(&mut pkg_src, what);
 
+        debug!("Done building package source {}", pkg_src.to_str());
+
         let to_do = ~[pkg_src.libs.clone(), pkg_src.mains.clone(),
                       pkg_src.tests.clone(), pkg_src.benchs.clone()];
         debug!("In declare inputs for {}", id.to_str());
@@ -823,6 +840,7 @@ pub fn main_args(args: &[~str]) -> int {
         save_temps: save_temps,
         target: target,
         target_cpu: target_cpu,
+        additional_library_paths: ~[], // No way to set this from the rustpkg command line
         experimental_features: experimental_features
     };
 
@@ -895,7 +913,8 @@ pub fn main_args(args: &[~str]) -> int {
                 use_rust_path_hack: use_rust_path_hack,
                 sysroot: sroot.clone(), // Currently, only tests override this
             },
-            workcache_context: api::default_context(default_workspace()).workcache_context
+            workcache_context: api::default_context(sroot.clone(),
+                                                    default_workspace()).workcache_context
         }.run(sub_cmd, rm_args.clone())
     };
     // FIXME #9262: This is using the same error code for all errors,
index b21641a5e53e31f6567d8f9e27313520aebd1d58..9863fd0a89ee9357fb2dd9c8fb95f2df14c6dda7 100644 (file)
@@ -23,7 +23,31 @@ pub enum Target {
 }
 
 #[deriving(Eq, Clone)]
-pub enum WhatToBuild {
+pub struct WhatToBuild {
+    build_type: BuildType, // Whether or not to ignore the pkg.rs file
+    sources: SourceType, // Which crates to build
+    inputs_to_discover: ~[(~str, Path)] // Inputs to these crates to be discovered
+        // (For now all of these inputs will be taken as discovered inputs
+        // for all of the crates)
+        // (Paired with their kinds)
+}
+
+impl WhatToBuild {
+    pub fn new(build_type: BuildType, sources: SourceType) -> WhatToBuild {
+        WhatToBuild { build_type: build_type,
+                      sources: sources,
+                      inputs_to_discover: ~[] }
+    }
+}
+
+#[deriving(Eq, Clone)]
+pub enum BuildType {
+    Inferred, // Ignore the pkg.rs file even if one exists
+    MaybeCustom // Use the pkg.rs file if it exists
+}
+
+#[deriving(Eq, Clone)]
+pub enum SourceType {
     /// Build just one lib.rs file in `path`, which is relative to the active workspace's src/ dir
     JustOne(Path),
     /// Build any test.rs files that can be recursively found in the active workspace
index 58c6b4ff81fb66e9e193d1ad45aab93055689c96..16e13f700921246d932a0b018e44db84be392d42 100644 (file)
@@ -28,7 +28,7 @@
                library_in_workspace, installed_library_in_workspace,
                built_bench_in_workspace, built_test_in_workspace,
                built_library_in_workspace, built_executable_in_workspace, target_build_dir,
-               chmod_read_only};
+               chmod_read_only, platform_library_name};
 use rustc::back::link::get_cc_prog;
 use rustc::metadata::filesearch::rust_path;
 use rustc::driver::driver::{build_session, build_session_options, host_triple, optgroups};
@@ -299,12 +299,6 @@ fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~s
                     cmd, args, str::from_utf8(output.output),
                    str::from_utf8(output.error),
                    output.status);
-/*
-By the way, rustpkg *won't* return a nonzero exit code if it fails --
-see #4547
-So tests that use this need to check the existence of a file
-to make sure the command succeeded
-*/
     if output.status != 0 {
         debug!("Command {} {:?} failed with exit code {:?}; its output was --- {} ---",
               cmd, args, output.status,
@@ -600,7 +594,7 @@ fn test_install_valid() {
                           temp_workspace.clone(),
                           false,
                           temp_pkg_id.clone());
-    ctxt.install(src, &Everything);
+    ctxt.install(src, &WhatToBuild::new(MaybeCustom, Everything));
     // Check that all files exist
     let exec = target_executable_in_workspace(&temp_pkg_id, temp_workspace);
     debug!("exec = {}", exec.display());
@@ -639,7 +633,7 @@ fn test_install_invalid() {
                                   temp_workspace.clone(),
                                   false,
                                   pkgid.clone());
-        ctxt.install(pkg_src, &Everything);
+        ctxt.install(pkg_src, &WhatToBuild::new(MaybeCustom, Everything));
     };
     // Not the best test -- doesn't test that we failed in the right way.
     // Best we can do for now.
@@ -897,14 +891,14 @@ fn rustpkg_local_pkg() {
 }
 
 #[test]
-#[ignore (reason = "test makes bogus assumptions about build directory layout: issue #8690")]
 fn package_script_with_default_build() {
     let dir = create_local_package(&PkgId::new("fancy-lib"));
     let dir = dir.path();
     debug!("dir = {}", dir.display());
     let mut source = test_sysroot().dir_path();
     source.pop(); source.pop();
-    source.push_many(["src", "librustpkg", "testsuite", "pass", "src", "fancy-lib", "pkg.rs"]);
+    let source = Path::new(file!()).dir_path().join_many(
+        [~"testsuite", ~"pass", ~"src", ~"fancy-lib", ~"pkg.rs"]);
     debug!("package_script_with_default_build: {}", source.display());
     if !os::copy_file(&source,
                       &dir.join_many(["src", "fancy-lib-0.1", "pkg.rs"])) {
@@ -912,7 +906,10 @@ fn package_script_with_default_build() {
     }
     command_line_test([~"install", ~"fancy-lib"], dir);
     assert_lib_exists(dir, &Path::new("fancy-lib"), NoVersion);
-    assert!(os::path_exists(&target_build_dir(dir).join_many(["fancy-lib", "generated.rs"])));
+    assert!(os::path_exists(&target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"])));
+    let generated_path = target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]);
+    debug!("generated path = {}", generated_path.display());
+    assert!(os::path_exists(&generated_path));
 }
 
 #[test]
@@ -2251,6 +2248,106 @@ fn find_sources_in_cwd() {
     assert_executable_exists(&source_dir.join(".rust"), "foo");
 }
 
+#[test]
+fn test_c_dependency_ok() {
+    // Pkg has a custom build script that adds a single C file as a dependency, and
+    // registers a hook to build it if it's not fresh
+    // After running `build`, test that the C library built
+
+    let dir = create_local_package(&PkgId::new("cdep"));
+    let dir = dir.path();
+    writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]),
+              "#[link_args = \"-lfoo\"]\nextern { fn f(); } \
+              \n#[fixed_stack_segment]\nfn main() { unsafe { f(); } }");
+    writeFile(&dir.join_many(["src", "cdep-0.1", "foo.c"]), "void f() {}");
+
+    debug!("dir = {}", dir.display());
+    let source = Path::new(file!()).dir_path().join_many(
+        [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
+    if !os::copy_file(&source,
+                      &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])) {
+        fail!("Couldn't copy file");
+    }
+    command_line_test([~"build", ~"cdep"], dir);
+    assert_executable_exists(dir, "cdep");
+    let out_dir = target_build_dir(dir).join("cdep");
+    let c_library_path = out_dir.join(platform_library_name("foo"));
+    debug!("c library path: {}", c_library_path.display());
+    assert!(os::path_exists(&c_library_path));
+}
+
+#[test]
+fn test_c_dependency_no_rebuilding() {
+    let dir = create_local_package(&PkgId::new("cdep"));
+    let dir = dir.path();
+    writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]),
+              "#[link_args = \"-lfoo\"]\nextern { fn f(); } \
+              \n#[fixed_stack_segment]\nfn main() { unsafe { f(); } }");
+    writeFile(&dir.join_many(["src", "cdep-0.1", "foo.c"]), "void f() {}");
+
+    debug!("dir = {}", dir.display());
+    let source = Path::new(file!()).dir_path().join_many(
+        [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
+    if !os::copy_file(&source,
+                      &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])) {
+        fail!("Couldn't copy file");
+    }
+    command_line_test([~"build", ~"cdep"], dir);
+    assert_executable_exists(dir, "cdep");
+    let out_dir = target_build_dir(dir).join("cdep");
+    let c_library_path = out_dir.join(platform_library_name("foo"));
+    debug!("c library path: {}", c_library_path.display());
+    assert!(os::path_exists(&c_library_path));
+
+    // Now, make it read-only so rebuilding will fail
+    assert!(chmod_read_only(&c_library_path));
+
+    match command_line_test_partial([~"build", ~"cdep"], dir) {
+        Success(*) => (), // ok
+        Fail(status) if status == 65 => fail!("test_c_dependency_no_rebuilding failed: \
+                                              it tried to rebuild foo.c"),
+        Fail(_) => fail!("test_c_dependency_no_rebuilding failed for some other reason")
+    }
+}
+
+#[test]
+fn test_c_dependency_yes_rebuilding() {
+    let dir = create_local_package(&PkgId::new("cdep"));
+    let dir = dir.path();
+    writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]),
+              "#[link_args = \"-lfoo\"]\nextern { fn f(); } \
+              \n#[fixed_stack_segment]\nfn main() { unsafe { f(); } }");
+    let c_file_name = dir.join_many(["src", "cdep-0.1", "foo.c"]);
+    writeFile(&c_file_name, "void f() {}");
+
+    let source = Path::new(file!()).dir_path().join_many(
+        [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
+    let target = dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"]);
+    debug!("Copying {} -> {}", source.display(), target.display());
+    if !os::copy_file(&source, &target) {
+        fail!("Couldn't copy file");
+    }
+    command_line_test([~"build", ~"cdep"], dir);
+    assert_executable_exists(dir, "cdep");
+    let out_dir = target_build_dir(dir).join("cdep");
+    let c_library_path = out_dir.join(platform_library_name("foo"));
+    debug!("c library path: {}", c_library_path.display());
+    assert!(os::path_exists(&c_library_path));
+
+    // Now, make the Rust library read-only so rebuilding will fail
+    match built_library_in_workspace(&PkgId::new("cdep"), dir) {
+        Some(ref pth) => assert!(chmod_read_only(pth)),
+        None => assert_built_library_exists(dir, "cdep")
+    }
+
+    match command_line_test_partial([~"build", ~"cdep"], dir) {
+        Success(*) => fail!("test_c_dependency_yes_rebuilding failed: \
+                            it didn't rebuild and should have"),
+        Fail(status) if status == 65 => (),
+        Fail(_) => fail!("test_c_dependency_yes_rebuilding failed for some other reason")
+    }
+}
+
 /// 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/testsuite/pass/src/c-dependencies/bar.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/bar.rs
new file mode 100644 (file)
index 0000000..ffbc6e2
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn assert_true() {
+    assert!(true);
+}
diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs
new file mode 100644 (file)
index 0000000..542a6af
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn do_nothing() {
+}
\ No newline at end of file
diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/lib.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/lib.rs
new file mode 100644 (file)
index 0000000..bd1cb24
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern mod std;
+
+pub mod foo;
+pub mod bar;
diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs
new file mode 100644 (file)
index 0000000..b667dc0
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern mod rustpkg;
+extern mod rustc;
+
+use std::{io, os, task};
+use rustpkg::api;
+use rustpkg::version::NoVersion;
+use rustpkg::workcache_support::digest_file_with_date;
+use rustpkg::exit_codes::COPY_FAILED_CODE;
+
+pub fn main() {
+    let args = os::args();
+
+// by convention, first arg is sysroot
+    if args.len() < 2 {
+        fail!("Package script requires a directory where rustc libraries live as the first \
+               argument");
+    }
+
+    let path_for_db = api::default_workspace();
+    debug!("path_for_db = {}", path_for_db.display());
+
+    let sysroot_arg = args[1].clone();
+    let sysroot = Path::new(sysroot_arg);
+    if !os::path_exists(&sysroot) {
+        fail!("Package script requires a sysroot that exists; {} doesn't", sysroot.display());
+    }
+
+    if args[2] != ~"install" {
+        io::println(format!("Warning: I don't know how to {}", args[2]));
+        return;
+    }
+
+    let mut context = api::default_context(sysroot, path_for_db);
+    let my_workspace = api::my_workspace(&context.context, "cdep");
+    let foo_c_name = my_workspace.join_many(["src", "cdep-0.1", "foo.c"]);
+
+    let out_lib_path = do context.workcache_context.with_prep("foo.c") |prep| {
+        let sub_cx = context.context.clone();
+        debug!("foo_c_name = {}", foo_c_name.display());
+        prep.declare_input("file",
+                           foo_c_name.as_str().unwrap().to_owned(),
+                           digest_file_with_date(&foo_c_name));
+        let out_path = do prep.exec |exec| {
+            let out_path = api::build_library_in_workspace(exec,
+                                                           &mut sub_cx.clone(),
+                                                           "cdep",
+                                                           "gcc",
+                                                           [~"-c"],
+                                                           [~"foo.c"],
+                                                           "foo");
+            let out_p = Path::new(out_path);
+            out_p.as_str().unwrap().to_owned()
+        };
+        out_path
+    };
+    let out_lib_path = Path::new(out_lib_path);
+    debug!("out_lib_path = {}", out_lib_path.display());
+    context.add_library_path(out_lib_path.dir_path());
+
+    let context_clone = context.clone();
+    let task_res = do task::try {
+        let mut cc = context_clone.clone();
+        api::install_pkg(&mut cc,
+                         os::getcwd(),
+                         ~"cdep",
+                         NoVersion,
+                         ~[(~"binary", out_lib_path.clone()), (~"file", foo_c_name.clone())]);
+    };
+
+    if task_res.is_err() {
+        os::set_exit_status(COPY_FAILED_CODE);
+    }
+}
index dc068eed143efd313d93299be2e0debbc10a0228..17386cd03c22b605a6edd3c6f758005bbcb67d00 100644 (file)
@@ -21,4 +21,4 @@
 
 pub mod foo;
 pub mod bar;
-#[path = "../../build/fancy_lib/generated.rs"] pub mod generated;
+#[path = "../../build/fancy-lib/generated.rs"] pub mod generated;
index db11ffa0cc644ff3c6b5c47ce253e8a0f9ba7e7f..0b838b3e0f9e34547e207d6313113fb6d14e0a98 100644 (file)
 use rustpkg::api;
 use rustpkg::version::NoVersion;
 
-use rustc::metadata::filesearch;
-
 pub fn main() {
-    use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
     let args = os::args();
 
 // by convention, first arg is sysroot
     if args.len() < 2 {
+        debug!("Failing, arg len");
         fail!("Package script requires a directory where rustc libraries live as the first \
                argument");
     }
 
     let sysroot_arg = args[1].clone();
-    let sysroot = Path(sysroot_arg);
+    let sysroot = Path::new(sysroot_arg);
     if !os::path_exists(&sysroot) {
-        fail!("Package script requires a sysroot that exists; %s doesn't", sysroot.to_str());
+        debug!("Failing, sysroot");
+        fail!("Package script requires a sysroot that exists;{} doesn't", sysroot.display());
     }
 
     if args[2] != ~"install" {
+        debug!("Failing, weird command");
         println!("Warning: I don't know how to {}", args[2]);
         return;
     }
 
-    let out_path = Path("build/fancy-lib");
-    if !os::path_exists(&out_path) {
-        assert!(os::make_dir(&out_path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
-    }
-
-    let file = io::file_writer(&out_path.push("generated.rs"),
-                               [io::Create]).unwrap();
-    file.write_str("pub fn wheeeee() { for [1, 2, 3].each() |_| { assert!(true); } }");
-
+    debug!("Checking self_exe_path");
+    let out_path = os::self_exe_path().expect("Couldn't get self_exe path");
 
-    debug!("api_____install_____lib, my sysroot:");
-    debug!(sysroot.to_str());
+    debug!("Writing file");
+    let file = io::file_writer(&out_path.join("generated.rs"), [io::Create]).unwrap();
+    file.write_str("pub fn wheeeee() { let xs = [1, 2, 3]; \
+                   for _ in xs.iter() { assert!(true); } }");
 
-    api::install_lib(@sysroot, os::getcwd(), ~"fancy-lib", Path("lib.rs"),
-                     NoVersion);
+    let context = api::default_context(sysroot, api::default_workspace());
+    api::install_pkg(&context, os::getcwd(), ~"fancy-lib", NoVersion, ~[]);
 }
index a3a4a07cfc77a9dbf432c78255d15ea55fba782c..0e4fbbf2c10fbabc682f2d7624317af17778a89e 100644 (file)
 use package_id::PkgId;
 use package_source::PkgSrc;
 use workspace::pkg_parent_workspaces;
-use path_util::{U_RWX, system_library, target_build_dir};
+use path_util::{system_library, target_build_dir};
 use path_util::{default_workspace, built_library_in_workspace};
 pub use target::{OutputType, Main, Lib, Bench, Test, JustOne, lib_name_of, lib_crate_filename};
 pub use target::{Target, Build, Install};
 use extra::treemap::TreeMap;
+use path_util::U_RWX;
+pub use target::{lib_name_of, lib_crate_filename, WhatToBuild, MaybeCustom, Inferred};
 use workcache_support::{digest_file_with_date, digest_only_date};
 
 // It would be nice to have the list of commands in just one place -- for example,
@@ -233,12 +235,14 @@ pub fn compile_input(context: &BuildContext,
         Nothing => link::output_type_exe
     };
 
+    debug!("Output type = {:?}", output_type);
+
     let options = @session::options {
         crate_type: crate_type,
         optimize: if opt { session::Aggressive } else { session::No },
         test: what == Test || what == Bench,
         maybe_sysroot: Some(sysroot_to_use),
-        addl_lib_search_paths: @mut (~[]),
+        addl_lib_search_paths: @mut context.additional_library_paths(),
         output_type: output_type,
         .. (*driver::build_session_options(binary,
                                            &matches,
@@ -246,6 +250,8 @@ pub fn compile_input(context: &BuildContext,
                                             @diagnostic::Emitter)).clone()
     };
 
+    debug!("Created options...");
+
     let addl_lib_search_paths = @mut options.addl_lib_search_paths;
     // Make sure all the library directories actually exist, since the linker will complain
     // otherwise
@@ -258,16 +264,22 @@ pub fn compile_input(context: &BuildContext,
         }
     }
 
+    debug!("About to build session...");
+
     let sess = driver::build_session(options,
                                      @diagnostic::DefaultEmitter as
                                         @diagnostic::Emitter);
 
+    debug!("About to build config...");
+
     // Infer dependencies that rustpkg needs to build, by scanning for
     // `extern mod` directives.
     let cfg = driver::build_configuration(sess);
     let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
     crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
 
+    debug!("About to call find_and_install_dependencies...");
+
     find_and_install_dependencies(context, pkg_id, in_file, sess, exec, &crate, deps,
                                   |p| {
                                       debug!("a dependency: {}", p.display());
@@ -377,7 +389,6 @@ pub fn compile_crate_from_input(input: &Path,
 
     debug!("Built {}, date = {:?}", outputs.out_filename.display(),
            datestamp(&outputs.out_filename));
-
     Some(outputs.out_filename)
 }
 
@@ -431,7 +442,9 @@ fn visit_view_item(&mut self, vi: &ast::view_item, env: ()) {
                 };
                 debug!("Finding and installing... {}", lib_name);
                 // Check standard Rust library path first
-                match system_library(&self.context.sysroot(), lib_name) {
+                let whatever = system_library(&self.context.sysroot(), lib_name);
+                debug!("system library returned {:?}", whatever);
+                match whatever {
                     Some(ref installed_path) => {
                         debug!("It exists: {}", installed_path.display());
                         // Say that [path for c] has a discovered dependency on
@@ -478,7 +491,10 @@ fn visit_view_item(&mut self, vi: &ast::view_item, env: ()) {
                                                   self.context.context.use_rust_path_hack,
                                                   pkg_id.clone());
                         let (outputs_disc, inputs_disc) =
-                            self.context.install(pkg_src, &JustOne(Path::new(lib_crate_filename)));
+                            self.context.install(
+                                pkg_src,
+                                &WhatToBuild::new(Inferred,
+                                                  JustOne(Path::new(lib_crate_filename))));
                         debug!("Installed {}, returned {:?} dependencies and \
                                {:?} transitive dependencies",
                                lib_name, outputs_disc.len(), inputs_disc.len());