@@ -281,7 +281,13 @@ impl Ctx {
281
281
282
282
match cmd {
283
283
~"build" => {
284
- self.build(&os::getcwd(), true, false, false);
284
+ if args.len() < 1 {
285
+ return usage::build();
286
+ }
287
+ let pkgid = PkgId::new(args[0]);
288
+ let mut src = PkgSrc::new(&Path("."), &pkgid);
289
+ src.find_crates();
290
+ src.build(&Path("."));
285
291
}
286
292
~"clean" => {
287
293
self.clean();
@@ -927,7 +933,7 @@ pub fn main() {
927
933
928
934
/// A crate is a unit of Rust code to be compiled into a binary or library
929
935
pub struct Crate {
930
- file: ~str ,
936
+ file: Path ,
931
937
flags: ~[~str],
932
938
cfgs: ~[~str]
933
939
}
@@ -959,44 +965,44 @@ pub fn run(listeners: ~[Listener]) {
959
965
}
960
966
961
967
pub impl Crate {
962
- pub fn flag(&self, flag: ~str) -> Crate {
968
+
969
+ static fn new(p: &Path) -> Crate {
970
+ Crate {
971
+ file: copy *p,
972
+ flags: ~[],
973
+ cfgs: ~[]
974
+ }
975
+ }
976
+
977
+ fn flag(&self, flag: ~str) -> Crate {
963
978
Crate {
964
979
flags: vec::append(copy self.flags, ~[flag]),
965
980
.. copy *self
966
981
}
967
982
}
968
983
969
- pub fn flags(&self, flags: ~[~str]) -> Crate {
984
+ fn flags(&self, flags: ~[~str]) -> Crate {
970
985
Crate {
971
986
flags: vec::append(copy self.flags, flags),
972
987
.. copy *self
973
988
}
974
989
}
975
990
976
- pub fn cfg(&self, cfg: ~str) -> Crate {
991
+ fn cfg(&self, cfg: ~str) -> Crate {
977
992
Crate {
978
993
cfgs: vec::append(copy self.cfgs, ~[cfg]),
979
994
.. copy *self
980
995
}
981
996
}
982
997
983
- pub fn cfgs(&self, cfgs: ~[~str]) -> Crate {
998
+ fn cfgs(&self, cfgs: ~[~str]) -> Crate {
984
999
Crate {
985
1000
cfgs: vec::append(copy self.cfgs, cfgs),
986
1001
.. copy *self
987
1002
}
988
1003
}
989
1004
}
990
1005
991
- /// Create a crate target from a source file
992
- pub fn Crate(file: ~str) -> Crate {
993
- Crate {
994
- file: file,
995
- flags: ~[],
996
- cfgs: ~[]
997
- }
998
- }
999
-
1000
1006
/**
1001
1007
* Get the working directory of the package script.
1002
1008
* Assumes that the package script has been compiled
@@ -1026,7 +1032,7 @@ pub fn build(crates: ~[Crate]) -> bool {
1026
1032
let test = args[3] == ~"true";
1027
1033
1028
1034
for crates.each |&crate| {
1029
- let path = &dir.push_rel(&Path( crate.file) ).normalize();
1035
+ let path = &dir.push_rel(&crate.file).normalize();
1030
1036
1031
1037
util::note(fmt!("compiling %s", path.to_str()));
1032
1038
@@ -1043,3 +1049,155 @@ pub fn build(crates: ~[Crate]) -> bool {
1043
1049
1044
1050
success
1045
1051
}
1052
+
1053
+
1054
+ // Path-fragment identifier of a package such as
1055
+ // 'github.com/graydon/test'; must be a relative
1056
+ // path with >=1 component.
1057
+ struct PkgId {
1058
+ path: Path
1059
+ }
1060
+
1061
+ condition! {
1062
+ bad_pkg_id: (::core::path::Path, ~str) -> ::PkgId;
1063
+ }
1064
+
1065
+ impl PkgId {
1066
+ static fn new(s: &str) -> PkgId {
1067
+ use bad_pkg_id::cond;
1068
+
1069
+ let p = Path(s);
1070
+ if p.is_absolute {
1071
+ return cond.raise((p, ~"absolute pkgid"));
1072
+ }
1073
+ if p.components.len() < 1 {
1074
+ return cond.raise((p, ~"0-length pkgid"));
1075
+ }
1076
+ PkgId {
1077
+ path: p
1078
+ }
1079
+ }
1080
+ }
1081
+
1082
+
1083
+ // An enumeration of the unpacked source of a package workspace.
1084
+ // This contains a list of files found in the source workspace.
1085
+ pub struct PkgSrc {
1086
+ root: Path,
1087
+ id: PkgId,
1088
+ libs: ~[Crate],
1089
+ mains: ~[Crate],
1090
+ tests: ~[Crate],
1091
+ benchs: ~[Crate],
1092
+ }
1093
+
1094
+ condition! {
1095
+ bad_path: (::core::path::Path, ~str) -> ::core::path::Path;
1096
+ }
1097
+
1098
+ condition! {
1099
+ build_err: (~str) -> ();
1100
+ }
1101
+
1102
+ impl PkgSrc {
1103
+
1104
+
1105
+ static fn new(fs_root: &Path, id: &PkgId) -> PkgSrc {
1106
+ PkgSrc {
1107
+ root: copy *fs_root,
1108
+ id: copy *id,
1109
+ libs: ~[],
1110
+ mains: ~[],
1111
+ tests: ~[],
1112
+ benchs: ~[]
1113
+ }
1114
+ }
1115
+
1116
+
1117
+ fn check_dir(&self) -> Path {
1118
+ use bad_path::cond;
1119
+
1120
+ let dir = self.root.push_rel(&self.id.path).normalize();
1121
+
1122
+ if ! os::path_exists(&dir) {
1123
+ return cond.raise((dir, ~"missing package dir"));
1124
+ }
1125
+
1126
+ if ! os::path_is_dir(&dir) {
1127
+ return cond.raise((dir, ~"missing package dir"));
1128
+ }
1129
+
1130
+ dir
1131
+ }
1132
+
1133
+
1134
+ fn has_pkg_file(&self) -> bool {
1135
+ let dir = self.check_dir();
1136
+ dir.push("pkg.rs").exists()
1137
+ }
1138
+
1139
+
1140
+ static fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) {
1141
+ assert p.components.len() > prefix;
1142
+ let mut sub = Path("");
1143
+ for vec::slice(p.components, prefix,
1144
+ p.components.len()).each |c| {
1145
+ sub = sub.push(*c);
1146
+ }
1147
+ debug!("found crate %s", sub.to_str());
1148
+ cs.push(Crate::new(&sub));
1149
+ }
1150
+
1151
+ fn find_crates(&mut self) {
1152
+ use PkgSrc::push_crate;
1153
+ assert ! self.has_pkg_file();
1154
+ let dir = self.check_dir();
1155
+ let prefix = dir.components.len();
1156
+ for os::walk_dir(&dir) |pth| {
1157
+ match pth.filename() {
1158
+ Some(~"lib.rs") => push_crate(&mut self.libs,
1159
+ prefix, pth),
1160
+ Some(~"main.rs") => push_crate(&mut self.mains,
1161
+ prefix, pth),
1162
+ Some(~"test.rs") => push_crate(&mut self.tests,
1163
+ prefix, pth),
1164
+ Some(~"bench.rs") => push_crate(&mut self.benchs,
1165
+ prefix, pth),
1166
+ _ => ()
1167
+ }
1168
+ }
1169
+ debug!("found %u libs, %u mains, %u tests, %u benchs",
1170
+ self.libs.len(),
1171
+ self.mains.len(),
1172
+ self.tests.len(),
1173
+ self.benchs.len())
1174
+ }
1175
+
1176
+
1177
+ static fn build_crates(dst_dir: &Path,
1178
+ src_dir: &Path,
1179
+ crates: &[Crate],
1180
+ test: bool) {
1181
+
1182
+ for crates.each |&crate| {
1183
+ let path = &src_dir.push_rel(&crate.file).normalize();
1184
+ util::note(fmt!("compiling %s", path.to_str()));
1185
+ if ! util::compile_crate(None, path,
1186
+ dst_dir,
1187
+ crate.flags,
1188
+ crate.cfgs,
1189
+ false, test) {
1190
+ build_err::cond.raise(fmt!("build failure on %s",
1191
+ path.to_str()));
1192
+ }
1193
+ }
1194
+ }
1195
+
1196
+ fn build(&self, dst_dir: &Path) {
1197
+ let dir = self.check_dir();
1198
+ PkgSrc::build_crates(dst_dir, &dir, self.libs, false);
1199
+ PkgSrc::build_crates(dst_dir, &dir, self.mains, false);
1200
+ PkgSrc::build_crates(dst_dir, &dir, self.tests, true);
1201
+ PkgSrc::build_crates(dst_dir, &dir, self.benchs, true);
1202
+ }
1203
+ }
0 commit comments