checkpoint
This commit is contained in:
parent
d6f455ebca
commit
e0f72e2298
2 changed files with 200 additions and 68 deletions
|
@ -281,7 +281,13 @@ impl Ctx {
|
||||||
|
|
||||||
match cmd {
|
match cmd {
|
||||||
~"build" => {
|
~"build" => {
|
||||||
self.build(&os::getcwd(), true, false, false);
|
if args.len() < 1 {
|
||||||
|
return usage::build();
|
||||||
|
}
|
||||||
|
let pkgid = PkgId::new(args[0]);
|
||||||
|
let mut src = PkgSrc::new(&Path("."), &pkgid);
|
||||||
|
src.find_crates();
|
||||||
|
src.build(&Path("."));
|
||||||
}
|
}
|
||||||
~"clean" => {
|
~"clean" => {
|
||||||
self.clean();
|
self.clean();
|
||||||
|
@ -927,7 +933,7 @@ pub fn main() {
|
||||||
|
|
||||||
/// A crate is a unit of Rust code to be compiled into a binary or library
|
/// A crate is a unit of Rust code to be compiled into a binary or library
|
||||||
pub struct Crate {
|
pub struct Crate {
|
||||||
file: ~str,
|
file: Path,
|
||||||
flags: ~[~str],
|
flags: ~[~str],
|
||||||
cfgs: ~[~str]
|
cfgs: ~[~str]
|
||||||
}
|
}
|
||||||
|
@ -959,28 +965,37 @@ pub fn run(listeners: ~[Listener]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl Crate {
|
pub impl Crate {
|
||||||
pub fn flag(&self, flag: ~str) -> Crate {
|
|
||||||
|
static fn new(p: &Path) -> Crate {
|
||||||
|
Crate {
|
||||||
|
file: copy *p,
|
||||||
|
flags: ~[],
|
||||||
|
cfgs: ~[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flag(&self, flag: ~str) -> Crate {
|
||||||
Crate {
|
Crate {
|
||||||
flags: vec::append(copy self.flags, ~[flag]),
|
flags: vec::append(copy self.flags, ~[flag]),
|
||||||
.. copy *self
|
.. copy *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flags(&self, flags: ~[~str]) -> Crate {
|
fn flags(&self, flags: ~[~str]) -> Crate {
|
||||||
Crate {
|
Crate {
|
||||||
flags: vec::append(copy self.flags, flags),
|
flags: vec::append(copy self.flags, flags),
|
||||||
.. copy *self
|
.. copy *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cfg(&self, cfg: ~str) -> Crate {
|
fn cfg(&self, cfg: ~str) -> Crate {
|
||||||
Crate {
|
Crate {
|
||||||
cfgs: vec::append(copy self.cfgs, ~[cfg]),
|
cfgs: vec::append(copy self.cfgs, ~[cfg]),
|
||||||
.. copy *self
|
.. copy *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cfgs(&self, cfgs: ~[~str]) -> Crate {
|
fn cfgs(&self, cfgs: ~[~str]) -> Crate {
|
||||||
Crate {
|
Crate {
|
||||||
cfgs: vec::append(copy self.cfgs, cfgs),
|
cfgs: vec::append(copy self.cfgs, cfgs),
|
||||||
.. copy *self
|
.. copy *self
|
||||||
|
@ -988,15 +1003,6 @@ pub impl Crate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
* Get the working directory of the package script.
|
||||||
* Assumes that the package script has been compiled
|
* Assumes that the package script has been compiled
|
||||||
|
@ -1026,7 +1032,7 @@ pub fn build(crates: ~[Crate]) -> bool {
|
||||||
let test = args[3] == ~"true";
|
let test = args[3] == ~"true";
|
||||||
|
|
||||||
for crates.each |&crate| {
|
for crates.each |&crate| {
|
||||||
let path = &dir.push_rel(&Path(crate.file)).normalize();
|
let path = &dir.push_rel(&crate.file).normalize();
|
||||||
|
|
||||||
util::note(fmt!("compiling %s", path.to_str()));
|
util::note(fmt!("compiling %s", path.to_str()));
|
||||||
|
|
||||||
|
@ -1043,3 +1049,155 @@ pub fn build(crates: ~[Crate]) -> bool {
|
||||||
|
|
||||||
success
|
success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Path-fragment identifier of a package such as
|
||||||
|
// 'github.com/graydon/test'; must be a relative
|
||||||
|
// path with >=1 component.
|
||||||
|
struct PkgId {
|
||||||
|
path: Path
|
||||||
|
}
|
||||||
|
|
||||||
|
condition! {
|
||||||
|
bad_pkg_id: (::core::path::Path, ~str) -> ::PkgId;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PkgId {
|
||||||
|
static fn new(s: &str) -> PkgId {
|
||||||
|
use bad_pkg_id::cond;
|
||||||
|
|
||||||
|
let p = Path(s);
|
||||||
|
if p.is_absolute {
|
||||||
|
return cond.raise((p, ~"absolute pkgid"));
|
||||||
|
}
|
||||||
|
if p.components.len() < 1 {
|
||||||
|
return cond.raise((p, ~"0-length pkgid"));
|
||||||
|
}
|
||||||
|
PkgId {
|
||||||
|
path: p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// An enumeration of the unpacked source of a package workspace.
|
||||||
|
// This contains a list of files found in the source workspace.
|
||||||
|
pub struct PkgSrc {
|
||||||
|
root: Path,
|
||||||
|
id: PkgId,
|
||||||
|
libs: ~[Crate],
|
||||||
|
mains: ~[Crate],
|
||||||
|
tests: ~[Crate],
|
||||||
|
benchs: ~[Crate],
|
||||||
|
}
|
||||||
|
|
||||||
|
condition! {
|
||||||
|
bad_path: (::core::path::Path, ~str) -> ::core::path::Path;
|
||||||
|
}
|
||||||
|
|
||||||
|
condition! {
|
||||||
|
build_err: (~str) -> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PkgSrc {
|
||||||
|
|
||||||
|
|
||||||
|
static fn new(fs_root: &Path, id: &PkgId) -> PkgSrc {
|
||||||
|
PkgSrc {
|
||||||
|
root: copy *fs_root,
|
||||||
|
id: copy *id,
|
||||||
|
libs: ~[],
|
||||||
|
mains: ~[],
|
||||||
|
tests: ~[],
|
||||||
|
benchs: ~[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn check_dir(&self) -> Path {
|
||||||
|
use bad_path::cond;
|
||||||
|
|
||||||
|
let dir = self.root.push_rel(&self.id.path).normalize();
|
||||||
|
|
||||||
|
if ! os::path_exists(&dir) {
|
||||||
|
return cond.raise((dir, ~"missing package dir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! os::path_is_dir(&dir) {
|
||||||
|
return cond.raise((dir, ~"missing package dir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
dir
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn has_pkg_file(&self) -> bool {
|
||||||
|
let dir = self.check_dir();
|
||||||
|
dir.push("pkg.rs").exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) {
|
||||||
|
assert p.components.len() > prefix;
|
||||||
|
let mut sub = Path("");
|
||||||
|
for vec::slice(p.components, prefix,
|
||||||
|
p.components.len()).each |c| {
|
||||||
|
sub = sub.push(*c);
|
||||||
|
}
|
||||||
|
debug!("found crate %s", sub.to_str());
|
||||||
|
cs.push(Crate::new(&sub));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_crates(&mut self) {
|
||||||
|
use PkgSrc::push_crate;
|
||||||
|
assert ! self.has_pkg_file();
|
||||||
|
let dir = self.check_dir();
|
||||||
|
let prefix = dir.components.len();
|
||||||
|
for os::walk_dir(&dir) |pth| {
|
||||||
|
match pth.filename() {
|
||||||
|
Some(~"lib.rs") => push_crate(&mut self.libs,
|
||||||
|
prefix, pth),
|
||||||
|
Some(~"main.rs") => push_crate(&mut self.mains,
|
||||||
|
prefix, pth),
|
||||||
|
Some(~"test.rs") => push_crate(&mut self.tests,
|
||||||
|
prefix, pth),
|
||||||
|
Some(~"bench.rs") => push_crate(&mut self.benchs,
|
||||||
|
prefix, pth),
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug!("found %u libs, %u mains, %u tests, %u benchs",
|
||||||
|
self.libs.len(),
|
||||||
|
self.mains.len(),
|
||||||
|
self.tests.len(),
|
||||||
|
self.benchs.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static fn build_crates(dst_dir: &Path,
|
||||||
|
src_dir: &Path,
|
||||||
|
crates: &[Crate],
|
||||||
|
test: bool) {
|
||||||
|
|
||||||
|
for crates.each |&crate| {
|
||||||
|
let path = &src_dir.push_rel(&crate.file).normalize();
|
||||||
|
util::note(fmt!("compiling %s", path.to_str()));
|
||||||
|
if ! util::compile_crate(None, path,
|
||||||
|
dst_dir,
|
||||||
|
crate.flags,
|
||||||
|
crate.cfgs,
|
||||||
|
false, test) {
|
||||||
|
build_err::cond.raise(fmt!("build failure on %s",
|
||||||
|
path.to_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(&self, dst_dir: &Path) {
|
||||||
|
let dir = self.check_dir();
|
||||||
|
PkgSrc::build_crates(dst_dir, &dir, self.libs, false);
|
||||||
|
PkgSrc::build_crates(dst_dir, &dir, self.mains, false);
|
||||||
|
PkgSrc::build_crates(dst_dir, &dir, self.tests, true);
|
||||||
|
PkgSrc::build_crates(dst_dir, &dir, self.benchs, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -597,11 +597,23 @@ pub fn remove_pkg(pkg: &Package) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
pub fn compile_input(sysroot: Option<Path>,
|
||||||
flags: ~[~str], cfgs: ~[~str], opt: bool, test: bool) -> bool {
|
in_file: &Path,
|
||||||
let lib_dir = dir.push(~"lib");
|
out_dir: &Path,
|
||||||
let bin_dir = dir.push(~"bin");
|
flags: ~[~str],
|
||||||
let test_dir = dir.push(~"test");
|
cfgs: ~[~str],
|
||||||
|
opt: bool,
|
||||||
|
test: bool) -> bool {
|
||||||
|
|
||||||
|
assert in_file.components.len() > 1;
|
||||||
|
let input = driver::file_input(copy *in_file);
|
||||||
|
let short_name = in_file.pop().filename().get();
|
||||||
|
let out_file = out_dir.push(os::dll_filename(short_name));
|
||||||
|
|
||||||
|
debug!("compiling %s into %s",
|
||||||
|
in_file.to_str(),
|
||||||
|
out_file.to_str());
|
||||||
|
|
||||||
let binary = os::args()[0];
|
let binary = os::args()[0];
|
||||||
let matches = getopts(flags, driver::optgroups()).get();
|
let matches = getopts(flags, driver::optgroups()).get();
|
||||||
let options = @session::options {
|
let options = @session::options {
|
||||||
|
@ -630,15 +642,12 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
||||||
|
|
||||||
let mut name = None;
|
let mut name = None;
|
||||||
let mut vers = None;
|
let mut vers = None;
|
||||||
let mut uuid = None;
|
|
||||||
let mut crate_type = None;
|
let mut crate_type = None;
|
||||||
|
|
||||||
fn load_link_attr(mis: ~[@ast::meta_item]) -> (Option<~str>,
|
fn load_link_attr(mis: ~[@ast::meta_item]) -> (Option<~str>,
|
||||||
Option<~str>,
|
|
||||||
Option<~str>) {
|
Option<~str>) {
|
||||||
let mut name = None;
|
let mut name = None;
|
||||||
let mut vers = None;
|
let mut vers = None;
|
||||||
let mut uuid = None;
|
|
||||||
|
|
||||||
for mis.each |a| {
|
for mis.each |a| {
|
||||||
match a.node {
|
match a.node {
|
||||||
|
@ -647,7 +656,6 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
||||||
match *v {
|
match *v {
|
||||||
~"name" => name = Some(*s),
|
~"name" => name = Some(*s),
|
||||||
~"vers" => vers = Some(*s),
|
~"vers" => vers = Some(*s),
|
||||||
~"uuid" => uuid = Some(*s),
|
|
||||||
_ => { }
|
_ => { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,7 +663,7 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(name, vers, uuid)
|
(name, vers)
|
||||||
}
|
}
|
||||||
|
|
||||||
for crate.node.attrs.each |a| {
|
for crate.node.attrs.each |a| {
|
||||||
|
@ -670,11 +678,10 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
||||||
ast::meta_list(v, mis) => {
|
ast::meta_list(v, mis) => {
|
||||||
match *v {
|
match *v {
|
||||||
~"link" => {
|
~"link" => {
|
||||||
let (n, v, u) = load_link_attr(mis);
|
let (n, v) = load_link_attr(mis);
|
||||||
|
|
||||||
name = n;
|
name = n;
|
||||||
vers = v;
|
vers = v;
|
||||||
uuid = u;
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -683,16 +690,6 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.is_none() || vers.is_none() || uuid.is_none() {
|
|
||||||
error(~"link attr without (name, vers, uuid) values");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = name.get();
|
|
||||||
let vers = vers.get();
|
|
||||||
let uuid = uuid.get();
|
|
||||||
|
|
||||||
let is_bin = match crate_type {
|
let is_bin = match crate_type {
|
||||||
Some(crate_type) => {
|
Some(crate_type) => {
|
||||||
match crate_type {
|
match crate_type {
|
||||||
|
@ -712,29 +709,14 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if test {
|
outputs = driver::build_output_filenames(input,
|
||||||
need_dir(&test_dir);
|
&Some(copy *out_dir),
|
||||||
|
&Some(out_file),
|
||||||
outputs = driver::build_output_filenames(input, &Some(test_dir),
|
sess);
|
||||||
&None, sess)
|
|
||||||
}
|
|
||||||
else if is_bin {
|
|
||||||
need_dir(&bin_dir);
|
|
||||||
|
|
||||||
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);
|
|
||||||
} else {
|
|
||||||
need_dir(&lib_dir);
|
|
||||||
|
|
||||||
outputs = driver::build_output_filenames(input, &Some(lib_dir),
|
|
||||||
&None, sess)
|
|
||||||
}
|
|
||||||
|
|
||||||
driver::compile_rest(sess, cfg, driver::cu_everything,
|
driver::compile_rest(sess, cfg, driver::cu_everything,
|
||||||
Some(outputs), Some(crate));
|
Some(outputs),
|
||||||
|
Some(crate));
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -753,15 +735,7 @@ pub fn exe_suffix() -> ~str { ~"" }
|
||||||
pub fn compile_crate(sysroot: Option<Path>, crate: &Path, dir: &Path,
|
pub fn compile_crate(sysroot: Option<Path>, crate: &Path, dir: &Path,
|
||||||
flags: ~[~str], cfgs: ~[~str], opt: bool,
|
flags: ~[~str], cfgs: ~[~str], opt: bool,
|
||||||
test: bool) -> bool {
|
test: bool) -> bool {
|
||||||
compile_input(sysroot, driver::file_input(*crate), dir, flags, cfgs,
|
compile_input(sysroot, crate, dir, flags, cfgs, opt, test)
|
||||||
opt, test)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn compile_str(sysroot: Option<Path>, 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)]
|
#[cfg(windows)]
|
||||||
|
|
Loading…
Reference in a new issue