From 4fe527cd3b34e3ccf4c949696bfce046b3d90bb2 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Wed, 14 Oct 2020 15:36:24 +0200 Subject: concretizer: concretize a virtual root Before this modification the root of a DAG has to be a real package. This commit adds rules to concretize virtual roots. --- lib/spack/spack/cmd/solve.py | 8 +++++++- lib/spack/spack/solver/asp.py | 10 ++++++++-- lib/spack/spack/solver/concretize.lp | 17 +++++++++++++++++ lib/spack/spack/spec.py | 11 +++++++++-- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/lib/spack/spack/cmd/solve.py b/lib/spack/spack/cmd/solve.py index b343861b55..ff6ab4e676 100644 --- a/lib/spack/spack/cmd/solve.py +++ b/lib/spack/spack/cmd/solve.py @@ -119,7 +119,13 @@ def solve(parser, args): # iterate over roots from command line for input_spec in specs: - spec = answer[input_spec.name] + key = input_spec.name + if input_spec.virtual: + providers = [spec.name for spec in answer.values() + if spec.package.provides(key)] + key = providers[0] + + spec = answer[key] # With -y, just print YAML to output. if args.format == 'yaml': diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 9da2677c24..3575d58c03 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1380,7 +1380,9 @@ class SpackSolverSetup(object): check_packages_exist(specs) # get list of all possible dependencies - self.possible_virtuals = set() + self.possible_virtuals = set( + x.name for x in specs if x.virtual + ) possible = spack.package.possible_dependencies( *specs, virtuals=self.possible_virtuals, @@ -1424,7 +1426,11 @@ class SpackSolverSetup(object): self.gen.h1('Spec Constraints') for spec in sorted(specs): - self.gen.fact(fn.root(spec.name)) + if not spec.virtual: + self.gen.fact(fn.root(spec.name)) + else: + self.gen.fact(fn.virtual_root(spec.name)) + for dep in spec.traverse(): self.gen.h2('Spec: %s' % str(dep)) diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index 4688f51c20..e495db4664 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -65,6 +65,7 @@ provider_weight(Dependency, Weight) :- virtual(Virtual), depends_on(Package, Dependency), provider(Dependency, Virtual), pkg_provider_preference(Package, Virtual, Dependency, Weight). + provider_weight(Dependency, Weight) :- virtual(Virtual), depends_on(Package, Dependency), provider(Dependency, Virtual), @@ -80,8 +81,23 @@ provider_weight(Dependency, 100) not pkg_provider_preference(Package, Virtual, Dependency, _), not default_provider_preference(Virtual, Dependency, _). +% Do the same for virtual roots +provider_weight(Package, Weight) + :- virtual_root(Virtual), + provider(Package, Virtual), + default_provider_preference(Virtual, Package, Weight). + +provider_weight(Package, 100) + :- virtual_root(Virtual), + provider(Package, Virtual), + not default_provider_preference(Virtual, Package, _). + % all nodes must be reachable from some root node(Package) :- root(Package). + +1 { root(Package) : provides_virtual(Package, Virtual) } 1 + :- virtual_root(Virtual). + needed(Package) :- root(Package). needed(Dependency) :- needed(Package), depends_on(Package, Dependency). :- node(Package), not needed(Package). @@ -94,6 +110,7 @@ node(Dependency) :- node(Package), depends_on(Package, Dependency). #defined declared_dependency/3. #defined virtual/1. #defined virtual_node/1. +#defined virtual_root/1. #defined provides_virtual/2. #defined external/1. #defined external_spec/2. diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index bddba98d71..235d4ad147 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -2434,9 +2434,16 @@ class Spec(object): # take the best answer opt, i, answer = min(result.answers) - assert self.name in answer + name = self.name + # TODO: Consolidate this code with similar code in solve.py + if self.virtual: + providers = [spec.name for spec in answer.values() + if spec.package.provides(name)] + name = providers[0] - concretized = answer[self.name] + assert name in answer + + concretized = answer[name] self._dup(concretized) self._mark_concrete() -- cgit v1.2.3-70-g09d2