diff options
-rw-r--r-- | lib/spack/spack/solver/asp.py | 41 | ||||
-rw-r--r-- | lib/spack/spack/solver/concretize.lp | 37 |
2 files changed, 60 insertions, 18 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 9de674ab60..167baea0da 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -729,10 +729,17 @@ class SpackSolverSetup(object): def package_dependencies_rules(self, pkg, tests): """Translate 'depends_on' directives into ASP logic.""" for name, conditions in sorted(pkg.dependencies.items()): - for cond, dep in sorted(conditions.items()): + for cond_id, (cond, dep) in enumerate(sorted(conditions.items())): named_cond = cond.copy() named_cond.name = named_cond.name or pkg.name + # each independent condition has an id + self.gen.fact( + fn.dependency_condition( + dep.pkg.name, dep.spec.name, cond_id + ) + ) + for t in sorted(dep.type): # Skip test dependencies if they're not requested at all if t == 'test' and not tests: @@ -743,22 +750,29 @@ class SpackSolverSetup(object): and pkg.name not in tests): continue - if cond == spack.spec.Spec(): + # there is a declared dependency of type t + + # TODO: this ends up being redundant in the output -- + # TODO: not sure if we really need it anymore. + # TODO: Look at simplifying the logic in concretize.lp + self.gen.fact( + fn.declared_dependency(dep.pkg.name, dep.spec.name, t)) + + # if it has conditions, declare them. + conditions = self.spec_clauses(named_cond, body=True) + for cond in conditions: self.gen.fact( - fn.declared_dependency( - dep.pkg.name, dep.spec.name, t + fn.dep_cond( + dep.pkg.name, dep.spec.name, t, cond_id, + cond.name, *cond.args ) ) - else: - clauses = self.spec_clauses(named_cond, body=True) - - self.gen.rule( - fn.declared_dependency( - dep.pkg.name, dep.spec.name, t - ), self.gen._and(*clauses) - ) # add constraints on the dependency from dep spec. + + # TODO: nest this in the type loop so that dependency + # TODO: constraints apply only for their deptypes and + # TODO: specific conditions. if spack.repo.path.is_virtual(dep.spec.name): self.virtual_constraints.add(str(dep.spec)) conditions = ([fn.real_node(pkg.name)] + @@ -779,7 +793,8 @@ class SpackSolverSetup(object): *self.spec_clauses(named_cond, body=True) ) ) - self.gen.newline() + + self.gen.newline() def virtual_preferences(self, pkg_name, func): """Call func(vspec, provider, i) for each of pkg's provider prefs.""" diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index 0affb9f297..7c4e0d6d02 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -40,8 +40,7 @@ depends_on(Package, Dependency) :- depends_on(Package, Dependency, _). % declared dependencies are real if they're not virtual AND % the package is not an external depends_on(Package, Dependency, Type) - :- declared_dependency(Package, Dependency, Type), - node(Package), + :- dependency_conditions(Package, Dependency, Type), not virtual(Dependency), not external(Package). @@ -51,10 +50,38 @@ depends_on(Package, Dependency, Type) depends_on(Package, Provider, Type) : provides_virtual(Provider, Virtual) } 1 - :- declared_dependency(Package, Virtual, Type), + :- dependency_conditions(Package, Virtual, Type), virtual(Virtual), - not external(Package), - node(Package). + not external(Package). + +% if any individual condition below is true, trigger the dependency. +dependency_conditions(P, D, T) :- dependency_conditions(P, D, T, _). + +% collect all the dependency condtions into a single conditional rule +dependency_conditions(P, D, T, I) :- + node(Package) + : dep_cond(P, D, T, I, "node", Package); + version(Package, Version) + : dep_cond(P, D, T, I, "version", Package, Version); + version_satisfies(Package, Constraint) + : dep_cond(P, D, T, I, "version_satisfies", Package, Constraint); + node_platform(Package, Platform) + : dep_cond(P, D, T, I, "node_platform", Package, Platform); + node_os(Package, OS) + : dep_cond(P, D, T, I, "node_os", Package, OS); + node_target(Package, Target) + : dep_cond(P, D, T, I, "node_target", Package, Target); + variant_value(Package, Variant, Value) + : dep_cond(P, D, T, I, "variant_value", Package, Variant, Value); + node_compiler(Package, Compiler) + : dep_cond(P, D, T, I, "node_compiler", Package, Compiler); + node_compiler_version(Package, Compiler, Version) + : dep_cond(P, D, T, I, "node_compiler_version", Package, Compiler, Version); + node_flag(Package, FlagType, Flag) + : dep_cond(P, D, T, I, "node_flag", Package, FlagType, Flag); + dependency_condition(P, D, I); + declared_dependency(P, D, T); + node(P). % if a virtual was required by some root spec, one provider is in the DAG 1 { node(Package) : provides_virtual(Package, Virtual) } 1 |