Skip to content

Commit 02a0fb9

Browse files
committed
rustpkg: Use workcache
rustpkg now uses the workcache library to avoid recompilation. Hooray!
1 parent bb30f04 commit 02a0fb9

15 files changed

+668
-497
lines changed

src/libextra/workcache.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,15 +493,20 @@ impl<'self, T:Send +
493493
#[test]
494494
fn test() {
495495
use std::io::WriterUtil;
496-
use std::run;
496+
use std::{os, run};
497497

498498
let pth = Path("foo.c");
499499
{
500500
let r = io::file_writer(&pth, [io::Create]);
501501
r.unwrap().write_str("int main() { return 0; }");
502502
}
503503

504-
let cx = Context::new(RWArc::new(Database::new(Path("db.json"))),
504+
let db_path = os::self_exe_path().expect("workcache::test failed").pop().push("db.json");
505+
if os::path_exists(&db_path) {
506+
os::remove_file(&db_path);
507+
}
508+
509+
let cx = Context::new(RWArc::new(Database::new(db_path)),
505510
RWArc::new(Logger::new()),
506511
Arc::new(TreeMap::new()));
507512

src/librustpkg/api.rs

Lines changed: 103 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,101 @@ use crate::*;
1313
use package_id::*;
1414
use package_source::*;
1515
use version::Version;
16+
use workcache_support::*;
1617

18+
use extra::arc::{Arc,RWArc};
19+
use extra::workcache;
20+
use extra::workcache::*;
1721
use std::os;
18-
use std::hashmap::*;
22+
use extra::treemap::TreeMap;
1923

2024
/// Convenience functions intended for calling from pkg.rs
25+
/// p is where to put the cache file for dependencies
26+
pub fn default_ctxt(p: Path) -> BuildCtx {
27+
new_default_ctx(new_workcache_cx(&p), p)
28+
}
2129

22-
fn default_ctxt(p: @Path) -> Ctx {
23-
Ctx {
24-
use_rust_path_hack: false,
25-
sysroot_opt: Some(p),
26-
json: false,
27-
dep_cache: @mut HashMap::new()
30+
pub fn new_default_ctx(c: Context, p: Path) -> BuildCtx {
31+
BuildCtx {
32+
cx: Ctx { use_rust_path_hack: false,
33+
sysroot_opt: p },
34+
workcache_cx: c
2835
}
2936
}
3037

31-
pub fn build_lib(sysroot: @Path, root: Path, name: ~str, version: Version,
32-
lib: Path) {
38+
fn file_is_fresh(path: &str, in_hash: &str) -> bool {
39+
in_hash == digest_file_with_date(&Path(path))
40+
}
3341

34-
let pkg_src = PkgSrc {
35-
root: root,
36-
id: PkgId{ version: version, ..PkgId::new(name)},
37-
libs: ~[mk_crate(lib)],
38-
mains: ~[],
39-
tests: ~[],
40-
benchs: ~[]
41-
};
42-
pkg_src.build(&default_ctxt(sysroot), ~[]);
42+
fn binary_is_fresh(path: &str, in_hash: &str) -> bool {
43+
in_hash == digest_only_date(&Path(path))
4344
}
4445

45-
pub fn build_exe(sysroot: @Path, root: Path, name: ~str, version: Version, main: Path) {
46-
let pkg_src = PkgSrc {
47-
root: root,
48-
id: PkgId{ version: version, ..PkgId::new(name)},
49-
libs: ~[],
50-
mains: ~[mk_crate(main)],
51-
tests: ~[],
52-
benchs: ~[]
46+
47+
pub fn new_workcache_cx(p: &Path) -> Context {
48+
let db_file = p.push("rustpkg_db.json"); // ??? probably wrong
49+
debug!("Workcache database file: %s", db_file.to_str());
50+
let db = RWArc::new(Database::new(db_file));
51+
let lg = RWArc::new(Logger::new());
52+
let cfg = Arc::new(TreeMap::new());
53+
let mut rslt: FreshnessMap = TreeMap::new();
54+
// Set up freshness functions for every type of dependency rustpkg
55+
// knows about
56+
rslt.insert(~"file", file_is_fresh);
57+
rslt.insert(~"binary", binary_is_fresh);
58+
workcache::Context::new_with_freshness(db, lg, cfg, Arc::new(rslt))
59+
}
60+
61+
pub fn build_lib(sysroot: Path, root: Path, name: ~str, version: Version,
62+
lib: Path) {
63+
let cx = default_ctxt(sysroot);
64+
let subroot = root.clone();
65+
let subversion = version.clone();
66+
let sublib = lib.clone();
67+
do cx.workcache_cx.with_prep(name) |prep| {
68+
let pkg_src = PkgSrc {
69+
workspace: subroot.clone(),
70+
start_dir: subroot.push("src").push(name),
71+
id: PkgId{ version: subversion.clone(), ..PkgId::new(name)},
72+
libs: ~[mk_crate(sublib.clone())],
73+
mains: ~[],
74+
tests: ~[],
75+
benchs: ~[]
76+
};
77+
pkg_src.declare_inputs(prep);
78+
let subcx = cx.clone();
79+
let subsrc = pkg_src.clone();
80+
do prep.exec |exec| {
81+
subsrc.clone().build(exec, &subcx.clone(), ~[]);
82+
}
5383
};
54-
pkg_src.build(&default_ctxt(sysroot), ~[]);
84+
}
5585

86+
pub fn build_exe(sysroot: Path, root: Path, name: ~str, version: Version,
87+
main: Path) {
88+
let cx = default_ctxt(sysroot);
89+
let subroot = root.clone();
90+
let submain = main.clone();
91+
do cx.workcache_cx.with_prep(name) |prep| {
92+
let pkg_src = PkgSrc {
93+
workspace: subroot.clone(),
94+
start_dir: subroot.push("src").push(name),
95+
id: PkgId{ version: version.clone(), ..PkgId::new(name)},
96+
libs: ~[],
97+
mains: ~[mk_crate(submain.clone())],
98+
tests: ~[],
99+
benchs: ~[]
100+
};
101+
pkg_src.declare_inputs(prep);
102+
let subsrc = pkg_src.clone();
103+
let subcx = cx.clone();
104+
do prep.exec |exec| {
105+
subsrc.clone().build(exec, &subcx.clone(), ~[]);
106+
}
107+
}
56108
}
57109

58-
pub fn install_lib(sysroot: @Path,
110+
pub fn install_lib(sysroot: Path,
59111
workspace: Path,
60112
name: ~str,
61113
lib_path: Path,
@@ -65,23 +117,33 @@ pub fn install_lib(sysroot: @Path,
65117
debug!("workspace = %s", workspace.to_str());
66118
// make a PkgSrc
67119
let pkg_id = PkgId{ version: version, ..PkgId::new(name)};
68-
let pkg_src = PkgSrc {
69-
root: workspace.clone(),
70-
id: pkg_id.clone(),
71-
libs: ~[mk_crate(lib_path)],
72-
mains: ~[],
73-
tests: ~[],
74-
benchs: ~[]
75-
};
76120
let cx = default_ctxt(sysroot);
77-
pkg_src.build(&cx, ~[]);
121+
let subpath = lib_path.clone();
122+
do cx.workcache_cx.with_prep(pkg_id.to_str()) |prep| {
123+
let pkg_src = PkgSrc {
124+
workspace: workspace.clone(),
125+
start_dir: subpath.push("src").push(name),
126+
id: pkg_id.clone(),
127+
libs: ~[mk_crate(subpath.clone())],
128+
mains: ~[],
129+
tests: ~[],
130+
benchs: ~[]
131+
};
132+
pkg_src.declare_inputs(prep);
133+
let subcx = cx.clone();
134+
let subpkg_src = pkg_src.clone();
135+
do prep.exec |exec| {
136+
subpkg_src.clone().build(exec, &subcx.clone(), ~[]);
137+
}
138+
}
78139
cx.install_no_build(&workspace, &pkg_id);
79140
}
80141

81-
pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version) {
82-
default_ctxt(sysroot).install(&workspace, &PkgId{ version: version,
83-
..PkgId::new(name)});
84-
142+
pub fn install_exe(sysroot: Path, workspace: Path, name: ~str, version: Version) {
143+
let cx = default_ctxt(sysroot);
144+
debug!("install_exe calling with_prep");
145+
let pkgid = PkgId{ version: version, ..PkgId::new(name)};
146+
cx.install(PkgSrc::new(workspace, false, pkgid));
85147
}
86148

87149
fn mk_crate(p: Path) -> Crate {

src/librustpkg/conditions.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@
1212

1313
pub use std::path::Path;
1414
pub use package_id::PkgId;
15+
pub use std::libc;
16+
pub use std::libc::stat;
1517

1618
condition! {
1719
pub bad_path: (Path, ~str) -> Path;
1820
}
1921

22+
condition! {
23+
pub bad_stat: (Path, ~str) -> stat;
24+
}
25+
2026
condition! {
2127
pub nonexistent_package: (PkgId, ~str) -> Path;
2228
}

src/librustpkg/context.rs

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,56 +10,66 @@
1010

1111
// Context data structure used by rustpkg
1212

13-
14-
use std::hashmap::HashMap;
1513
use std::os;
14+
use extra::workcache;
1615

16+
#[deriving(Clone)]
1717
pub struct Ctx {
1818
// If use_rust_path_hack is true, rustpkg searches for sources
1919
// in *package* directories that are in the RUST_PATH (for example,
2020
// FOO/src/bar-0.1 instead of FOO). The flag doesn't affect where
2121
// rustpkg stores build artifacts.
2222
use_rust_path_hack: bool,
23-
// Sysroot -- if this is None, uses rustc filesearch's
24-
// idea of the default
25-
sysroot_opt: Option<@Path>,
26-
// I'm not sure what this is for
27-
json: bool,
28-
// Cache of hashes of things already installed
29-
// though I'm not sure why the value is a bool
30-
dep_cache: @mut HashMap<~str, bool>,
23+
// The root directory containing the Rust standard libraries
24+
sysroot_opt: Path
25+
}
26+
27+
#[deriving(Clone)]
28+
pub struct BuildCtx {
29+
// Context for workcache
30+
workcache_cx: workcache::Context,
31+
// Everything else
32+
cx: Ctx
33+
}
34+
35+
impl BuildCtx {
36+
pub fn sysroot_opt(&self) -> Path {
37+
self.cx.sysroot_opt.clone()
38+
}
39+
40+
pub fn sysroot_to_use(&self) -> Path {
41+
self.cx.sysroot_to_use()
42+
}
43+
}
44+
45+
impl Ctx {
46+
pub fn sysroot_opt(&self) -> Path {
47+
self.sysroot_opt.clone()
48+
}
3149
}
3250

3351
impl Ctx {
3452
/// Debugging
3553
pub fn sysroot_opt_str(&self) -> ~str {
36-
match self.sysroot_opt {
37-
None => ~"[none]",
38-
Some(p) => p.to_str()
39-
}
54+
self.sysroot_opt.to_str()
4055
}
4156

4257
// Hack so that rustpkg can run either out of a rustc target dir,
4358
// or the host dir
44-
pub fn sysroot_to_use(&self) -> Option<@Path> {
45-
if !in_target(self.sysroot_opt) {
46-
self.sysroot_opt
59+
pub fn sysroot_to_use(&self) -> Path {
60+
if !in_target(&self.sysroot_opt) {
61+
self.sysroot_opt.clone()
4762
}
4863
else {
49-
self.sysroot_opt.map(|p| { @p.pop().pop().pop() })
64+
self.sysroot_opt.pop().pop().pop()
5065
}
51-
}
66+
}
5267
}
5368

5469
/// We assume that if ../../rustc exists, then we're running
5570
/// rustpkg from a Rust target directory. This is part of a
5671
/// kludgy hack used to adjust the sysroot.
57-
pub fn in_target(sysroot_opt: Option<@Path>) -> bool {
58-
match sysroot_opt {
59-
None => false,
60-
Some(p) => {
61-
debug!("Checking whether %s is in target", p.to_str());
62-
os::path_is_dir(&p.pop().pop().push("rustc"))
63-
}
64-
}
72+
pub fn in_target(sysroot_opt: &Path) -> bool {
73+
debug!("Checking whether %s is in target", sysroot_opt.to_str());
74+
os::path_is_dir(&sysroot_opt.pop().pop().push("rustc"))
6575
}

src/librustpkg/package_id.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,10 @@ impl PkgId {
5151
// Did the user request a specific version?
5252
let s = match split_version(s) {
5353
Some((path, v)) => {
54-
debug!("s = %s, path = %s, v = %s", s, path, v.to_str());
5554
given_version = Some(v);
5655
path
5756
}
5857
None => {
59-
debug!("%s has no explicit version", s);
6058
s
6159
}
6260
};
@@ -81,7 +79,6 @@ impl PkgId {
8179
}
8280
};
8381

84-
debug!("path = %s", path.to_str());
8582
PkgId {
8683
path: path.clone(),
8784
short_name: short_name.to_owned(),

0 commit comments

Comments
 (0)