auto merge of #5920 : catamorphism/rust/rustpkg, r=catamorphism
r? @graydon
This commit is contained in:
commit
50cd218c1e
src/librustpkg
@ -11,7 +11,8 @@
|
||||
// rustpkg utilities having to do with paths and directories
|
||||
|
||||
use core::path::*;
|
||||
use core::os;
|
||||
use core::{os, str};
|
||||
use core::option::*;
|
||||
use util::PkgId;
|
||||
|
||||
/// Returns the output directory to use.
|
||||
@ -50,6 +51,24 @@ pub fn default_dest_dir(pkg_dir: &Path) -> Path {
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace all occurrences of '-' in the stem part of path with '_'
|
||||
/// This is because we treat rust-foo-bar-quux and rust_foo_bar_quux
|
||||
/// as the same name
|
||||
pub fn normalize(p: ~Path) -> ~Path {
|
||||
match p.filestem() {
|
||||
None => p,
|
||||
Some(st) => {
|
||||
let replaced = str::replace(st, "-", "_");
|
||||
if replaced != st {
|
||||
~p.with_filestem(replaced)
|
||||
}
|
||||
else {
|
||||
p
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::{os, rand};
|
||||
|
@ -33,11 +33,11 @@ use core::hashmap::HashMap;
|
||||
use core::io::WriterUtil;
|
||||
use rustc::driver::{driver, session};
|
||||
use rustc::metadata::filesearch;
|
||||
use std::net::url;
|
||||
use std::{getopts};
|
||||
use syntax::{ast, diagnostic};
|
||||
use util::{ExitCode, Pkg, PkgId};
|
||||
use path_util::dest_dir;
|
||||
use util::*;
|
||||
use path_util::{dest_dir, normalize};
|
||||
use rustc::driver::session::{lib_crate, bin_crate, unknown_crate, crate_type};
|
||||
|
||||
mod conditions;
|
||||
mod usage;
|
||||
@ -117,9 +117,12 @@ impl PkgScript {
|
||||
Ok(r) => {
|
||||
let root = r.pop().pop().pop().pop(); // :-\
|
||||
debug!("Root is %s, calling compile_rest", root.to_str());
|
||||
util::compile_crate_from_input(self.input, Some(self.build_dir),
|
||||
sess, Some(crate), os::args()[0]);
|
||||
let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
|
||||
util::compile_crate_from_input(self.input, self.id,
|
||||
Some(self.build_dir),
|
||||
sess, Some(crate),
|
||||
exe, os::args()[0],
|
||||
driver::cu_everything);
|
||||
debug!("Running program: %s %s %s", exe.to_str(), root.to_str(), what);
|
||||
let status = run::run_program(exe.to_str(), ~[root.to_str(), what]);
|
||||
if status != 0 {
|
||||
@ -199,15 +202,15 @@ impl Ctx {
|
||||
// relative to the CWD. In the future, we should search
|
||||
// paths
|
||||
let cwd = os::getcwd().normalize();
|
||||
debug!("Current working directory = %?", cwd);
|
||||
debug!("Current working directory = %s", cwd.to_str());
|
||||
|
||||
// Find crates inside the workspace
|
||||
// Create the package source
|
||||
let mut src = PkgSrc::new(&cwd, &dst_dir, &pkgid);
|
||||
debug!("Package src = %?", src);
|
||||
src.find_crates();
|
||||
|
||||
// Is there custom build logic? If so, use it
|
||||
let pkg_src_dir = cwd.push_rel(&pkgid.path);
|
||||
let mut custom = false;;
|
||||
debug!("Package source directory = %s", pkg_src_dir.to_str());
|
||||
let cfgs = match src.package_script_option(&pkg_src_dir) {
|
||||
Some(package_script_path) => {
|
||||
@ -221,6 +224,7 @@ impl Ctx {
|
||||
if hook_result != 0 {
|
||||
fail!(fmt!("Error running custom build command"))
|
||||
}
|
||||
custom = true;
|
||||
// otherwise, the package script succeeded
|
||||
cfgs
|
||||
}
|
||||
@ -229,19 +233,32 @@ impl Ctx {
|
||||
~[]
|
||||
}
|
||||
};
|
||||
src.build(&dst_dir, cfgs);
|
||||
|
||||
// If there was a package script, it should have finished
|
||||
// the build already. Otherwise...
|
||||
if !custom {
|
||||
// Find crates inside the workspace
|
||||
src.find_crates();
|
||||
// Build it!
|
||||
src.build(&dst_dir, cfgs);
|
||||
}
|
||||
}
|
||||
~"clean" => {
|
||||
self.clean();
|
||||
if args.len() < 1 {
|
||||
return usage::build();
|
||||
}
|
||||
// The package id is presumed to be the first command-line
|
||||
// argument
|
||||
let pkgid = PkgId::new(args[0]);
|
||||
|
||||
self.clean(pkgid);
|
||||
}
|
||||
~"do" => {
|
||||
if args.len() < 2 {
|
||||
return usage::do_cmd();
|
||||
}
|
||||
|
||||
if !self.do_cmd(args[0], args[1]) {
|
||||
fail!(~"a command failed!");
|
||||
}
|
||||
self.do_cmd(args[0], args[1]);
|
||||
}
|
||||
~"info" => {
|
||||
self.info();
|
||||
@ -286,12 +303,11 @@ impl Ctx {
|
||||
}
|
||||
}
|
||||
|
||||
fn do_cmd(&self, cmd: ~str, pkgname: ~str) -> bool {
|
||||
fn do_cmd(&self, cmd: ~str, pkgname: ~str) {
|
||||
match cmd {
|
||||
~"build" | ~"test" => {
|
||||
util::error(~"that command cannot be manually called");
|
||||
|
||||
return false;
|
||||
fail!(~"do_cmd");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -307,16 +323,15 @@ impl Ctx {
|
||||
Some(script_path) => {
|
||||
let script = PkgScript::parse(script_path, pkgid);
|
||||
let (_, status) = script.run_custom(cmd); // Ignore cfgs?
|
||||
if status == 42 { // ???
|
||||
if status == 42 {
|
||||
util::error(~"no fns are listening for that cmd");
|
||||
return false;
|
||||
fail!(~"do_cmd");
|
||||
}
|
||||
status == 0
|
||||
}
|
||||
None => {
|
||||
util::error(fmt!("invoked `do`, but there is no package script in %s",
|
||||
cwd.to_str()));
|
||||
false
|
||||
fail!(~"do_cmd");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -329,128 +344,44 @@ impl Ctx {
|
||||
}
|
||||
|
||||
fn compile(&self, _crate: &Path, _dir: &Path, _flags: ~[~str],
|
||||
_cfgs: ~[~str], _opt: bool, _test: bool) -> bool {
|
||||
_cfgs: ~[~str], _opt: bool, _test: bool) {
|
||||
// What's the difference between build and compile?
|
||||
fail!(~"compile not yet implemented");
|
||||
}
|
||||
|
||||
fn clean(&self) -> bool {
|
||||
// stub
|
||||
fail!();
|
||||
fn clean(&self, id: PkgId) {
|
||||
// Could also support a custom build hook in the pkg
|
||||
// script for cleaning files rustpkg doesn't know about.
|
||||
// Do something reasonable for now
|
||||
|
||||
let dir = dest_dir(id);
|
||||
util::note(fmt!("Cleaning package %s (removing directory %s)",
|
||||
id.to_str(), dir.to_str()));
|
||||
if os::path_exists(&dir) {
|
||||
util::remove_dir_r(&dir);
|
||||
util::note(fmt!("Removed directory %s", dir.to_str()));
|
||||
}
|
||||
|
||||
util::note(fmt!("Cleaned package %s", id.to_str()));
|
||||
}
|
||||
|
||||
fn info(&self) {
|
||||
// stub
|
||||
fail!();
|
||||
fail!(~"info not yet implemented");
|
||||
}
|
||||
|
||||
fn install(&self, url: Option<~str>,
|
||||
target: Option<~str>, cache: bool) -> bool {
|
||||
let dir = match url {
|
||||
None => {
|
||||
util::note(~"installing from the cwd");
|
||||
os::getcwd()
|
||||
}
|
||||
Some(url) => {
|
||||
let hash = util::hash(if !target.is_none() {
|
||||
url + target.get()
|
||||
}
|
||||
else { url });
|
||||
|
||||
if self.dep_cache.contains_key(&hash) {
|
||||
util::warn(~"already installed dep this run");
|
||||
return true;
|
||||
}
|
||||
|
||||
self.dep_cache.insert(hash, true);
|
||||
|
||||
let dir = util::root().push(~"tmp").push(hash);
|
||||
|
||||
if cache && os::path_exists(&dir) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if !self.fetch(&dir, url, target) {
|
||||
return false;
|
||||
}
|
||||
dir
|
||||
}
|
||||
};
|
||||
|
||||
let script = match self.build(&dir, false, true, false) {
|
||||
Some(script) => script,
|
||||
None => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let work_dir = script.build_dir;
|
||||
let from_bin_dir = work_dir.push(~"bin");
|
||||
let from_lib_dir = work_dir.push(~"lib");
|
||||
let to_bin_dir = util::root().push(~"bin");
|
||||
let to_lib_dir = util::root().push(~"lib");
|
||||
let mut bins = ~[];
|
||||
let mut libs = ~[];
|
||||
|
||||
for os::walk_dir(&from_bin_dir) |bin| {
|
||||
let to = to_bin_dir.push_rel(&bin.file_path());
|
||||
|
||||
os::copy_file(bin, &to);
|
||||
bins.push(to.to_str());
|
||||
}
|
||||
|
||||
for os::walk_dir(&from_lib_dir) |lib| {
|
||||
let to = to_lib_dir.push_rel(&lib.file_path());
|
||||
|
||||
os::copy_file(lib, &to);
|
||||
libs.push(to.to_str());
|
||||
}
|
||||
|
||||
let package = Pkg {
|
||||
id: script.id,
|
||||
bins: bins,
|
||||
libs: libs
|
||||
};
|
||||
|
||||
util::note(fmt!("installed %s", script.id.to_str()));
|
||||
util::add_pkg(&package);
|
||||
|
||||
true
|
||||
fn install(&self, _url: Option<~str>,
|
||||
_target: Option<~str>, _cache: bool) {
|
||||
// stub
|
||||
fail!(~"install not yet implemented");
|
||||
}
|
||||
|
||||
fn fetch(&self, dir: &Path, url: ~str, target: Option<~str>) -> bool {
|
||||
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()));
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let str = url.to_str();
|
||||
|
||||
match Path(url.path).filetype() {
|
||||
Some(ext) => {
|
||||
if ext == ~".git" {
|
||||
return self.fetch_git(dir, str, target);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
match url.scheme {
|
||||
~"git" => self.fetch_git(dir, str, target),
|
||||
~"http" | ~"ftp" | ~"file" => self.fetch_curl(dir, str),
|
||||
_ => {
|
||||
util::warn(~"unknown url scheme to fetch, using curl");
|
||||
self.fetch_curl(dir, str)
|
||||
}
|
||||
}
|
||||
fn fetch(&self, _dir: &Path, _url: ~str, _target: Option<~str>) {
|
||||
// stub
|
||||
fail!(~"fetch not yet implemented");
|
||||
}
|
||||
|
||||
fn fetch_curl(&self, dir: &Path, url: ~str) -> bool {
|
||||
fn fetch_curl(&self, dir: &Path, url: ~str) {
|
||||
util::note(fmt!("fetching from %s using curl", url));
|
||||
|
||||
let tar = dir.dir_path().push(&dir.file_path().to_str() + ~".tar");
|
||||
@ -460,7 +391,7 @@ impl Ctx {
|
||||
url]).status != 0 {
|
||||
util::error(~"fetching failed: downloading using curl failed");
|
||||
|
||||
return false;
|
||||
fail!();
|
||||
}
|
||||
|
||||
if run::program_output(~"tar", ~[~"-x", ~"--strip-components=1",
|
||||
@ -469,13 +400,11 @@ impl Ctx {
|
||||
util::error(~"fetching failed: extracting using tar failed" +
|
||||
~"(is it a valid tar archive?)");
|
||||
|
||||
return false;
|
||||
fail!();
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn fetch_git(&self, dir: &Path, url: ~str, target: Option<~str>) -> bool {
|
||||
fn fetch_git(&self, dir: &Path, url: ~str, target: Option<~str>) {
|
||||
util::note(fmt!("fetching from %s using git", url));
|
||||
|
||||
// Git can't clone into a non-empty directory
|
||||
@ -484,8 +413,7 @@ impl Ctx {
|
||||
if run::program_output(~"git", ~[~"clone", url,
|
||||
dir.to_str()]).status != 0 {
|
||||
util::error(~"fetching failed: can't clone repository");
|
||||
|
||||
return false;
|
||||
fail!();
|
||||
}
|
||||
|
||||
if !target.is_none() {
|
||||
@ -499,21 +427,17 @@ impl Ctx {
|
||||
|
||||
if !success {
|
||||
util::error(~"fetching failed: can't checkout target");
|
||||
|
||||
return false;
|
||||
fail!();
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn prefer(&self, id: ~str, vers: Option<~str>) -> bool {
|
||||
fn prefer(&self, id: ~str, vers: Option<~str>) {
|
||||
let package = match util::get_pkg(id, vers) {
|
||||
result::Ok(package) => package,
|
||||
result::Err(err) => {
|
||||
util::error(err);
|
||||
|
||||
return false;
|
||||
fail!(); // Condition?
|
||||
}
|
||||
};
|
||||
let name = package.id.path.to_str(); // ???
|
||||
@ -536,29 +460,18 @@ impl Ctx {
|
||||
}
|
||||
|
||||
util::note(fmt!("preferred %s v%s", name, package.id.version.to_str()));
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn test(&self) -> bool {
|
||||
let script = match self.build(&os::getcwd(), false, false, true) {
|
||||
Some(script) => script,
|
||||
None => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// To do
|
||||
util::note(fmt!("Would test %s, but this is a dry run",
|
||||
script.id.to_str()));
|
||||
false
|
||||
fn test(&self) {
|
||||
// stub
|
||||
fail!(~"test not yet implemented");
|
||||
}
|
||||
|
||||
fn uninstall(&self, _id: ~str, _vers: Option<~str>) -> bool {
|
||||
fn uninstall(&self, _id: ~str, _vers: Option<~str>) {
|
||||
fail!(~"uninstall not yet implemented");
|
||||
}
|
||||
|
||||
fn unprefer(&self, _id: ~str, _vers: Option<~str>) -> bool {
|
||||
fn unprefer(&self, _id: ~str, _vers: Option<~str>) {
|
||||
fail!(~"unprefer not yet implemented");
|
||||
}
|
||||
}
|
||||
@ -728,7 +641,6 @@ condition! {
|
||||
|
||||
impl PkgSrc {
|
||||
|
||||
|
||||
fn new(src_dir: &Path, dst_dir: &Path,
|
||||
id: &PkgId) -> PkgSrc {
|
||||
PkgSrc {
|
||||
@ -765,12 +677,6 @@ impl PkgSrc {
|
||||
dir
|
||||
}
|
||||
|
||||
|
||||
fn has_pkg_file(&self) -> bool {
|
||||
let dir = self.check_dir();
|
||||
dir.push("pkg.rs").exists()
|
||||
}
|
||||
|
||||
// If a file named "pkg.rs" in the current directory exists,
|
||||
// return the path for it. Otherwise, None
|
||||
fn package_script_option(&self, cwd: &Path) -> Option<Path> {
|
||||
@ -786,14 +692,16 @@ impl PkgSrc {
|
||||
/// True if the given path's stem is self's pkg ID's stem
|
||||
/// or if the pkg ID's stem is <rust-foo> and the given path's
|
||||
/// stem is foo
|
||||
/// Requires that dashes in p have already been normalized to
|
||||
/// underscores
|
||||
fn stem_matches(&self, p: &Path) -> bool {
|
||||
let self_id = self.id.path.filestem();
|
||||
let self_id = normalize(~self.id.path).filestem();
|
||||
if self_id == p.filestem() {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
for self_id.each |pth| {
|
||||
if pth.starts_with("rust-")
|
||||
if pth.starts_with("rust_") // because p is already normalized
|
||||
&& match p.filestem() {
|
||||
Some(s) => str::eq_slice(s, pth.slice(5, pth.len())),
|
||||
None => false
|
||||
@ -814,17 +722,14 @@ impl PkgSrc {
|
||||
cs.push(Crate::new(&sub));
|
||||
}
|
||||
|
||||
/// Infers crates to build. Called only in the case where there
|
||||
/// is no custom build logic
|
||||
fn find_crates(&mut self) {
|
||||
use PkgSrc::push_crate;
|
||||
|
||||
let dir = self.check_dir();
|
||||
let prefix = dir.components.len();
|
||||
// This is ugly, but can go away once we get rid
|
||||
// of .rc files
|
||||
let mut saw_rs = false;
|
||||
let mut saw_rc = false;
|
||||
debug!("Matching against %?",
|
||||
self.id.path.filestem());
|
||||
debug!("Matching against %?", self.id.path.filestem());
|
||||
for os::walk_dir(&dir) |pth| {
|
||||
match pth.filename() {
|
||||
Some(~"lib.rs") => push_crate(&mut self.libs,
|
||||
@ -835,34 +740,19 @@ impl PkgSrc {
|
||||
prefix, pth),
|
||||
Some(~"bench.rs") => push_crate(&mut self.benchs,
|
||||
prefix, pth),
|
||||
_ => {
|
||||
// If the file stem is the same as the
|
||||
// package ID, with an .rs or .rc extension,
|
||||
// consider it to be a crate
|
||||
let ext = pth.filetype();
|
||||
let matches = |p: &Path| {
|
||||
self.stem_matches(p) && (ext == Some(~".rc")
|
||||
|| ext == Some(~".rs"))
|
||||
};
|
||||
debug!("Checking %? which %s and ext = %? %? %?", pth.filestem(),
|
||||
if matches(pth) { "matches" } else { "does not match" },
|
||||
ext, saw_rs, saw_rc);
|
||||
if matches(pth) &&
|
||||
// Avoid pushing foo.rc *and* foo.rs
|
||||
!((ext == Some(~".rc") && saw_rs) ||
|
||||
(ext == Some(~".rs") && saw_rc)) {
|
||||
push_crate(&mut self.libs, // ????
|
||||
prefix, pth);
|
||||
if ext == Some(~".rc") {
|
||||
saw_rc = true;
|
||||
}
|
||||
else if ext == Some(~".rs") {
|
||||
saw_rs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
if self.libs.is_empty() && self.mains.is_empty()
|
||||
&& self.tests.is_empty() && self.benchs.is_empty() {
|
||||
|
||||
util::note(~"Couldn't infer any crates to build.\n\
|
||||
Try naming a crate `main.rs`, `lib.rs`, \
|
||||
`test.rs`, or `bench.rs`.");
|
||||
fail!(~"Failed to infer crates to build");
|
||||
}
|
||||
|
||||
debug!("found %u libs, %u mains, %u tests, %u benchs",
|
||||
self.libs.len(),
|
||||
self.mains.len(),
|
||||
@ -870,22 +760,22 @@ impl PkgSrc {
|
||||
self.benchs.len())
|
||||
}
|
||||
|
||||
fn build_crates(dst_dir: &Path,
|
||||
fn build_crates(&self, dst_dir: &Path,
|
||||
src_dir: &Path,
|
||||
crates: &[Crate],
|
||||
cfgs: ~[~str],
|
||||
test: bool) {
|
||||
test: bool, crate_type: crate_type) {
|
||||
|
||||
for crates.each |&crate| {
|
||||
let path = &src_dir.push_rel(&crate.file).normalize();
|
||||
util::note(fmt!("build_crates: compiling %s", path.to_str()));
|
||||
util::note(fmt!("build_crates: destination dir is %s", dst_dir.to_str()));
|
||||
|
||||
let result = util::compile_crate(None, path,
|
||||
let result = util::compile_crate(None, self.id, path,
|
||||
dst_dir,
|
||||
crate.flags,
|
||||
crate.cfgs + cfgs,
|
||||
false, test);
|
||||
false, test, crate_type);
|
||||
if !result {
|
||||
build_err::cond.raise(fmt!("build failure on %s",
|
||||
path.to_str()));
|
||||
@ -898,12 +788,12 @@ impl PkgSrc {
|
||||
fn build(&self, dst_dir: &Path, cfgs: ~[~str]) {
|
||||
let dir = self.check_dir();
|
||||
debug!("Building libs");
|
||||
PkgSrc::build_crates(dst_dir, &dir, self.libs, cfgs, false);
|
||||
self.build_crates(dst_dir, &dir, self.libs, cfgs, false, lib_crate);
|
||||
debug!("Building mains");
|
||||
PkgSrc::build_crates(dst_dir, &dir, self.mains, cfgs, false);
|
||||
self.build_crates(dst_dir, &dir, self.mains, cfgs, false, bin_crate);
|
||||
debug!("Building tests");
|
||||
PkgSrc::build_crates(dst_dir, &dir, self.tests, cfgs, true);
|
||||
self.build_crates(dst_dir, &dir, self.tests, cfgs, true, bin_crate);
|
||||
debug!("Building benches");
|
||||
PkgSrc::build_crates(dst_dir, &dir, self.benchs, cfgs, true);
|
||||
self.build_crates(dst_dir, &dir, self.benchs, cfgs, true, bin_crate);
|
||||
}
|
||||
}
|
||||
|
22
src/librustpkg/testsuite/fail/no-inferred-crates/zzyzx.rs
Normal file
22
src/librustpkg/testsuite/fail/no-inferred-crates/zzyzx.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg build hello-world`:
|
||||
* testsuite/hello-world/build/ exists
|
||||
* testsuite/hello-world/build/ contains an executable named hello-world
|
||||
* testsuite/hello-world/build/ does not contain a library
|
||||
*/
|
||||
|
||||
use core::io;
|
||||
|
||||
fn main() {
|
||||
io::println(~"Hello world!");
|
||||
}
|
35
src/librustpkg/testsuite/pass/commands.txt
Normal file
35
src/librustpkg/testsuite/pass/commands.txt
Normal file
@ -0,0 +1,35 @@
|
||||
Commands that should succeed:
|
||||
|
||||
1. rustpkg install github.com/mozilla-servo/rust-http-client
|
||||
|
||||
2. Create a git repo containing a package "foo", add a tag called "1.0" -- `rustpkg install foo` should install a library called "libfoo-....-1.0..."
|
||||
|
||||
3. rustpkg install foo, if ./.rust/foo exists and is a valid package directory
|
||||
|
||||
4. RUST_PATH=/home/rust rustpkg install foo installs an executable in /home/rust/foo if ./foo exists and is a valid package directory
|
||||
|
||||
5. RUST_PATH=/home/rust:/home/more_rust rustpkg install foo succeeds if /home/more_rust/foo exists and is a valid package directory
|
||||
|
||||
6. rustpkg install foo; rustpkg install bar; rustpkg install quux; rustpkg list should show foo, bar, and quux
|
||||
6a. then, rustpkg remove foo; rustpkg list should show bar and quux, but not foo
|
||||
|
||||
7. Execute `rustpkg build foo`. Check the datestamp on build/foo. Execute the same command again. Make sure the datestamp hasn't changed.
|
||||
|
||||
8. Execute `rustpkg build foo` where foo has a dependency on bar, which hasn't been built before. Check the datestamps on build/foo and build/bar and make sure bar's datestamp is earlier than foo's.
|
||||
|
||||
9. Execute `rustpkg build foo` where foo has a dependency on bar, which hasn't been built before. Then, change one of the source files in bar. Execute `rustpkg build foo` again. Make sure, based on datestamps, that foo was really rebuilt.
|
||||
|
||||
10. Repeat test 9 in the case where the contents of the source file in bar change but its datestamp doesn't change.
|
||||
|
||||
11. If the current directory contains package directories for foo-0.1 and foo.0.2, `rustpkg install foo#0.1` installs foo#0.1 and doesn't install foo#0.2.
|
||||
|
||||
12. `rustpkg do fancy-pkg frob` succeeds if `fancy-pkg` has a package script that defines a custom build hook named `frob`.
|
||||
|
||||
13. `rustpkg info foo` prints out something about foo, if foo is installed.
|
||||
|
||||
14. (Not sure what prefer and unprefer do)
|
||||
|
||||
15. `rustpkg test foo` runs tests and prints their output, if foo contains #[test]s.
|
||||
|
||||
16. If foo is installed, `rustpkg uninstall foo; rustpkg list` doesn't include foo in the list
|
||||
|
18
src/librustpkg/testsuite/pass/deeply/nested/path/foo/main.rs
Normal file
18
src/librustpkg/testsuite/pass/deeply/nested/path/foo/main.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg install deeply/nested/path/foo`:
|
||||
with RUST_PATH undefined in the environment:
|
||||
* ./deeply/nested/path/foo exists and is an executable
|
||||
*/
|
||||
|
||||
fn main() {}
|
||||
|
21
src/librustpkg/testsuite/pass/external-crate/main.rs
Normal file
21
src/librustpkg/testsuite/pass/external-crate/main.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg install external crate`
|
||||
with RUST_PATH undefined in the environment
|
||||
and with `rustpkg install deeply/nested/path/foo` already
|
||||
executed:
|
||||
* ./.rust/external_crate exists and is an executable
|
||||
*/
|
||||
|
||||
extern mod foo; // refers to deeply/nested/path/foo
|
||||
|
||||
fn main() {}
|
13
src/librustpkg/testsuite/pass/fancy-lib/bar.rs
Normal file
13
src/librustpkg/testsuite/pass/fancy-lib/bar.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn assert_true() {
|
||||
assert!(true);
|
||||
}
|
24
src/librustpkg/testsuite/pass/fancy-lib/fancy-lib.rs
Normal file
24
src/librustpkg/testsuite/pass/fancy-lib/fancy-lib.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg build fancy-lib`:
|
||||
* testsuite/fancy-lib/build/ exists
|
||||
* testsuite/fancy-lib/build/ contains a file called generated.rs
|
||||
* testsuite/fancy-lib/build/ contains a library named libfancy_lib
|
||||
* testsuite/fancy-lib/build/ does not contain an executable
|
||||
*
|
||||
*/
|
||||
|
||||
extern mod std;
|
||||
|
||||
pub mod foo;
|
||||
pub mod bar;
|
||||
#[path = "build/generated.rs"] pub mod generated;
|
12
src/librustpkg/testsuite/pass/fancy-lib/foo.rs
Normal file
12
src/librustpkg/testsuite/pass/fancy-lib/foo.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn do_nothing() {
|
||||
}
|
23
src/librustpkg/testsuite/pass/fancy-lib/pkg.rs
Normal file
23
src/librustpkg/testsuite/pass/fancy-lib/pkg.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::run;
|
||||
|
||||
pub fn main() {
|
||||
let cwd = os::getcwd();
|
||||
debug!("cwd = %s", cwd.to_str());
|
||||
let file = io::file_writer(&Path(~"fancy-lib/build/generated.rs"),
|
||||
[io::Create]).get();
|
||||
file.write_str("pub fn wheeeee() { for [1, 2, 3].each() |_| { assert!(true); } }");
|
||||
|
||||
// now compile the crate itself
|
||||
run::run_program("rustc", ~[~"fancy-lib/fancy-lib.rs", ~"--lib",
|
||||
~"-o", ~"fancy-lib/build/fancy_lib"]);
|
||||
}
|
25
src/librustpkg/testsuite/pass/hello-world/main.rs
Normal file
25
src/librustpkg/testsuite/pass/hello-world/main.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg build hello-world`:
|
||||
* testsuite/pass/hello-world/build/ exists
|
||||
* testsuite/pass/hello-world/build/ contains an executable named hello-world
|
||||
* testsuite/pass/hello-world/build/ does not contain a library
|
||||
|
||||
It should also check that after `rustpkg clean hello-world`:
|
||||
* testsuite/pass/hello-world/build is empty
|
||||
*/
|
||||
|
||||
use core::io;
|
||||
|
||||
fn main() {
|
||||
io::println(~"Hello world!");
|
||||
}
|
17
src/librustpkg/testsuite/pass/install-paths/bench.rs
Normal file
17
src/librustpkg/testsuite/pass/install-paths/bench.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[bench]
|
||||
fn g() {
|
||||
let mut x = 0;
|
||||
while(x < 1000) {
|
||||
x += 1;
|
||||
}
|
||||
}
|
11
src/librustpkg/testsuite/pass/install-paths/lib.rs
Normal file
11
src/librustpkg/testsuite/pass/install-paths/lib.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn f() -> int { 42 }
|
22
src/librustpkg/testsuite/pass/install-paths/main.rs
Normal file
22
src/librustpkg/testsuite/pass/install-paths/main.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg install install-paths`
|
||||
with RUST_PATH undefined in the environment:
|
||||
* ./.rust/install_paths exists and is an executable
|
||||
* ./.rust/libinstall_paths exists and is a library
|
||||
* ./.rust/install_pathstest does not exist
|
||||
* ./.rust/install_pathsbench does not exist
|
||||
* install-paths/build/install_pathstest exists and is an executable
|
||||
* install-paths/build/install_pathsbench exists and is an executable
|
||||
*/
|
||||
|
||||
fn main() {}
|
14
src/librustpkg/testsuite/pass/install-paths/test.rs
Normal file
14
src/librustpkg/testsuite/pass/install-paths/test.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[test]
|
||||
fn test_two_plus_two() {
|
||||
assert!(2 + 2 == 4);
|
||||
}
|
13
src/librustpkg/testsuite/pass/simple-lib/bar.rs
Normal file
13
src/librustpkg/testsuite/pass/simple-lib/bar.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn assert_true() {
|
||||
assert!(true);
|
||||
}
|
12
src/librustpkg/testsuite/pass/simple-lib/foo.rs
Normal file
12
src/librustpkg/testsuite/pass/simple-lib/foo.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn do_nothing() {
|
||||
}
|
21
src/librustpkg/testsuite/pass/simple-lib/lib.rs
Normal file
21
src/librustpkg/testsuite/pass/simple-lib/lib.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg build simple-lib`:
|
||||
* testsuite/simple-lib/build/ exists
|
||||
* testsuite/simple-lib/build/ contains a library named libsimple_lib
|
||||
* testsuite/simple-lib/build/ does not contain an executable
|
||||
*/
|
||||
|
||||
extern mod std;
|
||||
|
||||
pub mod foo;
|
||||
pub mod bar;
|
21
src/librustpkg/testsuite/pass/simple-lib/simple-lib.rc
Normal file
21
src/librustpkg/testsuite/pass/simple-lib/simple-lib.rc
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
The test runner should check that, after `rustpkg build simple-lib`:
|
||||
* testsuite/simple-lib/build/ exists
|
||||
* testsuite/simple-lib/build/ contains a library named libsimple_lib
|
||||
* testsuite/simple-lib/build/ does not contain an executable
|
||||
*/
|
||||
|
||||
extern mod std;
|
||||
|
||||
pub mod foo;
|
||||
pub mod bar;
|
@ -12,16 +12,20 @@ use core::*;
|
||||
use core::cmp::Ord;
|
||||
use core::hash::Streaming;
|
||||
use rustc::driver::{driver, session};
|
||||
use rustc::driver::session::{lib_crate, bin_crate, unknown_crate};
|
||||
use rustc::metadata::filesearch;
|
||||
use std::getopts::groups::getopts;
|
||||
use std::semver;
|
||||
use std::{json, term, getopts};
|
||||
use syntax::ast_util::*;
|
||||
use syntax::codemap::{dummy_sp};
|
||||
use syntax::codemap::{dummy_sp, spanned, dummy_spanned};
|
||||
use syntax::ext::base::{mk_ctxt, ext_ctxt};
|
||||
use syntax::ext::build;
|
||||
use syntax::{ast, attr, codemap, diagnostic, fold};
|
||||
use syntax::ast::{meta_name_value, meta_list, attribute, crate_};
|
||||
use syntax::attr::{mk_attr};
|
||||
use rustc::back::link::output_type_exe;
|
||||
use rustc::driver::session::{lib_crate, bin_crate, unknown_crate, crate_type};
|
||||
|
||||
pub type ExitCode = int; // For now
|
||||
|
||||
@ -112,7 +116,7 @@ pub impl PkgId {
|
||||
impl ToStr for PkgId {
|
||||
fn to_str(&self) -> ~str {
|
||||
// should probably use the filestem and not the whole path
|
||||
fmt!("%s-v%s", self.path.to_str(), self.version.to_str())
|
||||
fmt!("%s-%s", self.path.to_str(), self.version.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,44 +429,51 @@ pub fn add_pkg(pkg: &Pkg) -> bool {
|
||||
|
||||
// FIXME (#4432): Use workcache to only compile when needed
|
||||
pub fn compile_input(sysroot: Option<Path>,
|
||||
pkg_id: PkgId,
|
||||
in_file: &Path,
|
||||
out_dir: &Path,
|
||||
flags: ~[~str],
|
||||
cfgs: ~[~str],
|
||||
opt: bool,
|
||||
test: bool) -> bool {
|
||||
test: bool,
|
||||
crate_type: session::crate_type) -> bool {
|
||||
|
||||
let short_name = pkg_id.to_str();
|
||||
|
||||
assert!(in_file.components.len() > 1);
|
||||
let input = driver::file_input(copy *in_file);
|
||||
debug!("compile_input: %s", in_file.to_str());
|
||||
debug!("compile_input: %s / %?", in_file.to_str(), crate_type);
|
||||
// tjc: by default, use the package ID name as the link name
|
||||
// not sure if we should support anything else
|
||||
let short_name = in_file.filestem().expect("Can't compile a directory!");
|
||||
debug!("short_name = %s", short_name.to_str());
|
||||
|
||||
// Right now we're always assuming that we're building a library.
|
||||
// What we should do is parse the crate and infer whether it's a library
|
||||
// from the absence or presence of a main fn
|
||||
let out_file = out_dir.push(os::dll_filename(short_name));
|
||||
let building_library = true;
|
||||
let binary = os::args()[0];
|
||||
let building_library = match crate_type {
|
||||
lib_crate | unknown_crate => true,
|
||||
_ => false
|
||||
};
|
||||
|
||||
let out_file = if building_library {
|
||||
out_dir.push(os::dll_filename(short_name))
|
||||
}
|
||||
else {
|
||||
out_dir.push(short_name + if test { ~"test" } else { ~"" }
|
||||
+ os::EXE_SUFFIX)
|
||||
};
|
||||
|
||||
debug!("compiling %s into %s",
|
||||
in_file.to_str(),
|
||||
out_file.to_str());
|
||||
|
||||
let binary = os::args()[0];
|
||||
|
||||
debug!("flags: %s", str::connect(flags, ~" "));
|
||||
debug!("cfgs: %s", str::connect(cfgs, ~" "));
|
||||
// Again, we assume we're building a library
|
||||
|
||||
let matches = getopts(~[~"-Z", ~"time-passes"]
|
||||
+ if building_library { ~[~"--lib"] } else { ~[] }
|
||||
+ if building_library { ~[~"--lib"] }
|
||||
else { ~[] }
|
||||
+ flags
|
||||
+ cfgs.flat_map(|&c| { ~[~"--cfg", c] }),
|
||||
driver::optgroups()).get();
|
||||
let options = @session::options {
|
||||
crate_type: if building_library { session::lib_crate }
|
||||
else { session::bin_crate },
|
||||
crate_type: crate_type,
|
||||
optimize: if opt { session::Aggressive } else { session::No },
|
||||
test: test,
|
||||
maybe_sysroot: sysroot,
|
||||
@ -485,7 +496,9 @@ pub fn compile_input(sysroot: Option<Path>,
|
||||
|
||||
debug!("calling compile_crate_from_input, out_dir = %s,
|
||||
building_library = %?", out_dir.to_str(), sess.building_library);
|
||||
compile_crate_from_input(input, Some(*out_dir), sess, None, binary);
|
||||
let _ = compile_crate_from_input(input, pkg_id, Some(*out_dir), sess, None,
|
||||
out_file, binary,
|
||||
driver::cu_everything);
|
||||
true
|
||||
}
|
||||
|
||||
@ -493,24 +506,46 @@ pub fn compile_input(sysroot: Option<Path>,
|
||||
// Should also rename this to something better
|
||||
// If crate_opt is present, then finish compilation. If it's None, then
|
||||
// call compile_upto and return the crate
|
||||
pub fn compile_crate_from_input(input: driver::input, build_dir_opt: Option<Path>,
|
||||
sess: session::Session, crate_opt: Option<@ast::crate>,
|
||||
binary: ~str) -> @ast::crate {
|
||||
// also, too many arguments
|
||||
pub fn compile_crate_from_input(input: driver::input,
|
||||
pkg_id: PkgId,
|
||||
build_dir_opt: Option<Path>,
|
||||
sess: session::Session,
|
||||
crate_opt: Option<@ast::crate>,
|
||||
out_file: Path,
|
||||
binary: ~str,
|
||||
what: driver::compile_upto) -> @ast::crate {
|
||||
debug!("Calling build_output_filenames with %?", build_dir_opt);
|
||||
let outputs = driver::build_output_filenames(input, &build_dir_opt, &None, sess);
|
||||
let outputs = driver::build_output_filenames(input, &build_dir_opt, &Some(out_file), sess);
|
||||
debug!("Outputs are %? and output type = %?", outputs, sess.opts.output_type);
|
||||
let cfg = driver::build_configuration(sess, binary, input);
|
||||
match crate_opt {
|
||||
Some(c) => {
|
||||
debug!("Calling compile_rest, outputs = %?", outputs);
|
||||
assert!(what == driver::cu_everything);
|
||||
driver::compile_rest(sess, cfg, driver::cu_everything, Some(outputs), Some(c));
|
||||
c
|
||||
}
|
||||
None => {
|
||||
debug!("Calling compile_upto, outputs = %?", outputs);
|
||||
let (crate, _) = driver::compile_upto(sess, cfg, input, driver::cu_parse,
|
||||
Some(outputs));
|
||||
crate
|
||||
let (crate, _) = driver::compile_upto(sess, cfg, input,
|
||||
driver::cu_parse, Some(outputs));
|
||||
|
||||
// Inject the inferred link_meta info if it's not already there
|
||||
// (assumes that name and vers are the only linkage metas)
|
||||
let mut crate_to_use = crate;
|
||||
if attr::find_linkage_metas(crate.node.attrs).is_empty() {
|
||||
crate_to_use = add_attrs(*crate, ~[mk_attr(@dummy_spanned(meta_list(@~"link",
|
||||
// change PkgId to have a <shortname> field?
|
||||
~[@dummy_spanned(meta_name_value(@~"name",
|
||||
mk_string_lit(@pkg_id.path.filestem().get()))),
|
||||
@dummy_spanned(meta_name_value(@~"vers",
|
||||
mk_string_lit(@pkg_id.version.to_str())))])))]);
|
||||
}
|
||||
|
||||
|
||||
driver::compile_rest(sess, cfg, what, Some(outputs), Some(crate_to_use));
|
||||
crate_to_use
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -525,17 +560,30 @@ pub fn exe_suffix() -> ~str { ~".exe" }
|
||||
pub fn exe_suffix() -> ~str { ~"" }
|
||||
|
||||
|
||||
/// Returns a copy of crate `c` with attributes `attrs` added to its
|
||||
/// attributes
|
||||
fn add_attrs(c: ast::crate, new_attrs: ~[attribute]) -> @ast::crate {
|
||||
@spanned {
|
||||
node: crate_ {
|
||||
attrs: c.node.attrs + new_attrs, ..c.node
|
||||
},
|
||||
span: c.span
|
||||
}
|
||||
}
|
||||
|
||||
// Called by build_crates
|
||||
// FIXME (#4432): Use workcache to only compile when needed
|
||||
pub fn compile_crate(sysroot: Option<Path>, crate: &Path, dir: &Path,
|
||||
pub fn compile_crate(sysroot: Option<Path>, pkg_id: PkgId,
|
||||
crate: &Path, dir: &Path,
|
||||
flags: ~[~str], cfgs: ~[~str], opt: bool,
|
||||
test: bool) -> bool {
|
||||
test: bool, crate_type: crate_type) -> bool {
|
||||
debug!("compile_crate: crate=%s, dir=%s", crate.to_str(), dir.to_str());
|
||||
debug!("compile_crate: flags =...");
|
||||
debug!("compile_crate: short_name = %s, flags =...", pkg_id.to_str());
|
||||
for flags.each |&fl| {
|
||||
debug!("+++ %s", fl);
|
||||
}
|
||||
compile_input(sysroot, crate, dir, flags, cfgs, opt, test)
|
||||
compile_input(sysroot, pkg_id,
|
||||
crate, dir, flags, cfgs, opt, test, crate_type)
|
||||
}
|
||||
|
||||
|
||||
@ -563,6 +611,13 @@ pub fn link_exe(src: &Path, dest: &Path) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_string_lit(s: @~str) -> ast::lit {
|
||||
spanned {
|
||||
node: ast::lit_str(s),
|
||||
span: dummy_sp()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{is_cmd, parse_name};
|
||||
|
Loading…
x
Reference in New Issue
Block a user