diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs deleted file mode 100644 index 349bbd0f4086f..0000000000000 --- a/src/librustpkg/api.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::*; -use util::{compile_crate, note}; - -/// A crate is a unit of Rust code to be compiled into a binary or library -pub struct Crate { - file: ~str, - flags: ~[~str], - cfgs: ~[~str] -} - -pub struct Listener { - cmds: ~[~str], - cb: fn~() -} - -pub fn run(listeners: ~[Listener]) { - let rcmd = os::args()[2]; - let mut found = false; - - for listeners.each |listener| { - for listener.cmds.each |&cmd| { - if cmd == rcmd { - (listener.cb)(); - - found = true; - - break; - } - } - } - - if !found { - os::set_exit_status(1); - } -} - -pub impl Crate { - fn flag(flag: ~str) -> Crate { - Crate { - flags: vec::append(copy self.flags, ~[flag]), - .. copy self - } - } - - fn flags(flags: ~[~str]) -> Crate { - Crate { - flags: vec::append(copy self.flags, flags), - .. copy self - } - } - - fn cfg(cfg: ~str) -> Crate { - Crate { - cfgs: vec::append(copy self.cfgs, ~[cfg]), - .. copy self - } - } - - fn cfgs(cfgs: ~[~str]) -> Crate { - Crate { - cfgs: vec::append(copy self.cfgs, cfgs), - .. copy self - } - } -} - -/// Create a crate target from a source file -pub fn Crate(file: ~str) -> Crate { - Crate { - file: file, - flags: ~[], - cfgs: ~[] - } -} - -/** - * Get the working directory of the package script. - * Assumes that the package script has been compiled - * in is the working directory. - */ -fn work_dir() -> Path { - os::self_exe_path().get() -} - -/** - * Get the source directory of the package (i.e. - * where the crates are located). Assumes - * that the cwd is changed to it before - * running this executable. - */ -fn src_dir() -> Path { - os::getcwd() -} - -pub fn args() -> ~[~str] { - let mut args = os::args(); - - args.shift(); - args.shift(); - - args -} - -/// Build a set of crates, should be called once -pub fn build(crates: ~[Crate]) -> bool { - let dir = src_dir(); - let work_dir = work_dir(); - let mut success = true; - let sysroot = Path(os::args()[1]); - - for crates.each |&crate| { - let path = &dir.push_rel(&Path(crate.file)).normalize(); - - note(fmt!("compiling %s", path.to_str())); - - success = compile_crate(Some(sysroot), path, &work_dir, crate.flags, crate.cfgs, - false, false); - - if !success { break; } - } - - if !success { - os::set_exit_status(2); - } - - success -} - -pub mod util { - // TODO: utilities for working with things like autotools -} diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index 76e6b5879426d..329c61f19187b 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -35,7 +35,6 @@ use rustc::driver::{driver, session}; use syntax::{ast, attr, codemap, diagnostic, parse, visit}; use semver::Version; -mod api; mod usage; mod util; @@ -223,7 +222,8 @@ impl PackageScript { } // Build the bootstrap and run a command - // TODO: Use JIT once it works, it should be faster + // FIXME: Use workcache to only compile the script when changed + // FIXME: Use JIT once it works, it should be faster fn run(cmd: ~str) -> int { let work_dir = self.work_dir(); let input = self.input; @@ -297,7 +297,7 @@ impl Ctx { } ~"install" => { self.install(if args.len() >= 1 { Some(args[0]) } - else { None }, + else { None }, if args.len() >= 2 { Some(args[1]) } else { None }, false); } @@ -370,7 +370,7 @@ impl Ctx { result::Err(err) => { util::error(err); - return None; + return None; } }; let work_dir = script.work_dir(); @@ -391,8 +391,9 @@ impl Ctx { if !success { - util::error(fmt!("building %s v%s failed: a dep wasn't installed", - script.name, script.vers.to_str())); + util::error( + fmt!("building %s v%s failed: a dep wasn't installed", + script.name, script.vers.to_str())); return None; } @@ -404,8 +405,9 @@ impl Ctx { os::change_dir(dir); if script.custom && script.run(~"build") != 0 { - util::error(fmt!("building %s v%s failed: custom build logic failed", - script.name, script.vers.to_str())); + util::error( + fmt!("building %s v%s failed: custom build logic failed", + script.name, script.vers.to_str())); return None; } @@ -424,14 +426,16 @@ impl Ctx { } if !success { - util::error(fmt!("building %s v%s failed: a crate failed to compile", - script.name, script.vers.to_str())); + util::error( + fmt!("building %s v%s failed: a crate failed to compile", + script.name, script.vers.to_str())); return None; } if verbose { - util::note(fmt!("built %s v%s", script.name, script.vers.to_str())); + util::note(fmt!("built %s v%s", script.name, + script.vers.to_str())); } Some(script) @@ -453,8 +457,8 @@ impl Ctx { }; let dir = script.work_dir(); - util::note(fmt!("cleaning %s v%s (%s)", script.name, script.vers.to_str(), - script.id)); + util::note(fmt!("cleaning %s v%s (%s)", script.name, + script.vers.to_str(), script.id)); if os::path_exists(&dir) { util::remove_dir_r(&dir); @@ -468,7 +472,7 @@ impl Ctx { } fn install(url: Option<~str>, target: Option<~str>, cache: bool) -> bool { - let mut success = true; + let mut success; let mut dir; if url.is_none() { @@ -544,8 +548,10 @@ impl Ctx { } fn fetch(dir: &Path, url: ~str, target: Option<~str>) -> bool { - let url = match url::from_str(if str::find_str(url, "://").is_none() { ~"http://" + url } - else { url }) { + let url = if str::find_str(url, "://").is_none() { + ~"http://" + url } + else { url }; + let url = match url::from_str(url) { result::Ok(url) => url, result::Err(err) => { util::error(fmt!("failed parsing %s", err.to_lower())); @@ -579,14 +585,19 @@ impl Ctx { let tar = dir.dir_path().push(&dir.file_path().to_str() + ~".tar"); - if run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", tar.to_str(), url]).status != 0 { + if run::program_output(~"curl", ~[~"-f", ~"-s", + ~"-o", tar.to_str(), + url]).status != 0 { util::error(~"fetching failed: downloading using curl failed"); return false; } - if run::program_output(~"tar", ~[~"-x", ~"--strip-components=1", ~"-C", dir.to_str(), ~"-f", tar.to_str()]).status != 0 { - util::error(~"fetching failed: extracting using tar failed (is it a valid tar archive?)"); + if run::program_output(~"tar", ~[~"-x", ~"--strip-components=1", + ~"-C", dir.to_str(), ~"-f", + tar.to_str()]).status != 0 { + util::error(~"fetching failed: extracting using tar failed" + + ~"(is it a valid tar archive?)"); return false; } @@ -600,7 +611,8 @@ impl Ctx { // Git can't clone into a non-empty directory util::remove_dir_r(dir); - if run::program_output(~"git", ~[~"clone", url, dir.to_str()]).status != 0 { + if run::program_output(~"git", ~[~"clone", url, + dir.to_str()]).status != 0 { util::error(~"fetching failed: can't clone repository"); return false; @@ -610,7 +622,9 @@ impl Ctx { let mut success = true; do util::temp_change_dir(dir) { - success = run::program_output(~"git", ~[~"checkout", target.get()]).status != 0 + success = run::program_output(~"git", + ~[~"checkout", + target.get()]).status != 0 } if !success { @@ -703,8 +717,8 @@ impl Ctx { } }; - util::note(fmt!("uninstalling %s v%s (%s)", name, package.vers.to_str(), - package.id)); + util::note(fmt!("uninstalling %s v%s (%s)", name, + package.vers.to_str(), package.id)); for vec::append(package.bins, package.libs).each |&file| { let path = Path(file); @@ -742,8 +756,8 @@ impl Ctx { } }; - util::note(fmt!("unpreferring %s v%s (%s)", name, package.vers.to_str(), - package.id)); + util::note(fmt!("unpreferring %s v%s (%s)", name, + package.vers.to_str(), package.id)); let bin_dir = util::root().push(~"bin"); @@ -815,8 +829,120 @@ pub fn main() { }.run(cmd, args); } -pub use Crate = api::Crate; -pub use build = api::build; -pub use util = api::util; -pub use Listener = api::Listener; -pub use run = api::run; + +/// A crate is a unit of Rust code to be compiled into a binary or library +pub struct Crate { + file: ~str, + flags: ~[~str], + cfgs: ~[~str] +} + +pub struct Listener { + cmds: ~[~str], + cb: fn~() +} + +pub fn run(listeners: ~[Listener]) { + let rcmd = os::args()[2]; + let mut found = false; + + for listeners.each |listener| { + for listener.cmds.each |&cmd| { + if cmd == rcmd { + (listener.cb)(); + + found = true; + + break; + } + } + } + + if !found { + os::set_exit_status(1); + } +} + +pub impl Crate { + pub fn flag(flag: ~str) -> Crate { + Crate { + flags: vec::append(copy self.flags, ~[flag]), + .. copy self + } + } + + pub fn flags(flags: ~[~str]) -> Crate { + Crate { + flags: vec::append(copy self.flags, flags), + .. copy self + } + } + + pub fn cfg(cfg: ~str) -> Crate { + Crate { + cfgs: vec::append(copy self.cfgs, ~[cfg]), + .. copy self + } + } + + pub fn cfgs(cfgs: ~[~str]) -> Crate { + Crate { + cfgs: vec::append(copy self.cfgs, cfgs), + .. copy self + } + } +} + +/// Create a crate target from a source file +pub fn Crate(file: ~str) -> Crate { + Crate { + file: file, + flags: ~[], + cfgs: ~[] + } +} + +/** + * Get the working directory of the package script. + * Assumes that the package script has been compiled + * in is the working directory. + */ +fn work_dir() -> Path { + os::self_exe_path().get() +} + +/** + * Get the source directory of the package (i.e. + * where the crates are located). Assumes + * that the cwd is changed to it before + * running this executable. + */ +fn src_dir() -> Path { + os::getcwd() +} + +/// Build a set of crates, should be called once +pub fn build(crates: ~[Crate]) -> bool { + let dir = src_dir(); + let work_dir = work_dir(); + let mut success = true; + let sysroot = Path(os::args()[1]); + + for crates.each |&crate| { + let path = &dir.push_rel(&Path(crate.file)).normalize(); + + util::note(fmt!("compiling %s", path.to_str())); + + success = util::compile_crate(Some(sysroot), path, &work_dir, + crate.flags, crate.cfgs, + false, false); + + if !success { break; } + } + + if !success { + os::set_exit_status(2); + } + + success +} diff --git a/src/librustpkg/usage.rs b/src/librustpkg/usage.rs index 18afcd38bae1c..94fa140e51eff 100644 --- a/src/librustpkg/usage.rs +++ b/src/librustpkg/usage.rs @@ -9,7 +9,7 @@ // except according to those terms. use core::io; - + pub fn general() { io::println(~"Usage: rustpkg [options] [args..] @@ -69,8 +69,8 @@ Options: pub fn uninstall() { io::println(~"rustpkg uninstall [@version] -Remove a package by id or name and optionally version. If the package(s) is/are depended -on by another package then they cannot be removed."); +Remove a package by id or name and optionally version. If the package(s) +is/are depended on by another package then they cannot be removed."); } pub fn prefer() { @@ -78,8 +78,8 @@ pub fn prefer() { By default all binaries are given a unique name so that multiple versions can coexist. The prefer command will symlink the uniquely named binary to -the binary directory under its bare name. If version is not supplied, the latest -version of the package will be preferred. +the binary directory under its bare name. If version is not supplied, the +latest version of the package will be preferred. Example: export PATH=$PATH:/home/user/.rustpkg/bin diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index c69e6921e06cc..f9ac1b59782a9 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -18,7 +18,7 @@ use codemap::span; use semver::Version; use std::{json, term, sort, getopts}; use getopts::groups::getopts; -use api::Listener; +use Listener; pub struct Package { id: ~str, @@ -47,9 +47,11 @@ pub fn parse_name(id: ~str) -> result::Result<~str, ~str> { for parts.each |&part| { for str::chars(part).each |&char| { if char::is_whitespace(char) { - return result::Err(~"could not parse id: contains whitespace"); + return result::Err( + ~"could not parse id: contains whitespace"); } else if char::is_uppercase(char) { - return result::Err(~"could not parse id: should be all lowercase"); + return result::Err( + ~"could not parse id: should be all lowercase"); } } } @@ -98,7 +100,7 @@ fn fold_mod(ctx: @ReadyCtx, m: ast::_mod, } } - fold::noop_fold_mod({ + fold::noop_fold_mod(ast::_mod { view_items: vec::append_one(m.view_items, mk_rustpkg_use(ctx)), items: do vec::map(m.items) |item| { strip_main(*item) @@ -116,7 +118,7 @@ fn fold_crate(ctx: @ReadyCtx, crate: ast::crate_, } } -fn fold_item(ctx: @ReadyCtx, &&item: @ast::item, +fn fold_item(ctx: @ReadyCtx, item: @ast::item, fold: fold::ast_fold) -> Option<@ast::item> { ctx.path.push(item.ident); @@ -177,7 +179,7 @@ fn mk_rustpkg_import(ctx: @ReadyCtx) -> @ast::view_item { fn add_pkg_module(ctx: @ReadyCtx, m: ast::_mod) -> ast::_mod { let listeners = mk_listeners(ctx); let main = mk_main(ctx); - let pkg_mod = @{ + let pkg_mod = @ast::_mod { view_items: ~[mk_rustpkg_import(ctx)], items: ~[main, listeners] }; @@ -193,7 +195,7 @@ fn add_pkg_module(ctx: @ReadyCtx, m: ast::_mod) -> ast::_mod { span: dummy_sp(), }; - { + ast::_mod { items: vec::append_one(/*bad*/copy m.items, item), .. m } @@ -228,7 +230,7 @@ fn path_node_global(ids: ~[ast::ident]) -> @ast::path { fn mk_listeners(ctx: @ReadyCtx) -> @ast::item { let ret_ty = mk_listener_vec_ty(ctx); - let decl = { + let decl = ast::fn_decl { inputs: ~[], output: ret_ty, cf: ast::return_val @@ -255,7 +257,7 @@ fn mk_path(ctx: @ReadyCtx, path: ~[ast::ident]) -> @ast::path { fn mk_listener_vec_ty(ctx: @ReadyCtx) -> @ast::Ty { let listener_ty_path = mk_path(ctx, ~[ctx.sess.ident_of(~"Listener")]); - let listener_ty = { + let listener_ty = ast::Ty { id: ctx.sess.next_node_id(), node: ast::ty_path(listener_ty_path, ctx.sess.next_node_id()), @@ -265,13 +267,13 @@ fn mk_listener_vec_ty(ctx: @ReadyCtx) -> @ast::Ty { ty: @listener_ty, mutbl: ast::m_imm }; - let inner_ty = @{ + let inner_ty = @ast::Ty { id: ctx.sess.next_node_id(), node: ast::ty_vec(vec_mt), span: dummy_sp() }; - @{ + @ast::Ty { id: ctx.sess.next_node_id(), node: ast::ty_uniq(ast::mt { ty: inner_ty, @@ -287,14 +289,14 @@ fn mk_listener_vec(ctx: @ReadyCtx) -> @ast::expr { let descs = do fns.map |listener| { mk_listener_rec(ctx, *listener) }; - let inner_expr = @{ + let inner_expr = @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_vec(descs, ast::m_imm), span: dummy_sp() }; - @{ + @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_vstore(inner_expr, ast::expr_vstore_uniq), @@ -306,27 +308,27 @@ fn mk_listener_rec(ctx: @ReadyCtx, listener: ListenerFn) -> @ast::expr { let span = listener.span; let path = /*bad*/copy listener.path; let descs = do listener.cmds.map |&cmd| { - let inner = @{ + let inner = @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_lit(@no_span(ast::lit_str(@cmd))), span: span }; - @{ + @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_vstore(inner, ast::expr_vstore_uniq), span: dummy_sp() } }; - let cmd_expr_inner = @{ + let cmd_expr_inner = @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_vec(descs, ast::m_imm), span: dummy_sp() }; - let cmd_expr = { + let cmd_expr = ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_vstore(cmd_expr_inner, ast::expr_vstore_uniq), @@ -339,7 +341,7 @@ fn mk_listener_rec(ctx: @ReadyCtx, listener: ListenerFn) -> @ast::expr { }); let cb_path = path_node_global(path); - let cb_expr = { + let cb_expr = ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_path(cb_path), @@ -356,7 +358,7 @@ fn mk_listener_rec(ctx: @ReadyCtx, listener: ListenerFn) -> @ast::expr { let listener_rec_ = ast::expr_struct(listener_path, ~[cmd_field, cb_field], option::None); - @{ + @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: listener_rec_, @@ -366,16 +368,17 @@ fn mk_listener_rec(ctx: @ReadyCtx, listener: ListenerFn) -> @ast::expr { fn mk_fn_wrapper(ctx: @ReadyCtx, fn_path_expr: ast::expr, span: span) -> @ast::expr { - let call_expr = { + let call_expr = ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_call(@fn_path_expr, ~[], false), span: span }; - let call_stmt = no_span(ast::stmt_semi(@call_expr, ctx.sess.next_node_id())); - let wrapper_decl = { + let call_stmt = no_span(ast::stmt_semi(@call_expr, + ctx.sess.next_node_id())); + let wrapper_decl = ast::fn_decl { inputs: ~[], - output: @{ + output: @ast::Ty { id: ctx.sess.next_node_id(), node: ast::ty_nil, span: span }, @@ -389,7 +392,7 @@ fn mk_fn_wrapper(ctx: @ReadyCtx, fn_path_expr: ast::expr, rules: ast::default_blk }); - @{ + @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: ast::expr_fn(ast::ProtoBare, wrapper_decl, @@ -399,12 +402,12 @@ fn mk_fn_wrapper(ctx: @ReadyCtx, fn_path_expr: ast::expr, } fn mk_main(ctx: @ReadyCtx) -> @ast::item { - let ret_ty = { + let ret_ty = ast::Ty { id: ctx.sess.next_node_id(), node: ast::ty_nil, span: dummy_sp() }; - let decl = { + let decl = ast::fn_decl { inputs: ~[], output: @ret_ty, cf: ast::return_val @@ -431,14 +434,14 @@ fn mk_main(ctx: @ReadyCtx) -> @ast::item { fn mk_run_call(ctx: @ReadyCtx) -> @ast::expr { let listener_path = path_node(~[ctx.sess.ident_of(~"listeners")]); let listener_path_expr_ = ast::expr_path(listener_path); - let listener_path_expr = { + let listener_path_expr = ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: listener_path_expr_, span: dummy_sp() }; let listener_call_expr_ = ast::expr_call(@listener_path_expr, ~[], false); - let listener_call_expr = { + let listener_call_expr = ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: listener_call_expr_, @@ -447,7 +450,7 @@ fn mk_run_call(ctx: @ReadyCtx) -> @ast::expr { let rustpkg_run_path = mk_path(ctx, ~[ctx.sess.ident_of(~"run")]); let rustpkg_run_path_expr_ = ast::expr_path(rustpkg_run_path); - let rustpkg_run_path_expr = { + let rustpkg_run_path_expr = ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: rustpkg_run_path_expr_, @@ -456,7 +459,7 @@ fn mk_run_call(ctx: @ReadyCtx) -> @ast::expr { let rustpkg_run_call_expr_ = ast::expr_call(@rustpkg_run_path_expr, ~[@listener_call_expr], false); - @{ + @ast::expr { id: ctx.sess.next_node_id(), callee_id: ctx.sess.next_node_id(), node: rustpkg_run_call_expr_, @@ -602,7 +605,7 @@ fn _add_pkg(packages: ~[json::Json], pkg: &Package) -> ~[json::Json] { match map.get(&~"vers") { json::String(str) => { - if pkg.vers.to_str() == str { + if has_id && pkg.vers.to_str() == str { return packages; } } @@ -644,8 +647,8 @@ fn _rm_pkg(packages: ~[json::Json], pkg: &Package) -> ~[json::Json] { match map.get(&~"vers") { json::String(str) => { - if pkg.vers.to_str() == str { None } - else { Some(package) } + if has_id && pkg.vers.to_str() == str { None } + else { Some(package) } } _ => { Some(package) } } @@ -673,21 +676,25 @@ pub fn load_pkgs() -> result::Result<~[json::Json], ~str> { _ => { os::remove_file(&db_lock); - return result::Err(~"package db's json is not a list"); + return result::Err( + ~"package db's json is not a list"); } } } result::Err(err) => { os::remove_file(&db_lock); - return result::Err(fmt!("failed to parse package db: %s", err.to_str())); + return result::Err( + fmt!("failed to parse package db: %s", + err.to_str())); } } } result::Err(err) => { os::remove_file(&db_lock); - return result::Err(fmt!("failed to read package db: %s", err)); + return result::Err(fmt!("failed to read package db: %s", + err)); } } } else { ~[] }; @@ -697,7 +704,8 @@ pub fn load_pkgs() -> result::Result<~[json::Json], ~str> { result::Ok(packages) } -pub fn get_pkg(id: ~str, vers: Option<~str>) -> result::Result { +pub fn get_pkg(id: ~str, + vers: Option<~str>) -> result::Result { let name = match parse_name(id) { result::Ok(name) => name, result::Err(err) => return result::Err(err) @@ -812,7 +820,8 @@ pub fn add_pkg(pkg: &Package) -> bool { match io::mk_file_writer(&db, ~[io::Create]) { result::Ok(writer) => { - writer.write_line(json::to_pretty_str(&json::List(_add_pkg(packages, pkg)))); + writer.write_line(json::to_pretty_str(&json::List( + _add_pkg(packages, pkg)))); } result::Err(err) => { error(fmt!("failed to dump package db: %s", err)); @@ -846,7 +855,8 @@ pub fn remove_pkg(pkg: &Package) -> bool { match io::mk_file_writer(&db, ~[io::Create]) { result::Ok(writer) => { - writer.write_line(json::to_pretty_str(&json::List(_rm_pkg(packages, pkg)))); + writer.write_line(json::to_pretty_str(&json::List( + _rm_pkg(packages, pkg)))); } result::Err(err) => { error(fmt!("failed to dump package db: %s", err)); @@ -868,14 +878,23 @@ pub fn compile_input(sysroot: Option, input: driver::input, dir: &Path, let test_dir = dir.push(~"test"); let binary = os::args()[0]; let matches = getopts(flags, driver::optgroups()).get(); - let mut options = driver::build_session_options(binary, matches, - diagnostic::emit); + let options = @{ + crate_type: session::unknown_crate, + optimize: if opt { session::Aggressive } else { session::No }, + test: test, + maybe_sysroot: sysroot, + .. *driver::build_session_options(binary, &matches, diagnostic::emit) + }; + let mut crate_cfg = options.cfg; - options.crate_type = session::unknown_crate; - options.optimize = if opt { session::Aggressive } else { session::No }; - options.test = test; - options.maybe_sysroot = sysroot; + for cfgs.each |&cfg| { + crate_cfg.push(attr::mk_word_item(cfg)); + } + let options = @{ + cfg: vec::append(options.cfg, crate_cfg), + .. *options + }; let sess = driver::build_session(options, diagnostic::emit); let cfg = driver::build_configuration(sess, binary, input); let mut outputs = driver::build_output_filenames(input, &None, &None, @@ -979,7 +998,8 @@ pub fn compile_input(sysroot: Option, input: driver::input, dir: &Path, let path = bin_dir.push(fmt!("%s-%s-%s%s", name, hash(name + uuid + vers), vers, exe_suffix())); - outputs = driver::build_output_filenames(input, &None, &Some(path), sess); + outputs = driver::build_output_filenames(input, &None, &Some(path), + sess); } else { need_dir(&lib_dir); @@ -1002,18 +1022,24 @@ pub fn exe_suffix() -> ~str { ~".exe" } #[cfg(target_os = "macos")] pub fn exe_suffix() -> ~str { ~"" } -pub fn compile_crate(sysroot: Option, crate: &Path, dir: &Path, flags: ~[~str], - cfgs: ~[~str], opt: bool, test: bool) -> bool { - compile_input(sysroot, driver::file_input(*crate), dir, flags, cfgs, opt, test) + +// FIXME: Use workcache to only compile when needed +pub fn compile_crate(sysroot: Option, crate: &Path, dir: &Path, + flags: ~[~str], cfgs: ~[~str], opt: bool, + test: bool) -> bool { + compile_input(sysroot, driver::file_input(*crate), dir, flags, cfgs, + opt, test) } -pub fn compile_str(sysroot: Option, code: ~str, dir: &Path, flags: ~[~str], - cfgs: ~[~str], opt: bool, test: bool) -> bool { - compile_input(sysroot, driver::str_input(code), dir, flags, cfgs, opt, test) +pub fn compile_str(sysroot: Option, code: ~str, dir: &Path, + flags: ~[~str], cfgs: ~[~str], opt: bool, + test: bool) -> bool { + compile_input(sysroot, driver::str_input(code), dir, flags, cfgs, + opt, test) } #[cfg(windows)] -pub fn link_exe(_src: &Path, _dest: &Path) -> bool{ +pub fn link_exe(_src: &Path, _dest: &Path) -> bool { /* FIXME: Investigate how to do this on win32 Node wraps symlinks by having a .bat, but that won't work with minGW. */