Move concretization into its own class.
Allows easy overriding of a single policy.
This commit is contained in:
parent
f31aaeed98
commit
6cf6eac3de
5 changed files with 73 additions and 56 deletions
|
@ -15,66 +15,72 @@
|
|||
from spack.spec import *
|
||||
|
||||
|
||||
def concretize_version(spec):
|
||||
"""If the spec is already concrete, return. Otherwise take
|
||||
the most recent available version, and default to the package's
|
||||
version if there are no avaialble versions.
|
||||
class DefaultConcretizer(object):
|
||||
"""This class doesn't have any state, it just provides some methods for
|
||||
concretization. You can subclass it to override just some of the
|
||||
default concretization strategies, or you can override all of them.
|
||||
"""
|
||||
# return if already concrete.
|
||||
if spec.versions.concrete:
|
||||
return
|
||||
|
||||
pkg = spec.package
|
||||
def concretize_version(self, spec):
|
||||
"""If the spec is already concrete, return. Otherwise take
|
||||
the most recent available version, and default to the package's
|
||||
version if there are no avaialble versions.
|
||||
"""
|
||||
# return if already concrete.
|
||||
if spec.versions.concrete:
|
||||
return
|
||||
|
||||
# If there are known avaialble versions, return the most recent
|
||||
available_versions = pkg.available_versions
|
||||
if available_versions:
|
||||
spec.versions = ver([available_versions[-1]])
|
||||
else:
|
||||
spec.versions = ver([pkg.version])
|
||||
pkg = spec.package
|
||||
|
||||
# If there are known avaialble versions, return the most recent
|
||||
available_versions = pkg.available_versions
|
||||
if available_versions:
|
||||
spec.versions = ver([available_versions[-1]])
|
||||
else:
|
||||
spec.versions = ver([pkg.version])
|
||||
|
||||
|
||||
def concretize_architecture(spec):
|
||||
"""If the spec already had an architecture, return. Otherwise if
|
||||
the root of the DAG has an architecture, then use that.
|
||||
Otherwise take the system's default architecture.
|
||||
def concretize_architecture(self, spec):
|
||||
"""If the spec already had an architecture, return. Otherwise if
|
||||
the root of the DAG has an architecture, then use that.
|
||||
Otherwise take the system's default architecture.
|
||||
|
||||
Intuition: Architectures won't be set a lot, and generally you
|
||||
want the host system's architecture. When architectures are
|
||||
mised in a spec, it is likely because the tool requries a
|
||||
cross-compiled component, e.g. for tools that run on BlueGene
|
||||
or Cray machines. These constraints will likely come directly
|
||||
from packages, so require the user to be explicit if they want
|
||||
to mess with the architecture, and revert to the default when
|
||||
they're not explicit.
|
||||
"""
|
||||
if spec.architecture is not None:
|
||||
return
|
||||
Intuition: Architectures won't be set a lot, and generally you
|
||||
want the host system's architecture. When architectures are
|
||||
mised in a spec, it is likely because the tool requries a
|
||||
cross-compiled component, e.g. for tools that run on BlueGene
|
||||
or Cray machines. These constraints will likely come directly
|
||||
from packages, so require the user to be explicit if they want
|
||||
to mess with the architecture, and revert to the default when
|
||||
they're not explicit.
|
||||
"""
|
||||
if spec.architecture is not None:
|
||||
return
|
||||
|
||||
if spec.root.architecture:
|
||||
spec.architecture = spec.root.architecture
|
||||
else:
|
||||
spec.architecture = spack.arch.sys_type()
|
||||
if spec.root.architecture:
|
||||
spec.architecture = spec.root.architecture
|
||||
else:
|
||||
spec.architecture = spack.arch.sys_type()
|
||||
|
||||
|
||||
def concretize_compiler(spec):
|
||||
"""Currently just sets the compiler to gcc or throws an exception
|
||||
if the compiler is set to something else.
|
||||
def concretize_compiler(self, spec):
|
||||
"""Currently just sets the compiler to gcc or throws an exception
|
||||
if the compiler is set to something else.
|
||||
|
||||
TODO: implement below description.
|
||||
TODO: implement below description.
|
||||
|
||||
If the spec already has a compiler, we're done. If not, then
|
||||
take the compiler used for the nearest ancestor with a concrete
|
||||
compiler, or use the system default if there is no ancestor
|
||||
with a compiler.
|
||||
If the spec already has a compiler, we're done. If not, then
|
||||
take the compiler used for the nearest ancestor with a concrete
|
||||
compiler, or use the system default if there is no ancestor
|
||||
with a compiler.
|
||||
|
||||
Intuition: Use the system default if no package that depends on
|
||||
this one has a strict compiler requirement. Otherwise, try to
|
||||
build with the compiler that will be used by libraries that
|
||||
link to this one, to maximize compatibility.
|
||||
"""
|
||||
if spec.compiler and spec.compiler.concrete:
|
||||
if spec.compiler != spack.compilers.default_compiler():
|
||||
raise spack.spec.UnknownCompilerError(str(spec.compiler))
|
||||
else:
|
||||
spec.compiler = spack.compilers.default_compiler()
|
||||
Intuition: Use the system default if no package that depends on
|
||||
this one has a strict compiler requirement. Otherwise, try to
|
||||
build with the compiler that will be used by libraries that
|
||||
link to this one, to maximize compatibility.
|
||||
"""
|
||||
if spec.compiler and spec.compiler.concrete:
|
||||
if spec.compiler != spack.compilers.default_compiler():
|
||||
raise spack.spec.UnknownCompilerError(str(spec.compiler))
|
||||
else:
|
||||
spec.compiler = spack.compilers.default_compiler()
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
from spack.util.filesystem import *
|
||||
from spack.util.executable import *
|
||||
from spack.directory_layout import DefaultDirectoryLayout
|
||||
from spack.concretize import DefaultConcretizer
|
||||
|
||||
# This lives in $prefix/lib/spac/spack/__file__
|
||||
prefix = ancestor(__file__, 4)
|
||||
|
@ -31,6 +32,13 @@
|
|||
#
|
||||
install_layout = DefaultDirectoryLayout(install_path)
|
||||
|
||||
#
|
||||
# This controls how things are concretized in spack.
|
||||
# Replace it with a subclass if you want different
|
||||
# policies.
|
||||
#
|
||||
concretizer = DefaultConcretizer()
|
||||
|
||||
# Version information
|
||||
spack_version = Version("0.5")
|
||||
|
||||
|
|
|
@ -81,4 +81,4 @@ def provides(*args):
|
|||
# Get the enclosing package's scope and add deps to it.
|
||||
provided = _caller_locals().setdefault("provided", [])
|
||||
for name in args:
|
||||
provides.append(name)
|
||||
provided.append(name)
|
||||
|
|
|
@ -67,7 +67,6 @@
|
|||
import tty
|
||||
import spack.parse
|
||||
import spack.error
|
||||
import spack.concretize
|
||||
import spack.compilers
|
||||
import spack.compilers.gcc
|
||||
import spack.packages as packages
|
||||
|
@ -330,6 +329,8 @@ def virtual(self):
|
|||
"""Right now, a spec is virtual if no package exists with its name.
|
||||
TODO: revisit this -- might need to use a separate namespace and
|
||||
be more explicit about this.
|
||||
Possible idea: just use conventin and make virtual deps all
|
||||
caps, e.g., MPI vs mpi.
|
||||
"""
|
||||
return not packages.exists(self.name)
|
||||
|
||||
|
@ -400,9 +401,9 @@ def _concretize_helper(self, presets):
|
|||
if self.name in presets:
|
||||
self.constrain(presets[self.name])
|
||||
else:
|
||||
spack.concretize.concretize_architecture(self)
|
||||
spack.concretize.concretize_compiler(self)
|
||||
spack.concretize.concretize_version(self)
|
||||
spack.concretizer.concretize_architecture(self)
|
||||
spack.concretizer.concretize_compiler(self)
|
||||
spack.concretizer.concretize_version(self)
|
||||
presets[self.name] = self
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ class Mpich(Package):
|
|||
|
||||
versions = '1.0.3, 1.3.2p1, 1.4.1p1, 3.0.4, 3.1b1'
|
||||
|
||||
provides('mpi')
|
||||
|
||||
def install(self, prefix):
|
||||
configure("--prefix=%s" % prefix)
|
||||
make()
|
||||
|
|
Loading…
Reference in a new issue