mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-05 04:15:06 +00:00
auto merge of #9107 : catamorphism/rust/rustpkg-command-line-flags, r=brson
r? @brson rustpkg now accepts most of rustc's command-line arguments and passes them along to rustc when building or installing. A few rarely-used arguments aren't implemented yet. rustpkg doesn't support flags that don't make sense with rustpkg (for example, --bin and --lib, which get inferred from crate file names). Closes #8522
This commit is contained in:
commit
d14bd0879d
@ -29,6 +29,8 @@ pub fn default_context(p: Path) -> BuildContext {
|
||||
pub fn new_default_context(c: workcache::Context, p: Path) -> BuildContext {
|
||||
BuildContext {
|
||||
context: Context {
|
||||
cfgs: ~[],
|
||||
rustc_flags: RustcFlags::default(),
|
||||
use_rust_path_hack: false,
|
||||
sysroot: p
|
||||
},
|
||||
@ -44,7 +46,6 @@ fn binary_is_fresh(path: &str, in_hash: &str) -> bool {
|
||||
in_hash == digest_only_date(&Path(path))
|
||||
}
|
||||
|
||||
|
||||
pub fn new_workcache_context(p: &Path) -> workcache::Context {
|
||||
let db_file = p.push("rustpkg_db.json"); // ??? probably wrong
|
||||
debug!("Workcache database file: %s", db_file.to_str());
|
||||
|
@ -10,11 +10,16 @@
|
||||
|
||||
// Context data structure used by rustpkg
|
||||
|
||||
use std::os;
|
||||
use std::{io, os};
|
||||
use extra::workcache;
|
||||
use rustc::driver::session::{OptLevel, No};
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct Context {
|
||||
// Config strings that the user passed in with --cfg
|
||||
cfgs: ~[~str],
|
||||
// Flags to pass to rustc
|
||||
rustc_flags: RustcFlags,
|
||||
// If use_rust_path_hack is true, rustpkg searches for sources
|
||||
// in *package* directories that are in the RUST_PATH (for example,
|
||||
// FOO/src/bar-0.1 instead of FOO). The flag doesn't affect where
|
||||
@ -40,15 +45,82 @@ impl BuildContext {
|
||||
pub fn sysroot_to_use(&self) -> Path {
|
||||
self.context.sysroot_to_use()
|
||||
}
|
||||
|
||||
/// Returns the flags to pass to rustc, as a vector of strings
|
||||
pub fn flag_strs(&self) -> ~[~str] {
|
||||
self.context.flag_strs()
|
||||
}
|
||||
|
||||
pub fn compile_upto(&self) -> StopBefore {
|
||||
self.context.compile_upto()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Deliberately unsupported rustc flags:
|
||||
--bin, --lib inferred from crate file names
|
||||
-L inferred from extern mods
|
||||
--out-dir inferred from RUST_PATH
|
||||
--test use `rustpkg test`
|
||||
-v -h --ls don't make sense with rustpkg
|
||||
-W -A -D -F - use pragmas instead
|
||||
|
||||
rustc flags that aren't implemented yet:
|
||||
--passes
|
||||
--llvm-arg
|
||||
--target-feature
|
||||
--android-cross-path
|
||||
*/
|
||||
pub struct RustcFlags {
|
||||
compile_upto: StopBefore,
|
||||
// Linker to use with the --linker flag
|
||||
linker: Option<~str>,
|
||||
// Extra arguments to pass to rustc with the --link-args flag
|
||||
link_args: Option<~str>,
|
||||
// Optimization level. 0 = default. -O = 2.
|
||||
optimization_level: OptLevel,
|
||||
// True if the user passed in --save-temps
|
||||
save_temps: bool,
|
||||
// Target (defaults to rustc's default target)
|
||||
target: Option<~str>,
|
||||
// Target CPU (defaults to rustc's default target CPU)
|
||||
target_cpu: Option<~str>,
|
||||
// Any -Z features
|
||||
experimental_features: Option<~[~str]>
|
||||
}
|
||||
|
||||
impl Clone for RustcFlags {
|
||||
fn clone(&self) -> RustcFlags {
|
||||
RustcFlags {
|
||||
compile_upto: self.compile_upto,
|
||||
linker: self.linker.clone(),
|
||||
link_args: self.link_args.clone(),
|
||||
optimization_level: self.optimization_level,
|
||||
save_temps: self.save_temps,
|
||||
target: self.target.clone(),
|
||||
target_cpu: self.target_cpu.clone(),
|
||||
experimental_features: self.experimental_features.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum StopBefore {
|
||||
Nothing, // compile everything
|
||||
Link, // --no-link
|
||||
LLVMCompileBitcode, // --emit-llvm without -S
|
||||
LLVMAssemble, // -S --emit-llvm
|
||||
Assemble, // -S without --emit-llvm
|
||||
Trans, // --no-trans
|
||||
Pretty, // --pretty
|
||||
Analysis, // --parse-only
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn sysroot(&self) -> Path {
|
||||
self.sysroot.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Debugging
|
||||
pub fn sysroot_str(&self) -> ~str {
|
||||
self.sysroot.to_str()
|
||||
@ -63,6 +135,15 @@ impl Context {
|
||||
self.sysroot.pop().pop().pop()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the flags to pass to rustc, as a vector of strings
|
||||
pub fn flag_strs(&self) -> ~[~str] {
|
||||
self.rustc_flags.flag_strs()
|
||||
}
|
||||
|
||||
pub fn compile_upto(&self) -> StopBefore {
|
||||
self.rustc_flags.compile_upto
|
||||
}
|
||||
}
|
||||
|
||||
/// We assume that if ../../rustc exists, then we're running
|
||||
@ -72,3 +153,141 @@ pub fn in_target(sysroot: &Path) -> bool {
|
||||
debug!("Checking whether %s is in target", sysroot.to_str());
|
||||
os::path_is_dir(&sysroot.pop().pop().push("rustc"))
|
||||
}
|
||||
|
||||
impl RustcFlags {
|
||||
fn flag_strs(&self) -> ~[~str] {
|
||||
let linker_flag = match self.linker {
|
||||
Some(ref l) => ~[~"--linker", l.clone()],
|
||||
None => ~[]
|
||||
};
|
||||
let link_args_flag = match self.link_args {
|
||||
Some(ref l) => ~[~"--link-args", l.clone()],
|
||||
None => ~[]
|
||||
};
|
||||
let save_temps_flag = if self.save_temps { ~[~"--save-temps"] } else { ~[] };
|
||||
let target_flag = match self.target {
|
||||
Some(ref l) => ~[~"--target", l.clone()],
|
||||
None => ~[]
|
||||
};
|
||||
let target_cpu_flag = match self.target_cpu {
|
||||
Some(ref l) => ~[~"--target-cpu", l.clone()],
|
||||
None => ~[]
|
||||
};
|
||||
let z_flags = match self.experimental_features {
|
||||
Some(ref ls) => ls.flat_map(|s| ~[~"-Z", s.clone()]),
|
||||
None => ~[]
|
||||
};
|
||||
linker_flag
|
||||
+ link_args_flag
|
||||
+ save_temps_flag
|
||||
+ target_flag
|
||||
+ target_cpu_flag
|
||||
+ z_flags + (match self.compile_upto {
|
||||
LLVMCompileBitcode => ~[~"--emit-llvm"],
|
||||
LLVMAssemble => ~[~"--emit-llvm", ~"-S"],
|
||||
Link => ~[~"-c"],
|
||||
Trans => ~[~"--no-trans"],
|
||||
Assemble => ~[~"-S"],
|
||||
// n.b. Doesn't support all flavors of --pretty (yet)
|
||||
Pretty => ~[~"--pretty"],
|
||||
Analysis => ~[~"--parse-only"],
|
||||
Nothing => ~[]
|
||||
})
|
||||
}
|
||||
|
||||
pub fn default() -> RustcFlags {
|
||||
RustcFlags {
|
||||
linker: None,
|
||||
link_args: None,
|
||||
compile_upto: Nothing,
|
||||
optimization_level: No,
|
||||
save_temps: false,
|
||||
target: None,
|
||||
target_cpu: None,
|
||||
experimental_features: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if any of the flags given are incompatible with the cmd
|
||||
pub fn flags_ok_for_cmd(flags: &RustcFlags,
|
||||
cfgs: &[~str],
|
||||
cmd: &str, user_supplied_opt_level: bool) -> bool {
|
||||
let complain = |s| {
|
||||
io::println(fmt!("The %s option can only be used with the build command:
|
||||
rustpkg [options..] build %s [package-ID]", s, s));
|
||||
};
|
||||
|
||||
if flags.linker.is_some() && cmd != "build" && cmd != "install" {
|
||||
io::println("The --linker option can only be used with the build or install commands.");
|
||||
return true;
|
||||
}
|
||||
if flags.link_args.is_some() && cmd != "build" && cmd != "install" {
|
||||
io::println("The --link-args option can only be used with the build or install commands.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if !cfgs.is_empty() && cmd != "build" && cmd != "install" {
|
||||
io::println("The --cfg option can only be used with the build or install commands.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if user_supplied_opt_level && cmd != "build" && cmd != "install" {
|
||||
io::println("The -O and --opt-level options can only be used with the build \
|
||||
or install commands.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if flags.save_temps && cmd != "build" && cmd != "install" {
|
||||
io::println("The --save-temps option can only be used with the build \
|
||||
or install commands.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if flags.target.is_some() && cmd != "build" && cmd != "install" {
|
||||
io::println("The --target option can only be used with the build \
|
||||
or install commands.");
|
||||
return true;
|
||||
}
|
||||
if flags.target_cpu.is_some() && cmd != "build" && cmd != "install" {
|
||||
io::println("The --target-cpu option can only be used with the build \
|
||||
or install commands.");
|
||||
return true;
|
||||
}
|
||||
if flags.experimental_features.is_some() && cmd != "build" && cmd != "install" {
|
||||
io::println("The -Z option can only be used with the build or install commands.");
|
||||
return true;
|
||||
}
|
||||
|
||||
match flags.compile_upto {
|
||||
Link if cmd != "build" => {
|
||||
complain("--no-link");
|
||||
true
|
||||
}
|
||||
Trans if cmd != "build" => {
|
||||
complain("--no-trans");
|
||||
true
|
||||
}
|
||||
Assemble if cmd != "build" => {
|
||||
complain("-S");
|
||||
true
|
||||
}
|
||||
Pretty if cmd != "build" => {
|
||||
complain("--pretty");
|
||||
true
|
||||
}
|
||||
Analysis if cmd != "build" => {
|
||||
complain("--parse-only");
|
||||
true
|
||||
}
|
||||
LLVMCompileBitcode if cmd != "build" => {
|
||||
complain("--emit-llvm");
|
||||
true
|
||||
}
|
||||
LLVMAssemble if cmd != "build" => {
|
||||
complain("--emit-llvm");
|
||||
true
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,9 @@ use path_util::{built_executable_in_workspace, built_library_in_workspace, defau
|
||||
use path_util::{target_executable_in_workspace, target_library_in_workspace};
|
||||
use source_control::is_git_dir;
|
||||
use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces, cwd_to_workspace};
|
||||
use context::{BuildContext, Context};
|
||||
use context::{Context, BuildContext,
|
||||
RustcFlags, Trans, Link, Nothing, Pretty, Analysis, Assemble,
|
||||
LLVMAssemble, LLVMCompileBitcode};
|
||||
use package_id::PkgId;
|
||||
use package_source::PkgSrc;
|
||||
use workcache_support::{discover_outputs, digest_only_date};
|
||||
@ -138,6 +140,7 @@ impl<'self> PkgScript<'self> {
|
||||
let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
|
||||
util::compile_crate_from_input(&self.input,
|
||||
exec,
|
||||
Nothing,
|
||||
&self.build_dir,
|
||||
sess,
|
||||
crate);
|
||||
@ -400,7 +403,7 @@ impl CtxMethods for BuildContext {
|
||||
debug!("No package script, continuing");
|
||||
~[]
|
||||
}
|
||||
};
|
||||
} + self.context.cfgs;
|
||||
|
||||
// If there was a package script, it should have finished
|
||||
// the build already. Otherwise...
|
||||
@ -539,9 +542,25 @@ pub fn main() {
|
||||
|
||||
pub fn main_args(args: &[~str]) {
|
||||
let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
|
||||
getopts::optflag("no-link"),
|
||||
getopts::optflag("no-trans"),
|
||||
// n.b. Ignores different --pretty options for now
|
||||
getopts::optflag("pretty"),
|
||||
getopts::optflag("parse-only"),
|
||||
getopts::optflag("S"), getopts::optflag("assembly"),
|
||||
getopts::optmulti("c"), getopts::optmulti("cfg"),
|
||||
getopts::optflag("v"), getopts::optflag("version"),
|
||||
getopts::optflag("r"), getopts::optflag("rust-path-hack")];
|
||||
getopts::optflag("r"), getopts::optflag("rust-path-hack"),
|
||||
getopts::optopt("sysroot"),
|
||||
getopts::optflag("emit-llvm"),
|
||||
getopts::optopt("linker"),
|
||||
getopts::optopt("link-args"),
|
||||
getopts::optopt("opt-level"),
|
||||
getopts::optflag("O"),
|
||||
getopts::optflag("save-temps"),
|
||||
getopts::optopt("target"),
|
||||
getopts::optopt("target-cpu"),
|
||||
getopts::optmulti("Z") ];
|
||||
let matches = &match getopts::getopts(args, opts) {
|
||||
result::Ok(m) => m,
|
||||
result::Err(f) => {
|
||||
@ -550,8 +569,16 @@ pub fn main_args(args: &[~str]) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let help = getopts::opt_present(matches, "h") ||
|
||||
getopts::opt_present(matches, "help");
|
||||
let mut help = getopts::opt_present(matches, "h") ||
|
||||
getopts::opt_present(matches, "help");
|
||||
let no_link = getopts::opt_present(matches, "no-link");
|
||||
let no_trans = getopts::opt_present(matches, "no-trans");
|
||||
let supplied_sysroot = getopts::opt_val(matches, "sysroot");
|
||||
let generate_asm = getopts::opt_present(matches, "S") ||
|
||||
getopts::opt_present(matches, "assembly");
|
||||
let parse_only = getopts::opt_present(matches, "parse-only");
|
||||
let pretty = getopts::opt_present(matches, "pretty");
|
||||
let emit_llvm = getopts::opt_present(matches, "emit-llvm");
|
||||
|
||||
if getopts::opt_present(matches, "v") ||
|
||||
getopts::opt_present(matches, "version") {
|
||||
@ -562,6 +589,35 @@ pub fn main_args(args: &[~str]) {
|
||||
let use_rust_path_hack = getopts::opt_present(matches, "r") ||
|
||||
getopts::opt_present(matches, "rust-path-hack");
|
||||
|
||||
let linker = getopts::opt_maybe_str(matches, "linker");
|
||||
let link_args = getopts::opt_maybe_str(matches, "link-args");
|
||||
let cfgs = getopts::opt_strs(matches, "cfg") + getopts::opt_strs(matches, "c");
|
||||
let mut user_supplied_opt_level = true;
|
||||
let opt_level = match getopts::opt_maybe_str(matches, "opt-level") {
|
||||
Some(~"0") => session::No,
|
||||
Some(~"1") => session::Less,
|
||||
Some(~"2") => session::Default,
|
||||
Some(~"3") => session::Aggressive,
|
||||
_ if getopts::opt_present(matches, "O") => session::Default,
|
||||
_ => {
|
||||
user_supplied_opt_level = false;
|
||||
session::No
|
||||
}
|
||||
};
|
||||
|
||||
let save_temps = getopts::opt_present(matches, "save-temps");
|
||||
let target = getopts::opt_maybe_str(matches, "target");
|
||||
let target_cpu = getopts::opt_maybe_str(matches, "target-cpu");
|
||||
let experimental_features = {
|
||||
let strs = getopts::opt_strs(matches, "Z");
|
||||
if getopts::opt_present(matches, "Z") {
|
||||
Some(strs)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let mut args = matches.free.clone();
|
||||
args.shift();
|
||||
|
||||
@ -569,6 +625,33 @@ pub fn main_args(args: &[~str]) {
|
||||
return usage::general();
|
||||
}
|
||||
|
||||
let rustc_flags = RustcFlags {
|
||||
linker: linker,
|
||||
link_args: link_args,
|
||||
optimization_level: opt_level,
|
||||
compile_upto: if no_trans {
|
||||
Trans
|
||||
} else if no_link {
|
||||
Link
|
||||
} else if pretty {
|
||||
Pretty
|
||||
} else if parse_only {
|
||||
Analysis
|
||||
} else if emit_llvm && generate_asm {
|
||||
LLVMAssemble
|
||||
} else if generate_asm {
|
||||
Assemble
|
||||
} else if emit_llvm {
|
||||
LLVMCompileBitcode
|
||||
} else {
|
||||
Nothing
|
||||
},
|
||||
save_temps: save_temps,
|
||||
target: target,
|
||||
target_cpu: target_cpu,
|
||||
experimental_features: experimental_features
|
||||
};
|
||||
|
||||
let mut cmd_opt = None;
|
||||
for a in args.iter() {
|
||||
if util::is_cmd(*a) {
|
||||
@ -578,23 +661,25 @@ pub fn main_args(args: &[~str]) {
|
||||
}
|
||||
let cmd = match cmd_opt {
|
||||
None => return usage::general(),
|
||||
Some(cmd) => if help {
|
||||
return match *cmd {
|
||||
~"build" => usage::build(),
|
||||
~"clean" => usage::clean(),
|
||||
~"do" => usage::do_cmd(),
|
||||
~"info" => usage::info(),
|
||||
~"install" => usage::install(),
|
||||
~"list" => usage::list(),
|
||||
~"prefer" => usage::prefer(),
|
||||
~"test" => usage::test(),
|
||||
~"uninstall" => usage::uninstall(),
|
||||
~"unprefer" => usage::unprefer(),
|
||||
_ => usage::general()
|
||||
};
|
||||
}
|
||||
else {
|
||||
cmd
|
||||
Some(cmd) => {
|
||||
help |= context::flags_ok_for_cmd(&rustc_flags, cfgs, *cmd, user_supplied_opt_level);
|
||||
if help {
|
||||
return match *cmd {
|
||||
~"build" => usage::build(),
|
||||
~"clean" => usage::clean(),
|
||||
~"do" => usage::do_cmd(),
|
||||
~"info" => usage::info(),
|
||||
~"install" => usage::install(),
|
||||
~"list" => usage::list(),
|
||||
~"prefer" => usage::prefer(),
|
||||
~"test" => usage::test(),
|
||||
~"uninstall" => usage::uninstall(),
|
||||
~"unprefer" => usage::unprefer(),
|
||||
_ => usage::general()
|
||||
};
|
||||
} else {
|
||||
cmd
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -603,14 +688,20 @@ pub fn main_args(args: &[~str]) {
|
||||
// I had to add this type annotation to get the code to typecheck
|
||||
let mut remaining_args: ~[~str] = remaining_args.map(|s| (*s).clone()).collect();
|
||||
remaining_args.shift();
|
||||
let sroot = filesearch::get_or_default_sysroot();
|
||||
let sroot = match supplied_sysroot {
|
||||
Some(getopts::Val(s)) => Path(s),
|
||||
_ => filesearch::get_or_default_sysroot()
|
||||
};
|
||||
|
||||
debug!("Using sysroot: %s", sroot.to_str());
|
||||
debug!("Will store workcache in %s", default_workspace().to_str());
|
||||
BuildContext {
|
||||
context: Context {
|
||||
use_rust_path_hack: use_rust_path_hack,
|
||||
sysroot: sroot, // Currently, only tests override this
|
||||
},
|
||||
cfgs: cfgs,
|
||||
rustc_flags: rustc_flags,
|
||||
use_rust_path_hack: use_rust_path_hack,
|
||||
sysroot: sroot, // Currently, only tests override this
|
||||
},
|
||||
workcache_context: api::default_context(default_workspace()).workcache_context
|
||||
}.run(*cmd, remaining_args)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// rustpkg unit tests
|
||||
|
||||
use context::{BuildContext, Context};
|
||||
use context::{BuildContext, Context, RustcFlags};
|
||||
use std::{io, libc, os, run, str, task};
|
||||
use extra::arc::Arc;
|
||||
use extra::arc::RWArc;
|
||||
@ -18,6 +18,7 @@ use extra::tempfile::mkdtemp;
|
||||
use extra::workcache;
|
||||
use extra::workcache::{Database, Logger};
|
||||
use extra::treemap::TreeMap;
|
||||
use extra::getopts::groups::getopts;
|
||||
use std::run::ProcessOutput;
|
||||
use installed_packages::list_installed_packages;
|
||||
use package_id::{PkgId};
|
||||
@ -27,8 +28,10 @@ use path_util::{target_executable_in_workspace, target_test_in_workspace,
|
||||
library_in_workspace, installed_library_in_workspace,
|
||||
built_bench_in_workspace, built_test_in_workspace,
|
||||
built_library_in_workspace, built_executable_in_workspace};
|
||||
use rustc::back::link::get_cc_prog;
|
||||
use rustc::metadata::filesearch::rust_path;
|
||||
use rustc::driver::driver::host_triple;
|
||||
use rustc::driver::driver::{build_session, build_session_options, host_triple, optgroups};
|
||||
use syntax::diagnostic;
|
||||
use target::*;
|
||||
use package_source::PkgSrc;
|
||||
|
||||
@ -45,6 +48,9 @@ fn fake_ctxt(sysroot: Path, workspace: &Path) -> BuildContext {
|
||||
BuildContext {
|
||||
workcache_context: context,
|
||||
context: Context {
|
||||
cfgs: ~[],
|
||||
rustc_flags: RustcFlags::default(),
|
||||
|
||||
use_rust_path_hack: false,
|
||||
sysroot: sysroot
|
||||
}
|
||||
@ -218,6 +224,10 @@ fn rustpkg_exec() -> Path {
|
||||
}
|
||||
|
||||
fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
|
||||
command_line_test_with_env(args, cwd, None).expect("Command line test failed")
|
||||
}
|
||||
|
||||
fn command_line_test_partial(args: &[~str], cwd: &Path) -> Option<ProcessOutput> {
|
||||
command_line_test_with_env(args, cwd, None)
|
||||
}
|
||||
|
||||
@ -225,7 +235,7 @@ fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
|
||||
/// invoked from) with the given arguments, in the given working directory.
|
||||
/// Returns the process's output.
|
||||
fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~str)]>)
|
||||
-> ProcessOutput {
|
||||
-> Option<ProcessOutput> {
|
||||
let cmd = rustpkg_exec().to_str();
|
||||
debug!("cd %s; %s %s",
|
||||
cwd.to_str(), cmd, args.connect(" "));
|
||||
@ -250,11 +260,14 @@ So tests that use this need to check the existence of a file
|
||||
to make sure the command succeeded
|
||||
*/
|
||||
if output.status != 0 {
|
||||
fail!("Command %s %? failed with exit code %?; its output was {{{ %s }}}",
|
||||
debug!("Command %s %? failed with exit code %?; its output was {{{ %s }}}",
|
||||
cmd, args, output.status,
|
||||
str::from_utf8(output.output) + str::from_utf8(output.error));
|
||||
None
|
||||
}
|
||||
else {
|
||||
Some(output)
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
fn create_local_package(pkgid: &PkgId) -> Path {
|
||||
@ -352,6 +365,27 @@ fn built_executable_exists(repo: &Path, short_name: &str) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn object_file_exists(repo: &Path, short_name: &str) -> bool {
|
||||
file_exists(repo, short_name, "o")
|
||||
}
|
||||
|
||||
fn assembly_file_exists(repo: &Path, short_name: &str) -> bool {
|
||||
file_exists(repo, short_name, "s")
|
||||
}
|
||||
|
||||
fn llvm_assembly_file_exists(repo: &Path, short_name: &str) -> bool {
|
||||
file_exists(repo, short_name, "ll")
|
||||
}
|
||||
|
||||
fn llvm_bitcode_file_exists(repo: &Path, short_name: &str) -> bool {
|
||||
file_exists(repo, short_name, "bc")
|
||||
}
|
||||
|
||||
fn file_exists(repo: &Path, short_name: &str, extension: &str) -> bool {
|
||||
os::path_exists(&repo.push_many([~"build", short_name.to_owned(),
|
||||
fmt!("%s.%s", short_name, extension)]))
|
||||
}
|
||||
|
||||
fn assert_built_library_exists(repo: &Path, short_name: &str) {
|
||||
assert!(built_library_exists(repo, short_name));
|
||||
}
|
||||
@ -377,7 +411,8 @@ fn command_line_test_output(args: &[~str]) -> ~[~str] {
|
||||
|
||||
fn command_line_test_output_with_env(args: &[~str], env: ~[(~str, ~str)]) -> ~[~str] {
|
||||
let mut result = ~[];
|
||||
let p_output = command_line_test_with_env(args, &os::getcwd(), Some(env));
|
||||
let p_output = command_line_test_with_env(args,
|
||||
&os::getcwd(), Some(env)).expect("Command-line test failed");
|
||||
let test_output = str::from_utf8(p_output.output);
|
||||
for s in test_output.split_iter('\n') {
|
||||
result.push(s.to_owned());
|
||||
@ -1264,6 +1299,256 @@ fn rust_path_install_target() {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sysroot_flag() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
// no-op sysroot setting; I'm not sure how else to test this
|
||||
command_line_test([~"--sysroot",
|
||||
test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert_built_executable_exists(&workspace, "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_flag_build() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"--no-link",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(object_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_flag_fail() {
|
||||
// --no-link shouldn't be accepted for install
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"install",
|
||||
~"--no-link",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn notrans_flag_build() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
let flags_to_test = [~"--no-trans", ~"--parse-only",
|
||||
~"--pretty", ~"-S"];
|
||||
|
||||
for flag in flags_to_test.iter() {
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"build",
|
||||
flag.clone(),
|
||||
~"foo"],
|
||||
&workspace);
|
||||
// Ideally we'd test that rustpkg actually succeeds, but
|
||||
// since task failure doesn't set the exit code properly,
|
||||
// we can't tell
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn notrans_flag_fail() {
|
||||
// --no-trans shouldn't be accepted for install
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
let flags_to_test = [~"--no-trans", ~"--parse-only",
|
||||
~"--pretty", ~"-S"];
|
||||
for flag in flags_to_test.iter() {
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"install",
|
||||
flag.clone(),
|
||||
~"foo"],
|
||||
&workspace);
|
||||
// Ideally we'd test that rustpkg actually fails, but
|
||||
// since task failure doesn't set the exit code properly,
|
||||
// we can't tell
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
assert!(!lib_exists(&workspace, "foo", NoVersion));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dash_S() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"-S",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
assert!(assembly_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dash_S_fail() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"install",
|
||||
~"-S",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
assert!(!assembly_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cfg_build() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
// If the cfg flag gets messed up, this won't compile
|
||||
writeFile(&workspace.push_many(["src", "foo-0.1", "main.rs"]),
|
||||
"#[cfg(quux)] fn main() {}");
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"--cfg",
|
||||
~"quux",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert_built_executable_exists(&workspace, "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cfg_fail() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
writeFile(&workspace.push_many(["src", "foo-0.1", "main.rs"]),
|
||||
"#[cfg(quux)] fn main() {}");
|
||||
assert!(command_line_test_partial([test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"foo"],
|
||||
&workspace).is_none());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_emit_llvm_S_build() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"-S", ~"--emit-llvm",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
assert!(llvm_assembly_file_exists(&workspace, "foo"));
|
||||
assert!(!assembly_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_emit_llvm_S_fail() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"install",
|
||||
~"-S", ~"--emit-llvm",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
assert!(!llvm_assembly_file_exists(&workspace, "foo"));
|
||||
assert!(!assembly_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_emit_llvm_build() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"--emit-llvm",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
assert!(llvm_bitcode_file_exists(&workspace, "foo"));
|
||||
assert!(!assembly_file_exists(&workspace, "foo"));
|
||||
assert!(!llvm_assembly_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_emit_llvm_fail() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"install",
|
||||
~"--emit-llvm",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(!built_executable_exists(&workspace, "foo"));
|
||||
assert!(!object_file_exists(&workspace, "foo"));
|
||||
assert!(!llvm_bitcode_file_exists(&workspace, "foo"));
|
||||
assert!(!llvm_assembly_file_exists(&workspace, "foo"));
|
||||
assert!(!assembly_file_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_linker_build() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
let matches = getopts([], optgroups());
|
||||
let options = build_session_options(@"rustpkg",
|
||||
matches.get_ref(),
|
||||
diagnostic::emit);
|
||||
let sess = build_session(options, diagnostic::emit);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"install",
|
||||
~"--linker",
|
||||
get_cc_prog(sess),
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert_executable_exists(&workspace, "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_install_flags_fail() {
|
||||
// The following flags can only be used with build or install:
|
||||
let forbidden = [~[~"--linker", ~"ld"],
|
||||
~[~"--link-args", ~"quux"],
|
||||
~[~"-O"],
|
||||
~[~"--opt-level", ~"2"],
|
||||
~[~"--save-temps"],
|
||||
~[~"--target", host_triple()],
|
||||
~[~"--target-cpu", ~"generic"],
|
||||
~[~"-Z", ~"--time-passes"]];
|
||||
for flag in forbidden.iter() {
|
||||
let output = command_line_test_output([test_sysroot().to_str(),
|
||||
~"list"] + *flag);
|
||||
assert!(output.len() > 1);
|
||||
assert!(output[1].find_str("can only be used with").is_some());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_optimized_build() {
|
||||
let p_id = PkgId::new("foo");
|
||||
let workspace = create_local_package(&p_id);
|
||||
command_line_test([test_sysroot().to_str(),
|
||||
~"build",
|
||||
~"-O",
|
||||
~"foo"],
|
||||
&workspace);
|
||||
assert!(built_executable_exists(&workspace, "foo"));
|
||||
}
|
||||
|
||||
/// Returns true if p exists and is executable
|
||||
fn is_executable(p: &Path) -> bool {
|
||||
|
@ -19,18 +19,34 @@ Where <cmd> is one of:
|
||||
Options:
|
||||
|
||||
-h, --help Display this message
|
||||
--sysroot PATH Override the system root
|
||||
<cmd> -h, <cmd> --help Display help for <cmd>");
|
||||
}
|
||||
|
||||
pub fn build() {
|
||||
io::println("rustpkg [options..] build [package-ID]
|
||||
io::println("rustpkg build [options..] [package-ID]
|
||||
|
||||
Build the given package ID if specified. With no package ID argument,
|
||||
build the package in the current directory. In that case, the current
|
||||
directory must be a direct child of an `src` directory in a workspace.
|
||||
|
||||
Options:
|
||||
-c, --cfg Pass a cfg flag to the package script");
|
||||
-c, --cfg Pass a cfg flag to the package script
|
||||
--no-link Compile and assemble, but don't link (like -c in rustc)
|
||||
--no-trans Parse and translate, but don't generate any code
|
||||
--pretty Pretty-print the code, but don't generate output
|
||||
--parse-only Parse the code, but don't typecheck or generate code
|
||||
-S Generate assembly code, but don't assemble or link it
|
||||
-S --emit-llvm Generate LLVM assembly code
|
||||
--emit-llvm Generate LLVM bitcode
|
||||
--linker PATH Use a linker other than the system linker
|
||||
--link-args [ARG..] Extra arguments to pass to the linker
|
||||
--opt-level=n Set the optimization level (0 <= n <= 3)
|
||||
-O Equivalent to --opt-level=2
|
||||
--save-temps Don't delete temporary files
|
||||
--target TRIPLE Set the target triple
|
||||
--target-cpu CPU Set the target CPU
|
||||
-Z FLAG Enable an experimental rustc feature (see `rustc --help`)");
|
||||
}
|
||||
|
||||
pub fn clean() {
|
||||
@ -63,7 +79,7 @@ List all installed packages.");
|
||||
}
|
||||
|
||||
pub fn install() {
|
||||
io::println("rustpkg [options..] install [package-ID]
|
||||
io::println("rustpkg install [options..] [package-ID]
|
||||
|
||||
Install the given package ID if specified. With no package ID
|
||||
argument, install the package in the current directory.
|
||||
@ -76,7 +92,16 @@ Examples:
|
||||
rustpkg install github.com/mozilla/servo#0.1.2
|
||||
|
||||
Options:
|
||||
-c, --cfg Pass a cfg flag to the package script");
|
||||
-c, --cfg Pass a cfg flag to the package script
|
||||
--emit-llvm Generate LLVM bitcode
|
||||
--linker PATH Use a linker other than the system linker
|
||||
--link-args [ARG..] Extra arguments to pass to the linker
|
||||
--opt-level=n Set the optimization level (0 <= n <= 3)
|
||||
-O Equivalent to --opt-level=2
|
||||
--save-temps Don't delete temporary files
|
||||
--target TRIPLE Set the target triple
|
||||
--target-cpu CPU Set the target CPU
|
||||
-Z FLAG Enable an experimental rustc feature (see `rustc --help`)");
|
||||
}
|
||||
|
||||
pub fn uninstall() {
|
||||
|
@ -17,9 +17,9 @@ use syntax::codemap::{dummy_sp, Spanned};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::{ast, attr, codemap, diagnostic, fold};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use rustc::back::link::output_type_exe;
|
||||
use rustc::back::link;
|
||||
use rustc::driver::session::{lib_crate, bin_crate};
|
||||
use context::{in_target, BuildContext};
|
||||
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};
|
||||
@ -153,7 +153,7 @@ pub fn ready_crate(sess: session::Session,
|
||||
@fold.fold_crate(crate)
|
||||
}
|
||||
|
||||
pub fn compile_input(ctxt: &BuildContext,
|
||||
pub fn compile_input(context: &BuildContext,
|
||||
exec: &mut workcache::Exec,
|
||||
pkg_id: &PkgId,
|
||||
in_file: &Path,
|
||||
@ -161,7 +161,7 @@ pub fn compile_input(ctxt: &BuildContext,
|
||||
flags: &[~str],
|
||||
cfgs: &[~str],
|
||||
opt: bool,
|
||||
what: OutputType) -> Path {
|
||||
what: OutputType) -> Option<Path> {
|
||||
assert!(in_file.components.len() > 1);
|
||||
let input = driver::file_input((*in_file).clone());
|
||||
debug!("compile_input: %s / %?", in_file.to_str(), what);
|
||||
@ -174,7 +174,7 @@ pub fn compile_input(ctxt: &BuildContext,
|
||||
|
||||
debug!("flags: %s", flags.connect(" "));
|
||||
debug!("cfgs: %s", cfgs.connect(" "));
|
||||
debug!("compile_input's sysroot = %s", ctxt.sysroot().to_str());
|
||||
debug!("compile_input's sysroot = %s", context.sysroot().to_str());
|
||||
|
||||
let crate_type = match what {
|
||||
Lib => lib_crate,
|
||||
@ -188,26 +188,38 @@ pub fn compile_input(ctxt: &BuildContext,
|
||||
Main => ~[]
|
||||
}
|
||||
+ flags
|
||||
+ context.flag_strs()
|
||||
+ cfgs.flat_map(|c| { ~[~"--cfg", (*c).clone()] }),
|
||||
driver::optgroups()).unwrap();
|
||||
debug!("rustc flags: %?", matches);
|
||||
|
||||
// Hack so that rustpkg can run either out of a rustc target dir,
|
||||
// or the host dir
|
||||
let sysroot_to_use = @if !in_target(&ctxt.sysroot()) {
|
||||
ctxt.sysroot()
|
||||
let sysroot_to_use = @if !in_target(&context.sysroot()) {
|
||||
context.sysroot()
|
||||
}
|
||||
else {
|
||||
ctxt.sysroot().pop().pop().pop()
|
||||
context.sysroot().pop().pop().pop()
|
||||
};
|
||||
debug!("compile_input's sysroot = %s", ctxt.sysroot().to_str());
|
||||
debug!("compile_input's sysroot = %s", context.sysroot().to_str());
|
||||
debug!("sysroot_to_use = %s", sysroot_to_use.to_str());
|
||||
|
||||
let output_type = match context.compile_upto() {
|
||||
Assemble => link::output_type_assembly,
|
||||
Link => link::output_type_object,
|
||||
Pretty | Trans | Analysis => link::output_type_none,
|
||||
LLVMAssemble => link::output_type_llvm_assembly,
|
||||
LLVMCompileBitcode => link::output_type_bitcode,
|
||||
Nothing => link::output_type_exe
|
||||
};
|
||||
|
||||
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 (~[out_dir.clone()]),
|
||||
// output_type should be conditional
|
||||
output_type: output_type_exe, // Use this to get a library? That's weird
|
||||
output_type: output_type,
|
||||
.. (*driver::build_session_options(binary, &matches, diagnostic::emit)).clone()
|
||||
};
|
||||
|
||||
@ -233,7 +245,7 @@ pub fn compile_input(ctxt: &BuildContext,
|
||||
|
||||
// Not really right. Should search other workspaces too, and the installed
|
||||
// database (which doesn't exist yet)
|
||||
find_and_install_dependencies(ctxt, sess, exec, workspace, crate,
|
||||
find_and_install_dependencies(context, sess, exec, workspace, crate,
|
||||
|p| {
|
||||
debug!("a dependency: %s", p.to_str());
|
||||
// Pass the directory containing a dependency
|
||||
@ -270,7 +282,7 @@ pub fn compile_input(ctxt: &BuildContext,
|
||||
|
||||
debug!("calling compile_crate_from_input, workspace = %s,
|
||||
building_library = %?", out_dir.to_str(), sess.building_library);
|
||||
compile_crate_from_input(in_file, exec, &out_dir, sess, crate)
|
||||
compile_crate_from_input(in_file, exec, context.compile_upto(), &out_dir, sess, crate)
|
||||
}
|
||||
|
||||
// Should use workcache to avoid recompiling when not necessary
|
||||
@ -280,10 +292,13 @@ pub fn compile_input(ctxt: &BuildContext,
|
||||
// also, too many arguments
|
||||
pub fn compile_crate_from_input(input: &Path,
|
||||
exec: &mut workcache::Exec,
|
||||
stop_before: StopBefore,
|
||||
// should be of the form <workspace>/build/<pkg id's path>
|
||||
out_dir: &Path,
|
||||
sess: session::Session,
|
||||
crate: @ast::Crate) -> Path {
|
||||
// Returns None if one of the flags that suppresses compilation output was
|
||||
// given
|
||||
crate: @ast::Crate) -> Option<Path> {
|
||||
debug!("Calling build_output_filenames with %s, building library? %?",
|
||||
out_dir.to_str(), sess.building_library);
|
||||
|
||||
@ -302,17 +317,21 @@ pub fn compile_crate_from_input(input: &Path,
|
||||
debug!("an additional library: %s", lib.to_str());
|
||||
}
|
||||
let analysis = driver::phase_3_run_analysis_passes(sess, crate);
|
||||
if driver::stop_after_phase_3(sess) { return None; }
|
||||
let translation = driver::phase_4_translate_to_llvm(sess, crate,
|
||||
&analysis,
|
||||
outputs);
|
||||
driver::phase_5_run_llvm_passes(sess, &translation, outputs);
|
||||
if driver::stop_after_phase_5(sess) { return outputs.out_filename; }
|
||||
// The second check shouldn't be necessary, but rustc seems to ignore
|
||||
// -c
|
||||
if driver::stop_after_phase_5(sess)
|
||||
|| stop_before == Link || stop_before == Assemble { return Some(outputs.out_filename); }
|
||||
driver::phase_6_link_output(sess, &translation, outputs);
|
||||
|
||||
// Register dependency on the source file
|
||||
exec.discover_input("file", input.to_str(), digest_file_with_date(input));
|
||||
|
||||
outputs.out_filename
|
||||
Some(outputs.out_filename)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@ -330,7 +349,7 @@ pub fn compile_crate(ctxt: &BuildContext,
|
||||
pkg_id: &PkgId,
|
||||
crate: &Path, workspace: &Path,
|
||||
flags: &[~str], cfgs: &[~str], opt: bool,
|
||||
what: OutputType) -> Path {
|
||||
what: OutputType) -> Option<Path> {
|
||||
debug!("compile_crate: crate=%s, workspace=%s", crate.to_str(), workspace.to_str());
|
||||
debug!("compile_crate: short_name = %s, flags =...", pkg_id.to_str());
|
||||
for fl in flags.iter() {
|
||||
@ -344,14 +363,13 @@ pub fn compile_crate(ctxt: &BuildContext,
|
||||
/// try to install their targets, failing if any target
|
||||
/// can't be found.
|
||||
pub fn find_and_install_dependencies(ctxt: &BuildContext,
|
||||
sess: session::Session,
|
||||
exec: &mut workcache::Exec,
|
||||
workspace: &Path,
|
||||
c: &ast::Crate,
|
||||
save: @fn(Path)
|
||||
) {
|
||||
debug!("Finding and installing dependencies...");
|
||||
do c.each_view_item |vi| {
|
||||
sess: session::Session,
|
||||
exec: &mut workcache::Exec,
|
||||
workspace: &Path,
|
||||
c: &ast::Crate,
|
||||
save: @fn(Path)
|
||||
) {
|
||||
do c.each_view_item() |vi: &ast::view_item| {
|
||||
debug!("A view item!");
|
||||
match vi.node {
|
||||
// ignore metadata, I guess
|
||||
|
Loading…
Reference in New Issue
Block a user