diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustpkg/rustpkg.rc | 190 | ||||
| -rw-r--r-- | src/librustpkg/util.rs | 78 |
2 files changed, 200 insertions, 68 deletions
diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index bf1301868af..86802c65781 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -281,7 +281,13 @@ impl Ctx { match cmd { ~"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" => { 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 pub struct Crate { - file: ~str, + file: Path, flags: ~[~str], cfgs: ~[~str] } @@ -959,28 +965,37 @@ pub fn run(listeners: ~[Listener]) { } 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 { flags: vec::append(copy self.flags, ~[flag]), .. copy *self } } - pub fn flags(&self, flags: ~[~str]) -> Crate { + fn flags(&self, flags: ~[~str]) -> Crate { Crate { flags: vec::append(copy self.flags, flags), .. copy *self } } - pub fn cfg(&self, cfg: ~str) -> Crate { + fn cfg(&self, cfg: ~str) -> Crate { Crate { cfgs: vec::append(copy self.cfgs, ~[cfg]), .. copy *self } } - pub fn cfgs(&self, cfgs: ~[~str]) -> Crate { + fn cfgs(&self, cfgs: ~[~str]) -> Crate { Crate { cfgs: vec::append(copy self.cfgs, cfgs), .. 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. * Assumes that the package script has been compiled @@ -1026,7 +1032,7 @@ pub fn build(crates: ~[Crate]) -> bool { let test = args[3] == ~"true"; 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())); @@ -1043,3 +1049,155 @@ pub fn build(crates: ~[Crate]) -> bool { 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); + } +} \ No newline at end of file diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 9d3751c3de2..776ca398268 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -597,11 +597,23 @@ pub fn remove_pkg(pkg: &Package) -> bool { true } -pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path, - flags: ~[~str], cfgs: ~[~str], opt: bool, test: bool) -> bool { - let lib_dir = dir.push(~"lib"); - let bin_dir = dir.push(~"bin"); - let test_dir = dir.push(~"test"); +pub fn compile_input(sysroot: Option<Path>, + in_file: &Path, + out_dir: &Path, + flags: ~[~str], + 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 matches = getopts(flags, driver::optgroups()).get(); 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 vers = None; - let mut uuid = None; let mut crate_type = None; fn load_link_attr(mis: ~[@ast::meta_item]) -> (Option<~str>, - Option<~str>, Option<~str>) { let mut name = None; let mut vers = None; - let mut uuid = None; for mis.each |a| { match a.node { @@ -647,7 +656,6 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path, match *v { ~"name" => name = 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| { @@ -670,11 +678,10 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path, ast::meta_list(v, mis) => { match *v { ~"link" => { - let (n, v, u) = load_link_attr(mis); + let (n, v) = load_link_attr(mis); name = n; 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 { Some(crate_type) => { match crate_type { @@ -712,29 +709,14 @@ pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path, } }; - if test { - need_dir(&test_dir); - - outputs = driver::build_output_filenames(input, &Some(test_dir), - &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) - } + outputs = driver::build_output_filenames(input, + &Some(copy *out_dir), + &Some(out_file), + sess); driver::compile_rest(sess, cfg, driver::cu_everything, - Some(outputs), Some(crate)); + Some(outputs), + Some(crate)); true } @@ -753,15 +735,7 @@ pub fn exe_suffix() -> ~str { ~"" } pub fn compile_crate(sysroot: Option<Path>, crate: &Path, dir: &Path, flags: ~[~str], cfgs: ~[~str], opt: bool, test: bool) -> bool { - compile_input(sysroot, driver::file_input(*crate), dir, flags, cfgs, - opt, test) -} - -pub fn compile_str(sysroot: Option<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) + compile_input(sysroot, crate, dir, flags, cfgs, opt, test) } #[cfg(windows)] |
