diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/solver/asp.py | 15 | ||||
-rw-r--r-- | lib/spack/spack/spec.py | 84 |
2 files changed, 55 insertions, 44 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 1d4602ce62..292d3a5a3f 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1351,6 +1351,12 @@ class SpackSolverSetup(object): if v.satisfies(versions) ] + # This is needed to account for a variable number of + # numbers e.g. if both 1.0 and 1.0.2 are possible versions + exact_match = [v for v in allowed_versions if v == versions] + if exact_match: + allowed_versions = exact_match + # don't bother restricting anything if all versions are allowed if len(allowed_versions) == len(self.possible_versions[pkg_name]): continue @@ -1658,17 +1664,20 @@ class SpecBuilder(object): repo = spack.repo.path.repo_for_pkg(spec) spec.namespace = repo.namespace - # once this is done, everything is concrete - spec._mark_concrete() - # fix flags after all specs are constructed self.reorder_flags() + for s in self._specs.values(): + spack.spec.Spec.inject_patches_variant(s) + # Add external paths to specs with just external modules for s in self._specs.values(): spack.spec.Spec.ensure_external_path_if_external(s) for s in self._specs.values(): + s._mark_concrete() + + for s in self._specs.values(): spack.spec.Spec.ensure_no_deprecated(s) return self._specs diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 1e42e90214..fb7c0a93ce 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -2293,10 +2293,50 @@ class Spec(object): if extra: raise InvalidDependencyError(self.name, extra) + Spec.inject_patches_variant(self) + + for s in self.traverse(): + # TODO: Refactor this into a common method to build external specs + # TODO: or turn external_path into a lazy property + Spec.ensure_external_path_if_external(s) + + # Mark everything in the spec as concrete, as well. + self._mark_concrete() + + # If any spec in the DAG is deprecated, throw an error + Spec.ensure_no_deprecated(self) + + # Now that the spec is concrete we should check if + # there are declared conflicts + # + # TODO: this needs rethinking, as currently we can only express + # TODO: internal configuration conflicts within one package. + matches = [] + for x in self.traverse(): + if x.external: + # external specs are already built, don't worry about whether + # it's possible to build that configuration with Spack + continue + for conflict_spec, when_list in x.package_class.conflicts.items(): + if x.satisfies(conflict_spec, strict=True): + for when_spec, msg in when_list: + if x.satisfies(when_spec, strict=True): + when = when_spec.copy() + when.name = x.name + matches.append((x, conflict_spec, when, msg)) + if matches: + raise ConflictsInSpecError(self, matches) + + # Check if we can produce an optimized binary (will throw if + # there are declared inconsistencies) + self.architecture.target.optimization_flags(self.compiler) + + @staticmethod + def inject_patches_variant(root): # This dictionary will store object IDs rather than Specs as keys # since the Spec __hash__ will change as patches are added to them spec_to_patches = {} - for s in self.traverse(): + for s in root.traverse(): # After concretizing, assign namespaces to anything left. # Note that this doesn't count as a "change". The repository # configuration is constant throughout a spack run, and @@ -2319,10 +2359,9 @@ class Spec(object): patches.append(patch) if patches: spec_to_patches[id(s)] = patches - # Also record all patches required on dependencies by # depends_on(..., patch=...) - for dspec in self.traverse_edges(deptype=all, + for dspec in root.traverse_edges(deptype=all, cover='edges', root=False): pkg_deps = dspec.parent.package_class.dependencies if dspec.spec.name not in pkg_deps: @@ -2341,8 +2380,7 @@ class Spec(object): if patches: all_patches = spec_to_patches.setdefault(id(dspec.spec), []) all_patches.extend(patches) - - for spec in self.traverse(): + for spec in root.traverse(): if id(spec) not in spec_to_patches: continue @@ -2361,42 +2399,6 @@ class Spec(object): mvar._patches_in_order_of_appearance = list( t[-1] for t in ordered_hashes) - for s in self.traverse(): - # TODO: Refactor this into a common method to build external specs - # TODO: or turn external_path into a lazy property - Spec.ensure_external_path_if_external(s) - - # Mark everything in the spec as concrete, as well. - self._mark_concrete() - - # If any spec in the DAG is deprecated, throw an error - Spec.ensure_no_deprecated(self) - - # Now that the spec is concrete we should check if - # there are declared conflicts - # - # TODO: this needs rethinking, as currently we can only express - # TODO: internal configuration conflicts within one package. - matches = [] - for x in self.traverse(): - if x.external: - # external specs are already built, don't worry about whether - # it's possible to build that configuration with Spack - continue - for conflict_spec, when_list in x.package_class.conflicts.items(): - if x.satisfies(conflict_spec, strict=True): - for when_spec, msg in when_list: - if x.satisfies(when_spec, strict=True): - when = when_spec.copy() - when.name = x.name - matches.append((x, conflict_spec, when, msg)) - if matches: - raise ConflictsInSpecError(self, matches) - - # Check if we can produce an optimized binary (will throw if - # there are declared inconsistencies) - self.architecture.target.optimization_flags(self.compiler) - @staticmethod def ensure_external_path_if_external(external_spec): if external_spec.external_modules and not external_spec.external_path: |