Use preferred package rules when concretize'ing specs
This commit is contained in:
parent
b5c597b318
commit
8d7b7e5d5d
2 changed files with 38 additions and 32 deletions
|
@ -38,6 +38,7 @@
|
||||||
import spack.architecture
|
import spack.architecture
|
||||||
import spack.error
|
import spack.error
|
||||||
from spack.version import *
|
from spack.version import *
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,8 +50,8 @@ class DefaultConcretizer(object):
|
||||||
|
|
||||||
def concretize_version(self, spec):
|
def concretize_version(self, spec):
|
||||||
"""If the spec is already concrete, return. Otherwise take
|
"""If the spec is already concrete, return. Otherwise take
|
||||||
the most recent available version, and default to the package's
|
the preferred version from spackconfig, and default to the package's
|
||||||
version if there are no avaialble versions.
|
version if there are no available versions.
|
||||||
|
|
||||||
TODO: In many cases we probably want to look for installed
|
TODO: In many cases we probably want to look for installed
|
||||||
versions of each package and use an installed version
|
versions of each package and use an installed version
|
||||||
|
@ -68,12 +69,14 @@ def concretize_version(self, spec):
|
||||||
# If there are known available versions, return the most recent
|
# If there are known available versions, return the most recent
|
||||||
# version that satisfies the spec
|
# version that satisfies the spec
|
||||||
pkg = spec.package
|
pkg = spec.package
|
||||||
|
cmp_versions = partial(spack.pkgsort.version_compare, spec.name)
|
||||||
valid_versions = sorted(
|
valid_versions = sorted(
|
||||||
[v for v in pkg.versions
|
[v for v in pkg.versions
|
||||||
if any(v.satisfies(sv) for sv in spec.versions)])
|
if any(v.satisfies(sv) for sv in spec.versions)],
|
||||||
|
cmp=cmp_versions)
|
||||||
|
|
||||||
if valid_versions:
|
if valid_versions:
|
||||||
spec.versions = ver([valid_versions[-1]])
|
spec.versions = ver([valid_versions[0]])
|
||||||
else:
|
else:
|
||||||
# We don't know of any SAFE versions that match the given
|
# We don't know of any SAFE versions that match the given
|
||||||
# spec. Grab the spec's versions and grab the highest
|
# spec. Grab the spec's versions and grab the highest
|
||||||
|
@ -138,10 +141,10 @@ def concretize_compiler(self, spec):
|
||||||
"""If the spec already has a compiler, we're done. If not, then take
|
"""If the spec already has a compiler, we're done. If not, then take
|
||||||
the compiler used for the nearest ancestor with a compiler
|
the compiler used for the nearest ancestor with a compiler
|
||||||
spec and use that. If the ancestor's compiler is not
|
spec and use that. If the ancestor's compiler is not
|
||||||
concrete, then give it a valid version. If there is no
|
concrete, then used the preferred compiler as specified in
|
||||||
ancestor with a compiler, use the system default compiler.
|
spackconfig.
|
||||||
|
|
||||||
Intuition: Use the system default if no package that depends on
|
Intuition: Use the spackconfig default if no package that depends on
|
||||||
this one has a strict compiler requirement. Otherwise, try to
|
this one has a strict compiler requirement. Otherwise, try to
|
||||||
build with the compiler that will be used by libraries that
|
build with the compiler that will be used by libraries that
|
||||||
link to this one, to maximize compatibility.
|
link to this one, to maximize compatibility.
|
||||||
|
@ -153,29 +156,31 @@ def concretize_compiler(self, spec):
|
||||||
spec.compiler in all_compilers):
|
spec.compiler in all_compilers):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
# Find the parent spec that has a compiler, or the root if none do
|
||||||
nearest = next(p for p in spec.traverse(direction='parents')
|
parent_spec = next(p for p in spec.traverse(direction='parents')
|
||||||
if p.compiler is not None).compiler
|
if p.compiler is not None or not p.dependents)
|
||||||
|
parent_compiler = parent_spec.compiler
|
||||||
|
assert(parent_spec)
|
||||||
|
|
||||||
if not nearest in all_compilers:
|
# Check if the compiler is already fully specified
|
||||||
# Take the newest compiler that saisfies the spec
|
if parent_compiler in all_compilers:
|
||||||
matches = sorted(spack.compilers.find(nearest))
|
spec.compiler = parent_compiler.copy()
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Filter the compilers into a sorted list based on the compiler_order from spackconfig
|
||||||
|
compiler_list = all_compilers if not parent_compiler else spack.compilers.find(parent_compiler)
|
||||||
|
cmp_compilers = partial(spack.pkgsort.compiler_compare, parent_spec.name)
|
||||||
|
matches = sorted(compiler_list, cmp=cmp_compilers)
|
||||||
if not matches:
|
if not matches:
|
||||||
raise UnavailableCompilerVersionError(nearest)
|
raise UnavailableCompilerVersionError(parent_compiler)
|
||||||
|
|
||||||
# copy concrete version into nearest spec
|
|
||||||
nearest.versions = matches[-1].versions.copy()
|
|
||||||
assert(nearest.concrete)
|
|
||||||
|
|
||||||
spec.compiler = nearest.copy()
|
|
||||||
|
|
||||||
except StopIteration:
|
|
||||||
spec.compiler = spack.compilers.default_compiler().copy()
|
|
||||||
|
|
||||||
|
# copy concrete version into parent_compiler
|
||||||
|
spec.compiler = matches[0].copy()
|
||||||
|
assert(spec.compiler.concrete)
|
||||||
return True # things changed.
|
return True # things changed.
|
||||||
|
|
||||||
|
|
||||||
def choose_provider(self, spec, providers):
|
def choose_provider(self, package_spec, spec, providers):
|
||||||
"""This is invoked for virtual specs. Given a spec with a virtual name,
|
"""This is invoked for virtual specs. Given a spec with a virtual name,
|
||||||
say "mpi", and a list of specs of possible providers of that spec,
|
say "mpi", and a list of specs of possible providers of that spec,
|
||||||
select a provider and return it.
|
select a provider and return it.
|
||||||
|
@ -183,10 +188,11 @@ def choose_provider(self, spec, providers):
|
||||||
assert(spec.virtual)
|
assert(spec.virtual)
|
||||||
assert(providers)
|
assert(providers)
|
||||||
|
|
||||||
index = spack.spec.index_specs(providers)
|
provider_cmp = partial(spack.pkgsort.provider_compare, package_spec.name, spec.name)
|
||||||
first_key = sorted(index.keys())[0]
|
sorted_providers = sorted(providers, cmp=provider_cmp)
|
||||||
latest_version = sorted(index[first_key])[-1]
|
first_key = sorted_providers[0]
|
||||||
return latest_version
|
|
||||||
|
return first_key
|
||||||
|
|
||||||
|
|
||||||
class UnavailableCompilerVersionError(spack.error.SpackError):
|
class UnavailableCompilerVersionError(spack.error.SpackError):
|
||||||
|
|
|
@ -796,7 +796,7 @@ def _expand_virtual_packages(self):
|
||||||
|
|
||||||
for spec in virtuals:
|
for spec in virtuals:
|
||||||
providers = spack.db.providers_for(spec)
|
providers = spack.db.providers_for(spec)
|
||||||
concrete = spack.concretizer.choose_provider(spec, providers)
|
concrete = spack.concretizer.choose_provider(self, spec, providers)
|
||||||
concrete = concrete.copy()
|
concrete = concrete.copy()
|
||||||
spec._replace_with(concrete)
|
spec._replace_with(concrete)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
Loading…
Reference in a new issue