Skip to content

Rootless resolve #3013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/cargo/core/resolver/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ impl EncodableResolve {

Ok(Resolve {
graph: g,
root: root,
features: HashMap::new(),
replacements: replacements,
checksums: checksums,
Expand Down
38 changes: 20 additions & 18 deletions src/cargo/core/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,13 @@ mod encode;
/// is a package and edges represent dependencies between packages.
///
/// Each instance of `Resolve` also understands the full set of features used
/// for each package as well as what the root package is.
/// for each package.
#[derive(PartialEq, Eq, Clone)]
pub struct Resolve {
graph: Graph<PackageId>,
replacements: HashMap<PackageId, PackageId>,
features: HashMap<PackageId, HashSet<String>>,
checksums: HashMap<PackageId, Option<String>>,
root: PackageId,
metadata: Metadata,
}

Expand Down Expand Up @@ -200,10 +199,6 @@ unable to verify that `{0}` is the same as when the lockfile was generated
self.graph.iter()
}

pub fn root(&self) -> &PackageId {
&self.root
}

pub fn deps(&self, pkg: &PackageId) -> Deps {
Deps { edges: self.graph.edges(pkg), resolve: self }
}
Expand Down Expand Up @@ -268,8 +263,7 @@ struct Context<'a> {
}

/// Builds the list of all packages required to build the first argument.
pub fn resolve(root: &PackageId,
summaries: &[(Summary, Method)],
pub fn resolve(summaries: &[(Summary, Method)],
replacements: &[(PackageIdSpec, Dependency)],
registry: &mut Registry) -> CargoResult<Resolve> {
let cx = Context {
Expand All @@ -279,13 +273,12 @@ pub fn resolve(root: &PackageId,
activations: HashMap::new(),
replacements: replacements,
};
let _p = profile::start(format!("resolving: {}", root));
let _p = profile::start(format!("resolving"));
let cx = try!(activate_deps_loop(cx, registry, summaries));

let mut resolve = Resolve {
graph: cx.resolve_graph,
features: cx.resolve_features,
root: root.clone(),
checksums: HashMap::new(),
metadata: BTreeMap::new(),
replacements: cx.resolve_replacements,
Expand Down Expand Up @@ -980,15 +973,24 @@ impl<'a> Context<'a> {
fn check_cycles(resolve: &Resolve,
activations: &HashMap<(String, SourceId), Vec<Rc<Summary>>>)
-> CargoResult<()> {
let mut summaries = HashMap::new();
for summary in activations.values().flat_map(|v| v) {
summaries.insert(summary.package_id(), &**summary);
let summaries: HashMap<&PackageId, &Summary> = activations.values()
.flat_map(|v| v)
.map(|s| (s.package_id(), &**s))
.collect();

// Sort packages to produce user friendly deterministic errors.
let all_packages = resolve.iter().collect::<BinaryHeap<_>>().into_sorted_vec();
let mut checked = HashSet::new();
for pkg in all_packages {
if !checked.contains(pkg) {
try!(visit(resolve,
pkg,
&summaries,
&mut HashSet::new(),
&mut checked))
}
}
return visit(resolve,
resolve.root(),
&summaries,
&mut HashSet::new(),
&mut HashSet::new());
return Ok(());

fn visit<'a>(resolve: &'a Resolve,
id: &'a PackageId,
Expand Down
7 changes: 4 additions & 3 deletions src/cargo/ops/cargo_output_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn metadata_full(ws: &Workspace,

Ok(ExportInfo {
packages: packages,
resolve: Some(MetadataResolve(resolve)),
resolve: Some(MetadataResolve(resolve, try!(ws.current()).package_id().clone())),
version: VERSION,
})
}
Expand All @@ -68,7 +68,7 @@ pub struct ExportInfo {
/// Newtype wrapper to provide a custom `Encodable` implementation.
/// The one from lockfile does not fit because it uses a non-standard
/// format for `PackageId`s
struct MetadataResolve(Resolve);
struct MetadataResolve(Resolve, PackageId);

impl Encodable for MetadataResolve {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
Expand All @@ -85,8 +85,9 @@ impl Encodable for MetadataResolve {
}

let resolve = &self.0;
let root = &self.1;
let encodable = EncodableResolve {
root: resolve.root(),
root: root,
nodes: resolve.iter().map(|id| {
Node {
id: id,
Expand Down
7 changes: 5 additions & 2 deletions src/cargo/ops/cargo_rustc/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct Unit<'a> {
pub struct Context<'a, 'cfg: 'a> {
pub config: &'cfg Config,
pub resolve: &'a Resolve,
pub current_package: PackageId,
pub compilation: Compilation<'cfg>,
pub packages: &'a PackageSet<'cfg>,
pub build_state: Arc<BuildState>,
Expand Down Expand Up @@ -74,10 +75,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
let engine = build_config.exec_engine.as_ref().cloned().unwrap_or({
Arc::new(Box::new(ProcessEngine))
});
let current_package = try!(ws.current()).package_id().clone();
Ok(Context {
host: host_layout,
target: target_layout,
resolve: resolve,
current_package: current_package,
packages: packages,
config: config,
target_info: TargetInfo::default(),
Expand Down Expand Up @@ -274,7 +277,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {

/// Returns the appropriate directory layout for either a plugin or not.
pub fn layout(&self, unit: &Unit) -> LayoutProxy {
let primary = unit.pkg.package_id() == self.resolve.root();
let primary = unit.pkg.package_id() == &self.current_package;
match unit.kind {
Kind::Host => LayoutProxy::new(&self.host, primary),
Kind::Target => LayoutProxy::new(self.target.as_ref()
Expand Down Expand Up @@ -704,7 +707,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
}

pub fn show_warnings(&self, pkg: &PackageId) -> bool {
pkg == self.resolve.root() || pkg.source_id().is_path() ||
pkg == &self.current_package || pkg.source_id().is_path() ||
self.config.extra_verbose()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_rustc/job_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl<'a> JobQueue<'a> {
}

let build_type = if self.is_release { "release" } else { "debug" };
let profile = cx.lib_profile(cx.resolve.root());
let profile = cx.lib_profile(&cx.current_package);
let mut opt_type = String::from(if profile.opt_level == "0" { "unoptimized" }
else { "optimized" });
if profile.debuginfo {
Expand Down
6 changes: 3 additions & 3 deletions src/cargo/ops/cargo_rustc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>,
})
}).collect::<Vec<_>>();

let root = try!(packages.get(resolve.root()));
let root = try!(ws.current());
let mut cx = try!(Context::new(ws, resolve, packages, config,
build_config, profiles));

Expand Down Expand Up @@ -229,7 +229,7 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
let do_rename = unit.target.allows_underscores() && !unit.profile.test;
let real_name = unit.target.name().to_string();
let crate_name = unit.target.crate_name();
let move_outputs_up = unit.pkg.package_id() == cx.resolve.root();
let move_outputs_up = unit.pkg.package_id() == &cx.current_package;

let rustc_dep_info_loc = if do_rename {
root.join(&crate_name)
Expand Down Expand Up @@ -504,7 +504,7 @@ fn build_base_args(cx: &Context,
let prefer_dynamic = (unit.target.for_host() &&
!unit.target.is_custom_build()) ||
(crate_types.contains(&"dylib") &&
unit.pkg.package_id() != cx.resolve.root());
unit.pkg.package_id() != &cx.current_package);
if prefer_dynamic {
cmd.arg("-C").arg("prefer-dynamic");
}
Expand Down
5 changes: 1 addition & 4 deletions src/cargo/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,7 @@ pub fn resolve_with_previous<'a>(registry: &mut PackageRegistry,
None => root_replace.to_vec(),
};

let mut resolved = try!(resolver::resolve(try!(ws.current()).package_id(),
&summaries,
&replace,
registry));
let mut resolved = try!(resolver::resolve(&summaries, &replace, registry));
if let Some(previous) = previous {
try!(resolved.merge_from(previous));
}
Expand Down
2 changes: 1 addition & 1 deletion tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1887,7 +1887,7 @@ fn cyclic_deps_rejected() {
assert_that(p.cargo_process("build").arg("-v"),
execs().with_status(101)
.with_stderr("\
[ERROR] cyclic package dependency: package `foo v0.0.1 ([..])` depends on itself
[ERROR] cyclic package dependency: package `a v0.0.1 ([..])` depends on itself
"));
}

Expand Down
3 changes: 1 addition & 2 deletions tests/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ fn resolve<R: Registry>(pkg: PackageId, deps: Vec<Dependency>,
-> CargoResult<Vec<PackageId>> {
let summary = Summary::new(pkg.clone(), deps, HashMap::new()).unwrap();
let method = Method::Everything;
Ok(try!(resolver::resolve(&pkg,
&[(summary, method)],
Ok(try!(resolver::resolve(&[(summary, method)],
&[],
registry)).iter().map(|p| {
p.clone()
Expand Down