Skip to content

Commit

Permalink
rustpkg: Make crates, not packages, the unit of rustpkg dependencies
Browse files Browse the repository at this point in the history
Treating a package as the thing that can have other packages depend on it,
and depends on other packages, was wrong if a package has more than one
crate. Now, rustpkg knows about dependencies between crates in the same
package. This solves the problem reported in #7879 where rustpkg wrongly
discovered a circular dependency between thhe package and itself, and
recursed infinitely.

Closes #7879
  • Loading branch information
catamorphism committed Sep 18, 2013
1 parent 4c6bf48 commit e199790
Show file tree
Hide file tree
Showing 9 changed files with 409 additions and 249 deletions.
57 changes: 21 additions & 36 deletions src/librustpkg/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use context::*;
use crate::*;
use package_id::*;
use package_source::*;
use target::*;
use version::Version;
use workcache_support::*;

Expand Down Expand Up @@ -63,56 +64,40 @@ pub fn new_workcache_context(p: &Path) -> workcache::Context {
pub fn build_lib(sysroot: Path, root: Path, name: ~str, version: Version,
lib: Path) {
let cx = default_context(sysroot);
let subroot = root.clone();
let subversion = version.clone();
let sublib = lib.clone();
do cx.workcache_context.with_prep(name) |prep| {
let pkg_src = PkgSrc {
workspace: subroot.clone(),
start_dir: subroot.push("src").push(name),
id: PkgId{ version: subversion.clone(), ..PkgId::new(name)},
libs: ~[mk_crate(sublib.clone())],
let pkg_src = PkgSrc {
workspace: root.clone(),
start_dir: root.push("src").push(name),
id: PkgId{ version: version, ..PkgId::new(name)},
// n.b. This assumes the package only has one crate
libs: ~[mk_crate(lib)],
mains: ~[],
tests: ~[],
benchs: ~[]
};
pkg_src.declare_inputs(prep);
let subcx = cx.clone();
let subsrc = pkg_src.clone();
do prep.exec |exec| {
subsrc.build(exec, &subcx.clone(), ~[]);
}
};
pkg_src.build(&cx, ~[]);
}

pub fn build_exe(sysroot: Path, root: Path, name: ~str, version: Version,
main: Path) {
let cx = default_context(sysroot);
let subroot = root.clone();
let submain = main.clone();
do cx.workcache_context.with_prep(name) |prep| {
let pkg_src = PkgSrc {
workspace: subroot.clone(),
start_dir: subroot.push("src").push(name),
id: PkgId{ version: version.clone(), ..PkgId::new(name)},
libs: ~[],
mains: ~[mk_crate(submain.clone())],
tests: ~[],
benchs: ~[]
};
pkg_src.declare_inputs(prep);
let subsrc = pkg_src.clone();
let subcx = cx.clone();
do prep.exec |exec| {
subsrc.clone().build(exec, &subcx.clone(), ~[]);
}
}
let pkg_src = PkgSrc {
workspace: root.clone(),
start_dir: root.push("src").push(name),
id: PkgId{ version: version, ..PkgId::new(name)},
libs: ~[],
// n.b. This assumes the package only has one crate
mains: ~[mk_crate(main)],
tests: ~[],
benchs: ~[]
};

pkg_src.build(&cx, ~[]);
}

pub fn install_pkg(sysroot: Path, workspace: Path, name: ~str, version: Version) {
let cx = default_context(sysroot);
let pkgid = PkgId{ version: version, ..PkgId::new(name)};
cx.install(PkgSrc::new(workspace, false, pkgid));
cx.install(PkgSrc::new(workspace, false, pkgid), &Everything);
}

fn mk_crate(p: Path) -> Crate {
Expand Down
11 changes: 11 additions & 0 deletions src/librustpkg/exit_codes.rs
Original file line number Diff line number Diff line change
@@ -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.

pub static copy_failed_code: int = 65;
6 changes: 6 additions & 0 deletions src/librustpkg/package_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ impl PkgId {
}
}

// This is the workcache function name for the *installed*
// binaries for this package (as opposed to the built ones,
// which are per-crate).
pub fn install_tag(&self) -> ~str {
fmt!("install(%s)", self.to_str())
}
}

struct Prefixes {
Expand Down
62 changes: 43 additions & 19 deletions src/librustpkg/package_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use path_util::{find_dir_using_rust_path_hack, default_workspace, make_dir_rwx_r
use util::compile_crate;
use workspace::is_workspace;
use workcache_support;
use workcache_support::crate_tag;
use extra::workcache;

// An enumeration of the unpacked source of a package workspace.
Expand Down Expand Up @@ -231,7 +232,7 @@ impl PkgSrc {
p.filestem().map_default(false, |p| { p == &self.id.short_name.as_slice() })
}

fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) {
pub fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) {
assert!(p.components.len() > prefix);
let mut sub = Path("");
for c in p.components.slice(prefix, p.components.len()).iter() {
Expand Down Expand Up @@ -286,7 +287,6 @@ impl PkgSrc {

fn build_crates(&self,
ctx: &BuildContext,
exec: &mut workcache::Exec,
destination_dir: &Path,
crates: &[Crate],
cfgs: &[~str],
Expand All @@ -297,25 +297,40 @@ impl PkgSrc {
let path_str = path.to_str();
let cfgs = crate.cfgs + cfgs;

let result =
// compile_crate should return the path of the output artifact
compile_crate(ctx,
exec,
&self.id,
&path,
destination_dir,
crate.flags,
cfgs,
false,
what).to_str();
debug!("Result of compiling %s was %s", path_str, result);
do ctx.workcache_context.with_prep(crate_tag(&path)) |prep| {
debug!("Building crate %s, declaring it as an input", path.to_str());
prep.declare_input("file", path.to_str(),
workcache_support::digest_file_with_date(&path));
let subpath = path.clone();
let subcfgs = cfgs.clone();
let subpath_str = path_str.clone();
let subcx = ctx.clone();
let id = self.id.clone();
let sub_dir = destination_dir.clone();
let sub_flags = crate.flags.clone();
do prep.exec |exec| {
let result = compile_crate(&subcx,
exec,
&id,
&subpath,
&sub_dir,
sub_flags,
subcfgs,
false,
what).to_str();
debug!("Result of compiling %s was %s", subpath_str, result);
result
}
};
}
}

/// Declare all the crate files in the package source as inputs
/// (to the package)
pub fn declare_inputs(&self, prep: &mut workcache::Prep) {
let to_do = ~[self.libs.clone(), self.mains.clone(),
self.tests.clone(), self.benchs.clone()];
debug!("In declare inputs, self = %s", self.to_str());
for cs in to_do.iter() {
for c in cs.iter() {
let path = self.start_dir.push_rel(&c.file).normalize();
Expand All @@ -330,7 +345,6 @@ impl PkgSrc {
// It would be better if build returned a Path, but then Path would have to derive
// Encodable.
pub fn build(&self,
exec: &mut workcache::Exec,
build_context: &BuildContext,
cfgs: ~[~str]) -> ~str {
use conditions::not_a_workspace::cond;
Expand Down Expand Up @@ -360,13 +374,23 @@ impl PkgSrc {
let benchs = self.benchs.clone();
debug!("Building libs in %s, destination = %s",
destination_workspace.to_str(), destination_workspace.to_str());
self.build_crates(build_context, exec, &destination_workspace, libs, cfgs, Lib);
self.build_crates(build_context, &destination_workspace, libs, cfgs, Lib);
debug!("Building mains");
self.build_crates(build_context, exec, &destination_workspace, mains, cfgs, Main);
self.build_crates(build_context, &destination_workspace, mains, cfgs, Main);
debug!("Building tests");
self.build_crates(build_context, exec, &destination_workspace, tests, cfgs, Test);
self.build_crates(build_context, &destination_workspace, tests, cfgs, Test);
debug!("Building benches");
self.build_crates(build_context, exec, &destination_workspace, benchs, cfgs, Bench);
self.build_crates(build_context, &destination_workspace, benchs, cfgs, Bench);
destination_workspace.to_str()
}

/// Debugging
pub fn dump_crates(&self) {
let crate_sets = [&self.libs, &self.mains, &self.tests, &self.benchs];
for crate_set in crate_sets.iter() {
for c in crate_set.iter() {
debug!("Built crate: %s", c.file.to_str())
}
}
}
}
Loading

5 comments on commit e199790

@bors
Copy link
Contributor

@bors bors commented on e199790 Sep 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from brson
at catamorphism@e199790

@bors
Copy link
Contributor

@bors bors commented on e199790 Sep 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging catamorphism/rust/rustpkg-issue-7879 = e199790 into auto

@bors
Copy link
Contributor

@bors bors commented on e199790 Sep 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

catamorphism/rust/rustpkg-issue-7879 = e199790 merged ok, testing candidate = 36cc414

@bors
Copy link
Contributor

@bors bors commented on e199790 Sep 19, 2013

@bors
Copy link
Contributor

@bors bors commented on e199790 Sep 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 36cc414

Please sign in to comment.