2013-02-28 13:15:32 +00:00
|
|
|
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
2013-01-14 20:55:47 +10:00
|
|
|
// 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.
|
|
|
|
|
2013-04-12 16:15:40 -07:00
|
|
|
// rustpkg - a package manager and build system for Rust
|
2013-01-14 20:55:47 +10:00
|
|
|
|
|
|
|
#[link(name = "rustpkg",
|
2013-09-26 18:18:42 -07:00
|
|
|
vers = "0.9-pre",
|
2013-01-14 20:55:47 +10:00
|
|
|
uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf",
|
|
|
|
url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
|
|
|
|
|
2013-03-01 08:41:31 -08:00
|
|
|
#[license = "MIT/ASL2"];
|
2013-01-14 20:55:47 +10:00
|
|
|
#[crate_type = "lib"];
|
|
|
|
|
2013-06-28 18:32:26 -04:00
|
|
|
extern mod extra;
|
2013-05-19 00:21:41 -04:00
|
|
|
extern mod rustc;
|
|
|
|
extern mod syntax;
|
2013-01-14 20:55:47 +10:00
|
|
|
|
2013-09-16 19:27:09 -07:00
|
|
|
use std::{io, os, result, run, str, task};
|
2013-06-28 18:32:26 -04:00
|
|
|
pub use std::path::Path;
|
|
|
|
|
2013-09-06 20:29:16 -07:00
|
|
|
use extra::workcache;
|
2013-01-18 18:31:43 +10:00
|
|
|
use rustc::driver::{driver, session};
|
2013-03-01 10:44:43 -08:00
|
|
|
use rustc::metadata::filesearch;
|
2013-07-31 13:47:32 -07:00
|
|
|
use rustc::metadata::filesearch::rust_path;
|
2013-05-24 19:35:29 -07:00
|
|
|
use extra::{getopts};
|
2013-03-26 16:38:07 -04:00
|
|
|
use syntax::{ast, diagnostic};
|
2013-04-17 13:53:34 -07:00
|
|
|
use util::*;
|
2013-09-10 23:25:31 -07:00
|
|
|
use messages::{error, warn, note};
|
2013-09-26 16:04:49 -07:00
|
|
|
use path_util::{build_pkg_id_in_workspace, built_test_in_workspace};
|
2013-07-31 13:47:32 -07:00
|
|
|
use path_util::{U_RWX, in_rust_path};
|
2013-07-09 18:28:00 -07:00
|
|
|
use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace};
|
2013-05-02 13:09:28 -07:00
|
|
|
use path_util::{target_executable_in_workspace, target_library_in_workspace};
|
2013-07-09 18:28:00 -07:00
|
|
|
use source_control::is_git_dir;
|
2013-08-22 19:18:38 -07:00
|
|
|
use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces, cwd_to_workspace};
|
2013-09-10 11:41:05 -07:00
|
|
|
use context::{Context, BuildContext,
|
|
|
|
RustcFlags, Trans, Link, Nothing, Pretty, Analysis, Assemble,
|
|
|
|
LLVMAssemble, LLVMCompileBitcode};
|
2013-05-27 17:45:16 -07:00
|
|
|
use package_id::PkgId;
|
2013-06-01 15:59:12 -07:00
|
|
|
use package_source::PkgSrc;
|
2013-09-26 16:04:49 -07:00
|
|
|
use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench, Tests};
|
2013-09-16 19:27:09 -07:00
|
|
|
// use workcache_support::{discover_outputs, digest_only_date};
|
|
|
|
use workcache_support::digest_only_date;
|
2013-09-17 18:23:34 -07:00
|
|
|
use exit_codes::COPY_FAILED_CODE;
|
2013-01-14 20:55:47 +10:00
|
|
|
|
2013-06-25 22:26:22 -07:00
|
|
|
pub mod api;
|
2013-04-12 16:15:40 -07:00
|
|
|
mod conditions;
|
2013-04-24 17:37:59 -07:00
|
|
|
mod context;
|
2013-06-01 15:59:12 -07:00
|
|
|
mod crate;
|
2013-09-16 19:27:09 -07:00
|
|
|
mod exit_codes;
|
2013-07-11 18:20:31 -07:00
|
|
|
mod installed_packages;
|
2013-06-14 18:16:24 -07:00
|
|
|
mod messages;
|
2013-05-27 17:45:16 -07:00
|
|
|
mod package_id;
|
2013-06-01 15:59:12 -07:00
|
|
|
mod package_source;
|
2013-04-12 16:15:40 -07:00
|
|
|
mod path_util;
|
2013-05-27 17:45:16 -07:00
|
|
|
mod search;
|
2013-07-09 18:28:00 -07:00
|
|
|
mod source_control;
|
2013-05-27 17:45:16 -07:00
|
|
|
mod target;
|
2013-05-12 16:50:57 -04:00
|
|
|
#[cfg(test)]
|
2013-04-24 17:37:59 -07:00
|
|
|
mod tests;
|
2013-01-15 23:57:03 +10:00
|
|
|
mod util;
|
2013-05-30 12:03:21 -07:00
|
|
|
mod version;
|
2013-09-06 20:29:16 -07:00
|
|
|
pub mod workcache_support;
|
2013-04-24 17:37:59 -07:00
|
|
|
mod workspace;
|
2013-01-15 23:57:03 +10:00
|
|
|
|
2013-05-12 17:48:01 -04:00
|
|
|
pub mod usage;
|
|
|
|
|
2013-04-11 17:43:02 -07:00
|
|
|
/// A PkgScript represents user-supplied custom logic for
|
|
|
|
/// special build hooks. This only exists for packages with
|
|
|
|
/// an explicit package script.
|
2013-05-11 22:45:13 -04:00
|
|
|
struct PkgScript<'self> {
|
2013-04-11 17:43:02 -07:00
|
|
|
/// Uniquely identifies this package
|
2013-05-11 22:45:13 -04:00
|
|
|
id: &'self PkgId,
|
2013-09-06 20:29:16 -07:00
|
|
|
/// File path for the package script
|
|
|
|
input: Path,
|
2013-04-11 17:43:02 -07:00
|
|
|
/// The session to use *only* for compiling the custom
|
|
|
|
/// build script
|
2013-01-23 11:19:13 +10:00
|
|
|
sess: session::Session,
|
2013-04-11 17:43:02 -07:00
|
|
|
/// The config for compiling the custom build script
|
2013-07-19 07:38:55 +02:00
|
|
|
cfg: ast::CrateConfig,
|
2013-04-11 17:43:02 -07:00
|
|
|
/// The crate for the custom build script
|
2013-09-27 19:46:09 -07:00
|
|
|
crate: Option<ast::Crate>,
|
2013-04-11 17:43:02 -07:00
|
|
|
/// Directory in which to store build output
|
|
|
|
build_dir: Path
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
|
2013-05-11 22:45:13 -04:00
|
|
|
impl<'self> PkgScript<'self> {
|
2013-04-11 17:43:02 -07:00
|
|
|
/// Given the path name for a package script
|
|
|
|
/// and a package ID, parse the package script into
|
|
|
|
/// a PkgScript that we can then execute
|
2013-08-15 18:36:39 -07:00
|
|
|
fn parse<'a>(sysroot: @Path,
|
|
|
|
script: Path,
|
|
|
|
workspace: &Path,
|
|
|
|
id: &'a PkgId) -> PkgScript<'a> {
|
2013-04-11 17:43:02 -07:00
|
|
|
// Get the executable name that was invoked
|
2013-06-13 03:02:55 +10:00
|
|
|
let binary = os::args()[0].to_managed();
|
2013-04-11 17:43:02 -07:00
|
|
|
// Build the rustc session data structures to pass
|
|
|
|
// to the compiler
|
2013-08-15 18:36:39 -07:00
|
|
|
debug!("pkgscript parse: %s", sysroot.to_str());
|
2013-02-19 00:01:03 -08:00
|
|
|
let options = @session::options {
|
2013-05-11 22:45:13 -04:00
|
|
|
binary: binary,
|
2013-08-15 18:36:39 -07:00
|
|
|
maybe_sysroot: Some(sysroot),
|
2013-01-23 11:19:13 +10:00
|
|
|
crate_type: session::bin_crate,
|
2013-07-02 12:47:32 -07:00
|
|
|
.. (*session::basic_options()).clone()
|
2013-01-23 11:19:13 +10:00
|
|
|
};
|
2013-09-06 20:29:16 -07:00
|
|
|
let input = driver::file_input(script.clone());
|
2013-08-30 10:55:24 -07:00
|
|
|
let sess = driver::build_session(options,
|
|
|
|
@diagnostic::DefaultEmitter as
|
|
|
|
@diagnostic::Emitter);
|
2013-08-13 17:06:27 -07:00
|
|
|
let cfg = driver::build_configuration(sess);
|
2013-07-26 23:49:38 -07:00
|
|
|
let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
|
|
|
|
let crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
|
2013-04-22 17:54:54 -07:00
|
|
|
let work_dir = build_pkg_id_in_workspace(id, workspace);
|
2013-01-16 21:59:37 +10:00
|
|
|
|
2013-08-15 18:36:39 -07:00
|
|
|
debug!("Returning package script with id %s", id.to_str());
|
2013-01-16 21:59:37 +10:00
|
|
|
|
2013-04-11 17:43:02 -07:00
|
|
|
PkgScript {
|
2013-01-16 21:59:37 +10:00
|
|
|
id: id,
|
2013-09-06 20:29:16 -07:00
|
|
|
input: script,
|
2013-01-23 11:19:13 +10:00
|
|
|
sess: sess,
|
|
|
|
cfg: cfg,
|
2013-09-27 19:46:09 -07:00
|
|
|
crate: Some(crate),
|
2013-04-11 17:43:02 -07:00
|
|
|
build_dir: work_dir
|
|
|
|
}
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
|
2013-04-11 17:43:02 -07:00
|
|
|
/// 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
|
2013-09-27 19:46:09 -07:00
|
|
|
fn run_custom(&mut self, exec: &mut workcache::Exec,
|
|
|
|
sysroot: &Path) -> (~[~str], ExitCode) {
|
2013-01-23 11:19:13 +10:00
|
|
|
let sess = self.sess;
|
2013-04-11 17:43:02 -07:00
|
|
|
|
|
|
|
debug!("Working directory = %s", self.build_dir.to_str());
|
|
|
|
// Collect together any user-defined commands in the package script
|
2013-09-27 19:46:09 -07:00
|
|
|
let crate = util::ready_crate(sess, self.crate.take_unwrap());
|
2013-04-11 17:43:02 -07:00
|
|
|
debug!("Building output filenames with script name %s",
|
2013-09-06 20:29:16 -07:00
|
|
|
driver::source_name(&driver::file_input(self.input.clone())));
|
2013-07-31 13:47:32 -07:00
|
|
|
let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
|
|
|
|
util::compile_crate_from_input(&self.input,
|
2013-09-06 20:29:16 -07:00
|
|
|
exec,
|
2013-09-10 11:41:05 -07:00
|
|
|
Nothing,
|
2013-07-31 13:47:32 -07:00
|
|
|
&self.build_dir,
|
|
|
|
sess,
|
|
|
|
crate);
|
2013-08-15 18:36:39 -07:00
|
|
|
debug!("Running program: %s %s %s", exe.to_str(),
|
|
|
|
sysroot.to_str(), "install");
|
2013-09-06 20:29:16 -07:00
|
|
|
// Discover the output
|
|
|
|
exec.discover_output("binary", exe.to_str(), digest_only_date(&exe));
|
2013-07-31 13:47:32 -07:00
|
|
|
// FIXME #7401 should support commands besides `install`
|
|
|
|
let status = run::process_status(exe.to_str(), [sysroot.to_str(), ~"install"]);
|
|
|
|
if status != 0 {
|
|
|
|
return (~[], status);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
debug!("Running program (configs): %s %s %s",
|
2013-08-15 18:36:39 -07:00
|
|
|
exe.to_str(), sysroot.to_str(), "configs");
|
|
|
|
let output = run::process_output(exe.to_str(), [sysroot.to_str(), ~"configs"]);
|
2013-07-31 13:47:32 -07:00
|
|
|
// Run the configs() function to get the configs
|
2013-09-05 14:17:24 +02:00
|
|
|
let cfgs = str::from_utf8_slice(output.output).word_iter()
|
2013-08-09 20:09:47 -07:00
|
|
|
.map(|w| w.to_owned()).collect();
|
2013-07-31 13:47:32 -07:00
|
|
|
(cfgs, output.status)
|
2013-04-11 17:43:02 -07:00
|
|
|
}
|
2013-01-23 11:19:13 +10:00
|
|
|
}
|
|
|
|
|
2013-02-04 17:12:31 -08:00
|
|
|
fn hash(&self) -> ~str {
|
2013-04-11 17:43:02 -07:00
|
|
|
self.id.hash()
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-14 18:21:47 -07:00
|
|
|
pub trait CtxMethods {
|
|
|
|
fn run(&self, cmd: &str, args: ~[~str]);
|
|
|
|
fn do_cmd(&self, _cmd: &str, _pkgname: &str);
|
2013-09-26 16:04:49 -07:00
|
|
|
/// Returns a pair of the selected package ID, and the destination workspace
|
|
|
|
fn build_args(&self, args: ~[~str], what: &WhatToBuild) -> Option<(PkgId, Path)>;
|
2013-08-28 14:52:37 -07:00
|
|
|
/// Returns the destination workspace
|
2013-09-16 19:27:09 -07:00
|
|
|
fn build(&self, pkg_src: &mut PkgSrc, what: &WhatToBuild) -> Path;
|
2013-06-14 18:21:47 -07:00
|
|
|
fn clean(&self, workspace: &Path, id: &PkgId);
|
|
|
|
fn info(&self);
|
2013-09-08 22:00:49 -07:00
|
|
|
/// Returns a pair. First component is a list of installed paths,
|
|
|
|
/// second is a list of declared and discovered inputs
|
2013-09-16 19:27:09 -07:00
|
|
|
fn install(&self, src: PkgSrc, what: &WhatToBuild) -> (~[Path], ~[(~str, ~str)]);
|
2013-09-06 20:29:16 -07:00
|
|
|
/// Returns a list of installed files
|
2013-09-12 16:13:30 -07:00
|
|
|
fn install_no_build(&self,
|
|
|
|
source_workspace: &Path,
|
|
|
|
target_workspace: &Path,
|
2013-09-16 19:27:09 -07:00
|
|
|
id: &PkgId) -> ~[~str];
|
2013-06-14 18:21:47 -07:00
|
|
|
fn prefer(&self, _id: &str, _vers: Option<~str>);
|
2013-09-26 16:04:49 -07:00
|
|
|
fn test(&self, id: &PkgId, workspace: &Path);
|
2013-06-14 18:21:47 -07:00
|
|
|
fn uninstall(&self, _id: &str, _vers: Option<~str>);
|
|
|
|
fn unprefer(&self, _id: &str, _vers: Option<~str>);
|
2013-09-16 14:59:34 -07:00
|
|
|
fn init(&self);
|
2013-06-14 18:21:47 -07:00
|
|
|
}
|
|
|
|
|
2013-09-08 22:00:49 -07:00
|
|
|
impl CtxMethods for BuildContext {
|
2013-09-26 16:04:49 -07:00
|
|
|
fn build_args(&self, args: ~[~str], what: &WhatToBuild) -> Option<(PkgId, Path)> {
|
|
|
|
if args.len() < 1 {
|
|
|
|
match cwd_to_workspace() {
|
|
|
|
None if self.context.use_rust_path_hack => {
|
|
|
|
let cwd = os::getcwd();
|
|
|
|
let pkgid = PkgId::new(cwd.components[cwd.components.len() - 1]);
|
|
|
|
let mut pkg_src = PkgSrc::new(cwd, true, pkgid);
|
|
|
|
let dest_ws = self.build(&mut pkg_src, what);
|
|
|
|
Some((pkg_src.id, dest_ws))
|
|
|
|
}
|
|
|
|
None => { usage::build(); None }
|
|
|
|
Some((ws, pkgid)) => {
|
|
|
|
let mut pkg_src = PkgSrc::new(ws, false, pkgid);
|
|
|
|
let dest_ws = self.build(&mut pkg_src, what);
|
|
|
|
Some((pkg_src.id, dest_ws))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// The package id is presumed to be the first command-line
|
|
|
|
// argument
|
|
|
|
let pkgid = PkgId::new(args[0].clone());
|
|
|
|
let mut dest_ws = None;
|
|
|
|
do each_pkg_parent_workspace(&self.context, &pkgid) |workspace| {
|
|
|
|
debug!("found pkg %s in workspace %s, trying to build",
|
|
|
|
pkgid.to_str(), workspace.to_str());
|
|
|
|
let mut pkg_src = PkgSrc::new(workspace.clone(), false, pkgid.clone());
|
|
|
|
dest_ws = Some(self.build(&mut pkg_src, what));
|
|
|
|
true
|
|
|
|
};
|
|
|
|
assert!(dest_ws.is_some());
|
|
|
|
// n.b. If this builds multiple packages, it only returns the workspace for
|
|
|
|
// the last one. The whole building-multiple-packages-with-the-same-ID is weird
|
|
|
|
// anyway and there are no tests for it, so maybe take it out
|
|
|
|
Some((pkgid, dest_ws.unwrap()))
|
|
|
|
}
|
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
fn run(&self, cmd: &str, args: ~[~str]) {
|
2013-01-17 19:05:19 +10:00
|
|
|
match cmd {
|
2013-05-27 17:45:16 -07:00
|
|
|
"build" => {
|
2013-09-26 16:04:49 -07:00
|
|
|
self.build_args(args, &Everything);
|
2013-01-23 11:19:13 +10:00
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"clean" => {
|
2013-04-17 15:47:24 -07:00
|
|
|
if args.len() < 1 {
|
2013-08-22 19:18:38 -07:00
|
|
|
match cwd_to_workspace() {
|
|
|
|
None => { usage::clean(); return }
|
|
|
|
// tjc: Maybe clean should clean all the packages in the
|
|
|
|
// current workspace, though?
|
|
|
|
Some((ws, pkgid)) => self.clean(&ws, &pkgid)
|
2013-06-26 17:42:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// The package id is presumed to be the first command-line
|
|
|
|
// argument
|
2013-07-31 13:47:32 -07:00
|
|
|
let pkgid = PkgId::new(args[0].clone());
|
2013-06-26 17:42:24 -07:00
|
|
|
let cwd = os::getcwd();
|
|
|
|
self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd
|
2013-04-17 15:47:24 -07:00
|
|
|
}
|
2013-01-23 11:19:13 +10:00
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"do" => {
|
2013-04-11 17:43:02 -07:00
|
|
|
if args.len() < 2 {
|
2013-01-23 12:41:11 +10:00
|
|
|
return usage::do_cmd();
|
|
|
|
}
|
|
|
|
|
2013-07-02 12:47:32 -07:00
|
|
|
self.do_cmd(args[0].clone(), args[1].clone());
|
2013-01-23 12:41:11 +10:00
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"info" => {
|
2013-01-26 18:35:10 +10:00
|
|
|
self.info();
|
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"install" => {
|
2013-09-06 20:29:16 -07:00
|
|
|
if args.len() < 1 {
|
2013-08-22 19:18:38 -07:00
|
|
|
match cwd_to_workspace() {
|
2013-09-08 22:00:49 -07:00
|
|
|
None if self.context.use_rust_path_hack => {
|
2013-08-28 14:52:37 -07:00
|
|
|
let cwd = os::getcwd();
|
2013-09-06 20:29:16 -07:00
|
|
|
let inferred_pkgid =
|
|
|
|
PkgId::new(cwd.components[cwd.components.len() - 1]);
|
2013-09-16 19:27:09 -07:00
|
|
|
self.install(PkgSrc::new(cwd, true, inferred_pkgid), &Everything);
|
2013-08-28 14:52:37 -07:00
|
|
|
}
|
|
|
|
None => { usage::install(); return; }
|
2013-09-06 20:29:16 -07:00
|
|
|
Some((ws, pkgid)) => {
|
|
|
|
let pkg_src = PkgSrc::new(ws, false, pkgid);
|
2013-09-16 19:27:09 -07:00
|
|
|
self.install(pkg_src, &Everything);
|
2013-09-06 20:29:16 -07:00
|
|
|
}
|
|
|
|
}
|
2013-06-14 18:16:24 -07:00
|
|
|
}
|
|
|
|
else {
|
2013-06-26 17:42:24 -07:00
|
|
|
// The package id is presumed to be the first command-line
|
|
|
|
// argument
|
2013-07-31 13:47:32 -07:00
|
|
|
let pkgid = PkgId::new(args[0]);
|
2013-09-08 22:00:49 -07:00
|
|
|
let workspaces = pkg_parent_workspaces(&self.context, &pkgid);
|
2013-08-23 11:51:45 -07:00
|
|
|
debug!("package ID = %s, found it in %? workspaces",
|
|
|
|
pkgid.to_str(), workspaces.len());
|
2013-06-26 17:42:24 -07:00
|
|
|
if workspaces.is_empty() {
|
|
|
|
let rp = rust_path();
|
|
|
|
assert!(!rp.is_empty());
|
2013-09-06 20:29:16 -07:00
|
|
|
let src = PkgSrc::new(rp[0].clone(), false, pkgid.clone());
|
2013-09-16 19:27:09 -07:00
|
|
|
self.install(src, &Everything);
|
2013-06-26 17:42:24 -07:00
|
|
|
}
|
|
|
|
else {
|
2013-09-06 20:29:16 -07:00
|
|
|
for workspace in workspaces.iter() {
|
|
|
|
let src = PkgSrc::new(workspace.clone(),
|
2013-09-08 22:00:49 -07:00
|
|
|
self.context.use_rust_path_hack,
|
2013-09-06 20:29:16 -07:00
|
|
|
pkgid.clone());
|
2013-09-16 19:27:09 -07:00
|
|
|
self.install(src, &Everything);
|
2013-08-02 02:17:20 -04:00
|
|
|
};
|
2013-06-14 18:16:24 -07:00
|
|
|
}
|
2013-04-24 17:37:59 -07:00
|
|
|
}
|
2013-01-18 18:31:43 +10:00
|
|
|
}
|
2013-07-11 18:20:31 -07:00
|
|
|
"list" => {
|
|
|
|
io::println("Installed packages:");
|
2013-08-02 02:17:20 -04:00
|
|
|
do installed_packages::list_installed_packages |pkg_id| {
|
2013-08-02 16:59:58 -07:00
|
|
|
println(pkg_id.path.to_str());
|
2013-08-02 02:17:20 -04:00
|
|
|
true
|
|
|
|
};
|
2013-07-11 18:20:31 -07:00
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"prefer" => {
|
2013-01-18 18:31:43 +10:00
|
|
|
if args.len() < 1 {
|
|
|
|
return usage::uninstall();
|
|
|
|
}
|
|
|
|
|
2013-05-14 17:46:52 -07:00
|
|
|
self.prefer(args[0], None);
|
2013-01-23 11:19:13 +10:00
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"test" => {
|
2013-09-26 16:04:49 -07:00
|
|
|
// Build the test executable
|
|
|
|
let maybe_id_and_workspace = self.build_args(args, &Tests);
|
|
|
|
match maybe_id_and_workspace {
|
|
|
|
Some((pkg_id, workspace)) => {
|
|
|
|
// Assuming it's built, run the tests
|
|
|
|
self.test(&pkg_id, &workspace);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
error("Testing failed because building the specified package failed.");
|
|
|
|
}
|
|
|
|
}
|
2013-01-18 18:31:43 +10:00
|
|
|
}
|
2013-09-16 14:59:34 -07:00
|
|
|
"init" => {
|
|
|
|
if args.len() != 0 {
|
|
|
|
return usage::init();
|
|
|
|
} else {
|
|
|
|
self.init();
|
|
|
|
}
|
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"uninstall" => {
|
2013-01-18 18:31:43 +10:00
|
|
|
if args.len() < 1 {
|
|
|
|
return usage::uninstall();
|
|
|
|
}
|
|
|
|
|
2013-07-31 13:47:32 -07:00
|
|
|
let pkgid = PkgId::new(args[0]);
|
2013-07-11 18:20:31 -07:00
|
|
|
if !installed_packages::package_is_installed(&pkgid) {
|
|
|
|
warn(fmt!("Package %s doesn't seem to be installed! Doing nothing.", args[0]));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
let rp = rust_path();
|
|
|
|
assert!(!rp.is_empty());
|
2013-09-08 22:00:49 -07:00
|
|
|
do each_pkg_parent_workspace(&self.context, &pkgid) |workspace| {
|
2013-07-11 18:20:31 -07:00
|
|
|
path_util::uninstall_package_from(workspace, &pkgid);
|
|
|
|
note(fmt!("Uninstalled package %s (was installed in %s)",
|
|
|
|
pkgid.to_str(), workspace.to_str()));
|
2013-08-02 02:17:20 -04:00
|
|
|
true
|
|
|
|
};
|
2013-07-11 18:20:31 -07:00
|
|
|
}
|
2013-01-18 18:31:43 +10:00
|
|
|
}
|
2013-05-27 17:45:16 -07:00
|
|
|
"unprefer" => {
|
2013-01-18 18:31:43 +10:00
|
|
|
if args.len() < 1 {
|
2013-07-11 18:20:31 -07:00
|
|
|
return usage::unprefer();
|
2013-01-18 18:31:43 +10:00
|
|
|
}
|
|
|
|
|
2013-05-14 17:46:52 -07:00
|
|
|
self.unprefer(args[0], None);
|
2013-01-18 18:31:43 +10:00
|
|
|
}
|
2013-05-14 17:46:52 -07:00
|
|
|
_ => fail!(fmt!("I don't know the command `%s`", cmd))
|
2013-01-23 11:19:13 +10:00
|
|
|
}
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
|
2013-05-11 22:45:13 -04:00
|
|
|
fn do_cmd(&self, _cmd: &str, _pkgname: &str) {
|
2013-04-22 17:54:54 -07:00
|
|
|
// stub
|
2013-05-06 00:18:51 +02:00
|
|
|
fail!("`do` not yet implemented");
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
|
2013-08-28 14:52:37 -07:00
|
|
|
/// Returns the destination workspace
|
|
|
|
/// In the case of a custom build, we don't know, so we just return the source workspace
|
2013-09-16 19:27:09 -07:00
|
|
|
/// what_to_build says: "Just build the lib.rs file in one subdirectory,
|
|
|
|
/// don't walk anything recursively." Or else, everything.
|
|
|
|
fn build(&self, pkg_src: &mut PkgSrc, what_to_build: &WhatToBuild) -> Path {
|
2013-09-06 20:29:16 -07:00
|
|
|
let workspace = pkg_src.workspace.clone();
|
|
|
|
let pkgid = pkg_src.id.clone();
|
|
|
|
|
2013-07-09 18:28:00 -07:00
|
|
|
debug!("build: workspace = %s (in Rust path? %? is git dir? %? \
|
2013-09-06 20:29:16 -07:00
|
|
|
pkgid = %s pkgsrc start_dir = %s", workspace.to_str(),
|
|
|
|
in_rust_path(&workspace), is_git_dir(&workspace.push_rel(&pkgid.path)),
|
|
|
|
pkgid.to_str(), pkg_src.start_dir.to_str());
|
2013-05-02 13:09:28 -07:00
|
|
|
|
2013-07-09 18:28:00 -07:00
|
|
|
// 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
|
2013-09-06 20:29:16 -07:00
|
|
|
if !in_rust_path(&workspace) && is_git_dir(&workspace.push_rel(&pkgid.path)) {
|
2013-08-02 16:59:58 -07:00
|
|
|
let out_dir = default_workspace().push("src").push_rel(&pkgid.path);
|
|
|
|
source_control::git_clone(&workspace.push_rel(&pkgid.path),
|
2013-07-09 18:28:00 -07:00
|
|
|
&out_dir, &pkgid.version);
|
|
|
|
let default_ws = default_workspace();
|
|
|
|
debug!("Calling build recursively with %? and %?", default_ws.to_str(),
|
|
|
|
pkgid.to_str());
|
2013-09-16 19:27:09 -07:00
|
|
|
return self.build(&mut PkgSrc::new(default_ws, false, pkgid.clone()), what_to_build);
|
2013-07-09 18:28:00 -07:00
|
|
|
}
|
|
|
|
|
2013-05-02 13:09:28 -07:00
|
|
|
// Is there custom build logic? If so, use it
|
|
|
|
let mut custom = false;
|
2013-09-06 20:29:16 -07:00
|
|
|
debug!("Package source directory = %s", 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() {
|
2013-05-02 13:09:28 -07:00
|
|
|
Some(package_script_path) => {
|
2013-09-06 20:29:16 -07:00
|
|
|
let sysroot = self.sysroot_to_use();
|
2013-09-16 19:27:09 -07:00
|
|
|
let (cfgs, hook_result) =
|
|
|
|
do self.workcache_context.with_prep(package_script_path.to_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);
|
|
|
|
do prep.exec |exec| {
|
2013-09-27 19:46:09 -07:00
|
|
|
let mut pscript = PkgScript::parse(@sub_sysroot.clone(),
|
|
|
|
package_script_path_clone.clone(),
|
|
|
|
&sub_ws,
|
|
|
|
&sub_id);
|
2013-09-16 19:27:09 -07:00
|
|
|
|
|
|
|
pscript.run_custom(exec, &sub_sysroot)
|
|
|
|
}
|
2013-09-06 20:29:16 -07:00
|
|
|
};
|
2013-05-02 13:09:28 -07:00
|
|
|
debug!("Command return code = %?", hook_result);
|
|
|
|
if hook_result != 0 {
|
2013-05-06 00:18:51 +02:00
|
|
|
fail!("Error running custom build command")
|
2013-05-02 13:09:28 -07:00
|
|
|
}
|
|
|
|
custom = true;
|
|
|
|
// otherwise, the package script succeeded
|
|
|
|
cfgs
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
debug!("No package script, continuing");
|
|
|
|
~[]
|
|
|
|
}
|
2013-09-10 11:41:05 -07:00
|
|
|
} + self.context.cfgs;
|
2013-05-02 13:09:28 -07:00
|
|
|
|
|
|
|
// If there was a package script, it should have finished
|
|
|
|
// the build already. Otherwise...
|
|
|
|
if !custom {
|
2013-09-16 19:27:09 -07:00
|
|
|
match what_to_build {
|
|
|
|
// Find crates inside the workspace
|
|
|
|
&Everything => pkg_src.find_crates(),
|
2013-09-26 16:04:49 -07:00
|
|
|
// Find only tests
|
|
|
|
&Tests => pkg_src.find_crates_with_filter(|s| { is_test(&Path(s)) }),
|
2013-09-16 19:27:09 -07:00
|
|
|
// Don't infer any crates -- just build the one that was requested
|
|
|
|
&JustOne(ref p) => {
|
|
|
|
// We expect that p is relative to the package source's start directory,
|
|
|
|
// so check that assumption
|
|
|
|
debug!("JustOne: p = %s", p.to_str());
|
|
|
|
assert!(os::path_exists(&pkg_src.start_dir.push_rel(p)));
|
|
|
|
if is_lib(p) {
|
|
|
|
PkgSrc::push_crate(&mut pkg_src.libs, 0, p);
|
|
|
|
} else if is_main(p) {
|
|
|
|
PkgSrc::push_crate(&mut pkg_src.mains, 0, p);
|
|
|
|
} else if is_test(p) {
|
|
|
|
PkgSrc::push_crate(&mut pkg_src.tests, 0, p);
|
|
|
|
} else if is_bench(p) {
|
|
|
|
PkgSrc::push_crate(&mut pkg_src.benchs, 0, p);
|
|
|
|
} else {
|
|
|
|
warn(fmt!("Not building any crates for dependency %s", p.to_str()));
|
|
|
|
return workspace.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-05-02 13:09:28 -07:00
|
|
|
// Build it!
|
2013-09-16 19:27:09 -07:00
|
|
|
let rs_path = pkg_src.build(self, cfgs);
|
2013-09-06 20:29:16 -07:00
|
|
|
Path(rs_path)
|
2013-08-28 14:52:37 -07:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Just return the source workspace
|
|
|
|
workspace.clone()
|
2013-05-02 13:09:28 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-11 22:45:13 -04:00
|
|
|
fn clean(&self, workspace: &Path, id: &PkgId) {
|
2013-04-17 15:47:24 -07:00
|
|
|
// Could also support a custom build hook in the pkg
|
|
|
|
// script for cleaning files rustpkg doesn't know about.
|
|
|
|
// Do something reasonable for now
|
|
|
|
|
2013-04-22 17:54:54 -07:00
|
|
|
let dir = build_pkg_id_in_workspace(id, workspace);
|
2013-06-14 18:16:24 -07:00
|
|
|
note(fmt!("Cleaning package %s (removing directory %s)",
|
2013-04-17 15:47:24 -07:00
|
|
|
id.to_str(), dir.to_str()));
|
|
|
|
if os::path_exists(&dir) {
|
2013-05-14 17:46:52 -07:00
|
|
|
os::remove_dir_recursive(&dir);
|
2013-06-14 18:16:24 -07:00
|
|
|
note(fmt!("Removed directory %s", dir.to_str()));
|
2013-04-17 15:47:24 -07:00
|
|
|
}
|
|
|
|
|
2013-06-14 18:16:24 -07:00
|
|
|
note(fmt!("Cleaned package %s", id.to_str()));
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
|
2013-02-04 17:12:31 -08:00
|
|
|
fn info(&self) {
|
2013-04-11 17:43:02 -07:00
|
|
|
// stub
|
2013-05-06 00:18:51 +02:00
|
|
|
fail!("info not yet implemented");
|
2013-01-26 18:35:10 +10:00
|
|
|
}
|
|
|
|
|
2013-09-16 19:27:09 -07:00
|
|
|
fn install(&self, mut pkg_src: PkgSrc, what: &WhatToBuild) -> (~[Path], ~[(~str, ~str)]) {
|
|
|
|
|
|
|
|
let id = pkg_src.id.clone();
|
|
|
|
|
|
|
|
let mut installed_files = ~[];
|
|
|
|
let inputs = ~[];
|
|
|
|
|
|
|
|
// workcache only knows about *crates*. Building a package
|
|
|
|
// just means inferring all the crates in it, then building each one.
|
|
|
|
let destination_workspace = self.build(&mut pkg_src, what).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 %s", id.to_str());
|
|
|
|
for cs in to_do.iter() {
|
|
|
|
for c in cs.iter() {
|
|
|
|
let path = pkg_src.start_dir.push_rel(&c.file).normalize();
|
|
|
|
debug!("Recording input: %s", path.to_str());
|
|
|
|
installed_files.push(path);
|
2013-09-06 20:29:16 -07:00
|
|
|
}
|
2013-09-16 19:27:09 -07:00
|
|
|
}
|
|
|
|
// See #7402: This still isn't quite right yet; we want to
|
|
|
|
// install to the first workspace in the RUST_PATH if there's
|
|
|
|
// a non-default RUST_PATH. This code installs to the same
|
|
|
|
// workspace the package was built in.
|
|
|
|
let actual_workspace = if path_util::user_set_rust_path() {
|
|
|
|
default_workspace()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Path(destination_workspace)
|
2013-09-06 20:29:16 -07:00
|
|
|
};
|
2013-09-16 19:27:09 -07:00
|
|
|
debug!("install: destination workspace = %s, id = %s, installing to %s",
|
|
|
|
destination_workspace, id.to_str(), actual_workspace.to_str());
|
|
|
|
let result = self.install_no_build(&Path(destination_workspace),
|
|
|
|
&actual_workspace,
|
|
|
|
&id).map(|s| Path(*s));
|
|
|
|
debug!("install: id = %s, about to call discover_outputs, %?",
|
|
|
|
id.to_str(), result.to_str());
|
|
|
|
installed_files = installed_files + result;
|
|
|
|
note(fmt!("Installed package %s to %s", id.to_str(), actual_workspace.to_str()));
|
|
|
|
(installed_files, inputs)
|
2013-06-25 22:26:22 -07:00
|
|
|
}
|
|
|
|
|
2013-09-16 19:27:09 -07:00
|
|
|
// again, working around lack of Encodable for Path
|
2013-09-12 16:13:30 -07:00
|
|
|
fn install_no_build(&self,
|
|
|
|
source_workspace: &Path,
|
|
|
|
target_workspace: &Path,
|
2013-09-16 19:27:09 -07:00
|
|
|
id: &PkgId) -> ~[~str] {
|
2013-06-25 22:26:22 -07:00
|
|
|
use conditions::copy_failed::cond;
|
2013-05-02 13:09:28 -07:00
|
|
|
|
|
|
|
// Now copy stuff into the install dirs
|
2013-09-12 16:13:30 -07:00
|
|
|
let maybe_executable = built_executable_in_workspace(id, source_workspace);
|
|
|
|
let maybe_library = built_library_in_workspace(id, source_workspace);
|
|
|
|
let target_exec = target_executable_in_workspace(id, target_workspace);
|
|
|
|
let target_lib = maybe_library.map(|_p| target_library_in_workspace(id, target_workspace));
|
2013-05-02 13:09:28 -07:00
|
|
|
|
2013-06-01 15:59:12 -07:00
|
|
|
debug!("target_exec = %s target_lib = %? \
|
2013-09-16 19:27:09 -07:00
|
|
|
maybe_executable = %? maybe_library = %?",
|
2013-06-01 15:59:12 -07:00
|
|
|
target_exec.to_str(), target_lib,
|
2013-05-10 19:00:51 -07:00
|
|
|
maybe_executable, maybe_library);
|
|
|
|
|
2013-09-16 19:27:09 -07:00
|
|
|
do self.workcache_context.with_prep(id.install_tag()) |prep| {
|
|
|
|
for ee in maybe_executable.iter() {
|
|
|
|
prep.declare_input("binary",
|
|
|
|
ee.to_str(),
|
|
|
|
workcache_support::digest_only_date(ee));
|
2013-05-02 13:09:28 -07:00
|
|
|
}
|
2013-09-16 19:27:09 -07:00
|
|
|
for ll in maybe_library.iter() {
|
|
|
|
prep.declare_input("binary",
|
|
|
|
ll.to_str(),
|
|
|
|
workcache_support::digest_only_date(ll));
|
|
|
|
}
|
|
|
|
let subex = maybe_executable.clone();
|
|
|
|
let sublib = maybe_library.clone();
|
|
|
|
let sub_target_ex = target_exec.clone();
|
|
|
|
let sub_target_lib = target_lib.clone();
|
|
|
|
|
|
|
|
do prep.exec |exe_thing| {
|
|
|
|
let mut outputs = ~[];
|
|
|
|
|
|
|
|
for exec in subex.iter() {
|
|
|
|
debug!("Copying: %s -> %s", exec.to_str(), sub_target_ex.to_str());
|
|
|
|
if !(os::mkdir_recursive(&sub_target_ex.dir_path(), U_RWX) &&
|
|
|
|
os::copy_file(exec, &sub_target_ex)) {
|
|
|
|
cond.raise(((*exec).clone(), sub_target_ex.clone()));
|
|
|
|
}
|
|
|
|
exe_thing.discover_output("binary",
|
|
|
|
sub_target_ex.to_str(),
|
|
|
|
workcache_support::digest_only_date(&sub_target_ex));
|
|
|
|
outputs.push(sub_target_ex.to_str());
|
|
|
|
}
|
|
|
|
for lib in sublib.iter() {
|
|
|
|
let target_lib = sub_target_lib
|
|
|
|
.clone().expect(fmt!("I built %s but apparently \
|
|
|
|
didn't install it!", lib.to_str()));
|
|
|
|
let target_lib = target_lib
|
|
|
|
.pop().push(lib.filename().expect("weird target lib"));
|
|
|
|
debug!("Copying: %s -> %s", lib.to_str(), sub_target_lib.to_str());
|
|
|
|
if !(os::mkdir_recursive(&target_lib.dir_path(), U_RWX) &&
|
|
|
|
os::copy_file(lib, &target_lib)) {
|
|
|
|
cond.raise(((*lib).clone(), target_lib.clone()));
|
|
|
|
}
|
|
|
|
exe_thing.discover_output("binary",
|
|
|
|
target_lib.to_str(),
|
|
|
|
workcache_support::digest_only_date(&target_lib));
|
|
|
|
outputs.push(target_lib.to_str());
|
|
|
|
}
|
|
|
|
outputs
|
2013-01-18 18:31:43 +10:00
|
|
|
}
|
|
|
|
}
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
|
2013-05-14 17:46:52 -07:00
|
|
|
fn prefer(&self, _id: &str, _vers: Option<~str>) {
|
2013-05-27 17:45:16 -07:00
|
|
|
fail!("prefer not yet implemented");
|
2013-01-17 19:05:19 +10:00
|
|
|
}
|
2013-01-16 21:59:37 +10:00
|
|
|
|
2013-09-26 16:04:49 -07:00
|
|
|
fn test(&self, pkgid: &PkgId, workspace: &Path) {
|
|
|
|
match built_test_in_workspace(pkgid, workspace) {
|
|
|
|
Some(test_exec) => {
|
|
|
|
debug!("test: test_exec = %s", test_exec.to_str());
|
2013-09-28 22:03:54 -07:00
|
|
|
let status = run::process_status(test_exec.to_str(), [~"--test"]);
|
|
|
|
os::set_exit_status(status);
|
2013-09-26 16:04:49 -07:00
|
|
|
}
|
|
|
|
None => {
|
|
|
|
error(fmt!("Internal error: test executable for package ID %s in workspace %s \
|
|
|
|
wasn't built! Please report this as a bug.",
|
|
|
|
pkgid.to_str(), workspace.to_str()));
|
|
|
|
}
|
|
|
|
}
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
|
2013-09-16 14:59:34 -07:00
|
|
|
fn init(&self) {
|
|
|
|
os::mkdir_recursive(&Path("src"), U_RWX);
|
|
|
|
os::mkdir_recursive(&Path("lib"), U_RWX);
|
|
|
|
os::mkdir_recursive(&Path("bin"), U_RWX);
|
|
|
|
os::mkdir_recursive(&Path("build"), U_RWX);
|
|
|
|
}
|
|
|
|
|
2013-05-14 17:46:52 -07:00
|
|
|
fn uninstall(&self, _id: &str, _vers: Option<~str>) {
|
2013-05-06 00:18:51 +02:00
|
|
|
fail!("uninstall not yet implemented");
|
2013-01-17 19:05:19 +10:00
|
|
|
}
|
2013-01-16 21:59:37 +10:00
|
|
|
|
2013-05-14 17:46:52 -07:00
|
|
|
fn unprefer(&self, _id: &str, _vers: Option<~str>) {
|
2013-05-06 00:18:51 +02:00
|
|
|
fail!("unprefer not yet implemented");
|
2013-01-16 21:59:37 +10:00
|
|
|
}
|
|
|
|
}
|
2013-01-15 23:57:03 +10:00
|
|
|
|
2013-01-14 20:55:47 +10:00
|
|
|
pub fn main() {
|
2013-04-11 17:43:02 -07:00
|
|
|
io::println("WARNING: The Rust package manager is experimental and may be unstable");
|
2013-09-24 16:34:23 -07:00
|
|
|
os::set_exit_status(main_args(os::args()));
|
2013-08-22 17:41:33 +08:00
|
|
|
}
|
|
|
|
|
2013-09-24 16:34:23 -07:00
|
|
|
pub fn main_args(args: &[~str]) -> int {
|
2013-05-21 23:00:34 +09:00
|
|
|
let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
|
2013-09-10 11:41:05 -07:00
|
|
|
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"),
|
2013-08-26 15:34:34 -07:00
|
|
|
getopts::optmulti("c"), getopts::optmulti("cfg"),
|
2013-08-28 14:52:37 -07:00
|
|
|
getopts::optflag("v"), getopts::optflag("version"),
|
2013-09-10 11:41:05 -07:00
|
|
|
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") ];
|
2013-01-15 23:57:03 +10:00
|
|
|
let matches = &match getopts::getopts(args, opts) {
|
|
|
|
result::Ok(m) => m,
|
|
|
|
result::Err(f) => {
|
2013-09-18 03:42:23 +02:00
|
|
|
error(fmt!("%s", f.to_err_msg()));
|
2013-01-19 19:59:19 +10:00
|
|
|
|
2013-09-24 16:34:23 -07:00
|
|
|
return 1;
|
2013-01-15 23:57:03 +10:00
|
|
|
}
|
|
|
|
};
|
2013-09-18 03:42:23 +02:00
|
|
|
let mut help = matches.opt_present("h") ||
|
|
|
|
matches.opt_present("help");
|
|
|
|
let no_link = matches.opt_present("no-link");
|
|
|
|
let no_trans = matches.opt_present("no-trans");
|
|
|
|
let supplied_sysroot = matches.opt_val("sysroot");
|
|
|
|
let generate_asm = matches.opt_present("S") ||
|
|
|
|
matches.opt_present("assembly");
|
|
|
|
let parse_only = matches.opt_present("parse-only");
|
|
|
|
let pretty = matches.opt_present("pretty");
|
|
|
|
let emit_llvm = matches.opt_present("emit-llvm");
|
|
|
|
|
|
|
|
if matches.opt_present("v") ||
|
|
|
|
matches.opt_present("version") {
|
2013-08-26 15:34:34 -07:00
|
|
|
rustc::version(args[0]);
|
2013-09-24 16:34:23 -07:00
|
|
|
return 0;
|
2013-08-26 15:34:34 -07:00
|
|
|
}
|
|
|
|
|
2013-09-18 03:42:23 +02:00
|
|
|
let use_rust_path_hack = matches.opt_present("r") ||
|
|
|
|
matches.opt_present("rust-path-hack");
|
2013-08-28 14:52:37 -07:00
|
|
|
|
2013-09-18 03:42:23 +02:00
|
|
|
let linker = matches.opt_str("linker");
|
|
|
|
let link_args = matches.opt_str("link-args");
|
|
|
|
let cfgs = matches.opt_strs("cfg") + matches.opt_strs("c");
|
2013-09-10 11:41:05 -07:00
|
|
|
let mut user_supplied_opt_level = true;
|
2013-09-18 03:42:23 +02:00
|
|
|
let opt_level = match matches.opt_str("opt-level") {
|
2013-09-10 11:41:05 -07:00
|
|
|
Some(~"0") => session::No,
|
|
|
|
Some(~"1") => session::Less,
|
|
|
|
Some(~"2") => session::Default,
|
|
|
|
Some(~"3") => session::Aggressive,
|
2013-09-18 03:42:23 +02:00
|
|
|
_ if matches.opt_present("O") => session::Default,
|
2013-09-10 11:41:05 -07:00
|
|
|
_ => {
|
|
|
|
user_supplied_opt_level = false;
|
|
|
|
session::No
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-09-18 03:42:23 +02:00
|
|
|
let save_temps = matches.opt_present("save-temps");
|
|
|
|
let target = matches.opt_str("target");
|
|
|
|
let target_cpu = matches.opt_str("target-cpu");
|
2013-09-10 11:41:05 -07:00
|
|
|
let experimental_features = {
|
2013-09-18 03:42:23 +02:00
|
|
|
let strs = matches.opt_strs("Z");
|
|
|
|
if matches.opt_present("Z") {
|
2013-09-10 11:41:05 -07:00
|
|
|
Some(strs)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-07-02 12:47:32 -07:00
|
|
|
let mut args = matches.free.clone();
|
2013-01-15 23:57:03 +10:00
|
|
|
args.shift();
|
2013-01-14 20:55:47 +10:00
|
|
|
|
2013-01-15 23:57:03 +10:00
|
|
|
if (args.len() < 1) {
|
2013-09-24 16:34:23 -07:00
|
|
|
usage::general();
|
|
|
|
return 1;
|
2013-01-15 23:57:03 +10:00
|
|
|
}
|
|
|
|
|
2013-09-10 11:41:05 -07:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2013-08-28 14:52:37 -07:00
|
|
|
let mut cmd_opt = None;
|
|
|
|
for a in args.iter() {
|
|
|
|
if util::is_cmd(*a) {
|
|
|
|
cmd_opt = Some(a);
|
|
|
|
break;
|
|
|
|
}
|
2013-01-15 23:57:03 +10:00
|
|
|
}
|
2013-08-28 14:52:37 -07:00
|
|
|
let cmd = match cmd_opt {
|
2013-09-24 16:34:23 -07:00
|
|
|
None => {
|
|
|
|
usage::general();
|
|
|
|
return 0;
|
|
|
|
}
|
2013-09-10 11:41:05 -07:00
|
|
|
Some(cmd) => {
|
|
|
|
help |= context::flags_ok_for_cmd(&rustc_flags, cfgs, *cmd, user_supplied_opt_level);
|
|
|
|
if help {
|
2013-09-24 16:34:23 -07:00
|
|
|
match *cmd {
|
2013-09-10 11:41:05 -07:00
|
|
|
~"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(),
|
2013-09-16 14:59:34 -07:00
|
|
|
~"init" => usage::init(),
|
2013-09-10 11:41:05 -07:00
|
|
|
~"uninstall" => usage::uninstall(),
|
|
|
|
~"unprefer" => usage::unprefer(),
|
|
|
|
_ => usage::general()
|
|
|
|
};
|
2013-09-24 16:34:23 -07:00
|
|
|
return 0;
|
2013-09-10 11:41:05 -07:00
|
|
|
} else {
|
|
|
|
cmd
|
|
|
|
}
|
2013-08-28 14:52:37 -07:00
|
|
|
}
|
|
|
|
};
|
2013-01-15 23:57:03 +10:00
|
|
|
|
2013-08-28 14:52:37 -07:00
|
|
|
// Pop off all flags, plus the command
|
|
|
|
let remaining_args = args.iter().skip_while(|s| !util::is_cmd(**s));
|
|
|
|
// 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();
|
2013-09-10 11:41:05 -07:00
|
|
|
let sroot = match supplied_sysroot {
|
|
|
|
Some(getopts::Val(s)) => Path(s),
|
|
|
|
_ => filesearch::get_or_default_sysroot()
|
|
|
|
};
|
|
|
|
|
2013-09-06 20:29:16 -07:00
|
|
|
debug!("Using sysroot: %s", sroot.to_str());
|
|
|
|
debug!("Will store workcache in %s", default_workspace().to_str());
|
2013-09-16 19:27:09 -07:00
|
|
|
|
|
|
|
let rm_args = remaining_args.clone();
|
|
|
|
let sub_cmd = cmd.clone();
|
|
|
|
// Wrap the rest in task::try in case of a condition failure in a task
|
|
|
|
let result = do task::try {
|
|
|
|
BuildContext {
|
|
|
|
context: Context {
|
|
|
|
cfgs: cfgs.clone(),
|
|
|
|
rustc_flags: rustc_flags.clone(),
|
|
|
|
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
|
|
|
|
}.run(sub_cmd, rm_args.clone())
|
|
|
|
};
|
|
|
|
// FIXME #9262: This is using the same error code for all errors,
|
2013-09-17 18:23:34 -07:00
|
|
|
// and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE,
|
2013-09-16 19:27:09 -07:00
|
|
|
// when actually, it might set the exit code for that even if a different
|
|
|
|
// unhandled condition got raised.
|
2013-09-24 16:34:23 -07:00
|
|
|
if result.is_err() { return COPY_FAILED_CODE; }
|
|
|
|
return 0;
|
2013-01-14 20:55:47 +10:00
|
|
|
}
|
2013-01-15 23:57:03 +10:00
|
|
|
|
2013-01-23 16:38:05 +10:00
|
|
|
/**
|
|
|
|
* Get the working directory of the package script.
|
|
|
|
* Assumes that the package script has been compiled
|
|
|
|
* in is the working directory.
|
|
|
|
*/
|
2013-01-26 18:35:10 +10:00
|
|
|
pub fn work_dir() -> Path {
|
2013-08-04 01:59:24 +02:00
|
|
|
os::self_exe_path().unwrap()
|
2013-01-23 16:38:05 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-01-26 18:35:10 +10:00
|
|
|
pub fn src_dir() -> Path {
|
2013-01-23 16:38:05 +10:00
|
|
|
os::getcwd()
|
|
|
|
}
|
2013-09-06 20:29:16 -07:00
|
|
|
|
|
|
|
fn declare_package_script_dependency(prep: &mut workcache::Prep, pkg_src: &PkgSrc) {
|
|
|
|
match pkg_src.package_script_option() {
|
|
|
|
Some(ref p) => prep.declare_input("file", p.to_str(),
|
|
|
|
workcache_support::digest_file_with_date(p)),
|
|
|
|
None => ()
|
|
|
|
}
|
|
|
|
}
|