Move concretization into its own class.

Allows easy overriding of a single policy.
This commit is contained in:
Todd Gamblin 2013-11-23 15:18:43 -08:00
parent f31aaeed98
commit 6cf6eac3de
5 changed files with 73 additions and 56 deletions

View file

@ -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()

View file

@ -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")

View file

@ -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)

View file

@ -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

View file

@ -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()