summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/architecture.py218
-rw-r--r--lib/spack/spack/build_environment.py9
-rw-r--r--lib/spack/spack/compilers/__init__.py46
-rw-r--r--lib/spack/spack/concretize.py15
-rw-r--r--lib/spack/spack/config.py24
-rw-r--r--lib/spack/spack/database.py10
-rw-r--r--lib/spack/spack/operating_systems/linux_distro.py13
-rw-r--r--lib/spack/spack/package.py2
-rw-r--r--lib/spack/spack/platforms/test.py4
-rw-r--r--lib/spack/spack/spec.py7
-rw-r--r--lib/spack/spack/test/architecture.py6
-rw-r--r--lib/spack/spack/test/concretize.py7
-rw-r--r--lib/spack/spack/test/config.py84
-rw-r--r--lib/spack/spack/test/mock_packages_test.py96
-rw-r--r--lib/spack/spack/yaml_version_check.py4
15 files changed, 286 insertions, 259 deletions
diff --git a/lib/spack/spack/architecture.py b/lib/spack/spack/architecture.py
index a0ef4f14da..1f25bc14ea 100644
--- a/lib/spack/spack/architecture.py
+++ b/lib/spack/spack/architecture.py
@@ -29,8 +29,9 @@ and the architecture platform (i.e. cray, darwin, linux, bgq, etc) classes.
On a multiple architecture machine, the architecture spec field can be set to
build a package against any target and operating system that is present on the
-platform. On Cray platforms or any other architecture that has different front and
-back end environments, the operating system will determine the method of compiler
+platform. On Cray platforms or any other architecture that has different front
+and back end environments, the operating system will determine the method of
+compiler
detection.
There are two different types of compiler detection:
@@ -40,44 +41,42 @@ There are two different types of compiler detection:
Depending on which operating system is specified, the compiler will be detected
using one of those methods.
-For platforms such as linux and darwin, the operating system is autodetected and
-the target is set to be x86_64.
+For platforms such as linux and darwin, the operating system is autodetected
+and the target is set to be x86_64.
The command line syntax for specifying an architecture is as follows:
target=<Target name> os=<OperatingSystem name>
If the user wishes to use the defaults, either target or os can be left out of
-the command line and Spack will concretize using the default. These defaults are
-set in the 'platforms/' directory which contains the different subclasses for
-platforms. If the machine has multiple architectures, the user can
+the command line and Spack will concretize using the default. These defaults
+are set in the 'platforms/' directory which contains the different subclasses
+for platforms. If the machine has multiple architectures, the user can
also enter front-end, or fe or back-end or be. These settings will concretize
to their respective front-end and back-end targets and operating systems.
Additional platforms can be added by creating a subclass of Platform
and adding it inside the platform directory.
Platforms are an abstract class that are extended by subclasses. If the user
-wants to add a new type of platform (such as cray_xe), they can create a subclass
-and set all the class attributes such as priority, front_target ,back_target,
-front_os, back_os. Platforms also contain a priority class attribute. A lower
-number signifies higher priority. These numbers are arbitrarily set and can be
-changed though often there isn't much need unless a new platform is added and
-the user wants that to be detected first.
-
-Targets are created inside the platform subclasses. Most architecture (like linux,
-and darwin) will have only one target (x86_64) but in the case of Cray machines,
-there is both a frontend and backend processor. The user can specify which targets
-are present on front-end and back-end architecture
+wants to add a new type of platform (such as cray_xe), they can create a
+subclass and set all the class attributes such as priority, front_target,
+back_target, front_os, back_os. Platforms also contain a priority class
+attribute. A lower number signifies higher priority. These numbers are
+arbitrarily set and can be changed though often there isn't much need unless a
+new platform is added and the user wants that to be detected first.
+
+Targets are created inside the platform subclasses. Most architecture
+(like linux, and darwin) will have only one target (x86_64) but in the case of
+Cray machines, there is both a frontend and backend processor. The user can
+specify which targets are present on front-end and back-end architecture
Depending on the platform, operating systems are either auto-detected or are
set. The user can set the front-end and back-end operating setting by the class
-attributes front_os and back_os. The operating system as described earlier, will
-be responsible for compiler detection.
+attributes front_os and back_os. The operating system as described earlier,
+will be responsible for compiler detection.
"""
import os
-from collections import namedtuple
import imp
-import platform as py_platform
import inspect
from llnl.util.lang import memoized, list_modules, key_ordering
@@ -91,6 +90,7 @@ from spack.util.environment import get_path
from spack.util.multiproc import parmap
import spack.error as serr
+
class InvalidSysTypeError(serr.SpackError):
def __init__(self, sys_type):
super(InvalidSysTypeError, self).__init__(
@@ -128,12 +128,6 @@ class Target(object):
def __str__(self):
return self.name
- def to_dict(self):
- d = {}
- d['name'] = self.name
- d['module_name'] = self.module_name
-
- return d
@key_ordering
class Platform(object):
@@ -142,7 +136,7 @@ class Platform(object):
is returned
"""
- priority = None # Subclass needs to set this number. This controls order in which platform is detected.
+ priority = None # Subclass sets number. Controls detection order
front_end = None
back_end = None
default = None # The default back end target. On cray ivybridge
@@ -156,19 +150,6 @@ class Platform(object):
self.operating_sys = {}
self.name = name
- def to_dict(self):
- n = {}
- n['targets'] = dict((name, target.to_dict()) for (name, target) in self.targets.items())
- n['operating_systems'] = dict((name, os.to_dict()) for (name, os) in self.operating_sys.items())
- n['priority'] = self.priority
- n['default_front_end_target'] = self.front_end
- n['default_back_end_target'] = self.back_end
- n['default_target'] = self.default
- n['default_front_end_os'] = self.front_os
- n['default_back_end_os'] = self.back_os
- n['default_os'] = self.default_os
- return {self.name: n}
-
def add_target(self, name, target):
"""Used by the platform specific subclass to list available targets.
Raises an error if the platform specifies a name
@@ -214,7 +195,7 @@ class Platform(object):
name = self.back_os
return self.operating_sys.get(name, None)
-
+
@classmethod
def detect(self):
@@ -232,8 +213,10 @@ class Platform(object):
return self.name
def _cmp_key(self):
- t_keys = ''.join(str(t._cmp_key()) for t in sorted(self.targets.values()))
- o_keys = ''.join(str(o._cmp_key()) for o in sorted(self.operating_sys.values()))
+ t_keys = ''.join(str(t._cmp_key()) for t in
+ sorted(self.targets.values()))
+ o_keys = ''.join(str(o._cmp_key()) for o in
+ sorted(self.operating_sys.values()))
return (self.name,
self.default,
self.front_end,
@@ -244,6 +227,7 @@ class Platform(object):
t_keys,
o_keys)
+
@key_ordering
class OperatingSystem(object):
""" Operating System will be like a class similar to platform extended
@@ -265,7 +249,6 @@ class OperatingSystem(object):
def _cmp_key(self):
return (self.name, self.version)
-
def find_compilers(self, *paths):
"""
Return a list of compilers found in the suppied paths.
@@ -293,11 +276,13 @@ class OperatingSystem(object):
# compiler. We can spawn a bunch of parallel searches to reduce
# the overhead of spelunking all these directories.
types = spack.compilers.all_compiler_types()
- compiler_lists = parmap(lambda cmp_cls: self.find_compiler(cmp_cls, *filtered_path), types)
+ compiler_lists = parmap(lambda cmp_cls:
+ self.find_compiler(cmp_cls, *filtered_path),
+ types)
# ensure all the version calls we made are cached in the parent
# process, as well. This speeds up Spack a lot.
- clist = reduce(lambda x,y: x+y, compiler_lists)
+ clist = reduce(lambda x, y: x+y, compiler_lists)
return clist
def find_compiler(self, cmp_cls, *path):
@@ -338,7 +323,7 @@ class OperatingSystem(object):
# prefer the one with more compilers.
prev_paths = [prev.cc, prev.cxx, prev.f77, prev.fc]
- newcount = len([p for p in paths if p is not None])
+ newcount = len([p for p in paths if p is not None])
prevcount = len([p for p in prev_paths if p is not None])
# Don't add if it's not an improvement over prev compiler.
@@ -353,10 +338,9 @@ class OperatingSystem(object):
d = {}
d['name'] = self.name
d['version'] = self.version
-
+
return d
-#NOTE: Key error caused because Architecture has no comparison method
@key_ordering
class Arch(object):
"Architecture is now a class to help with setting attributes"
@@ -376,10 +360,11 @@ class Arch(object):
@property
def concrete(self):
- return all( (self.platform is not None, isinstance(self.platform, Platform),
- self.platform_os is not None, isinstance(self.platform_os, OperatingSystem),
- self.target is not None, isinstance(self.target, Target) ) )
-
+ return all((self.platform is not None,
+ isinstance(self.platform, Platform),
+ self.platform_os is not None,
+ isinstance(self.platform_os, OperatingSystem),
+ self.target is not None, isinstance(self.target, Target)))
def __str__(self):
if self.platform or self.platform_os or self.target:
@@ -388,71 +373,66 @@ class Arch(object):
else:
os_name = str(self.platform_os)
- return (str(self.platform) +"-"+
+ return (str(self.platform) + "-" +
os_name + "-" + str(self.target))
else:
return ''
def _cmp_key(self):
- platform = self.platform.name if isinstance(self.platform, Platform) else self.platform
- os = self.platform_os.name if isinstance(self.platform_os, OperatingSystem) else self.platform_os
- target = self.target.name if isinstance(self.target, Target) else self.target
- return (platform, os, target)
+ if isinstance(self.platform, Platform):
+ platform = self.platform.name
+ else:
+ platform = self.platform
+ if isinstance(self.platform_os, OperatingSystem):
+ platform_os = self.platform_os.name
+ else:
+ platform_os = self.platform_os
+ if isinstance(self.target, Target):
+ target = self.target.name
+ else:
+ target = self.target
+ return (platform, platform_os, target)
def to_dict(self):
d = {}
- platform = self.platform
- platform_os = self.platform_os
- target = self.target
-
- d['platform'] = self.platform.to_dict() if self.platform else None
- d['platform_os'] = self.platform_os.to_dict() if self.platform_os else None
- d['target'] = self.target.to_dict() if self.target else None
+ d['platform'] = str(self.platform) if self.platform else None
+ d['platform_os'] = str(self.platform_os) if self.platform_os else None
+ d['target'] = str(self.target) if self.target else None
return d
-def _target_from_dict(target_dict):
+def _target_from_dict(target_name, platform=None):
""" Creates new instance of target and assigns all the attributes of
that target from the dictionary
"""
- target = Target.__new__(Target)
- target.name = target_dict['name']
- target.module_name = target_dict['module_name']
- if 'platform_name' in target_dict:
- target.platform_name = target_dict['platform_name']
- return target
-
-def _operating_system_from_dict(os_dict):
+ if not platform:
+ platform = sys_type()
+ return platform.target(target_name)
+
+
+def _operating_system_from_dict(os_name, platform=None):
""" uses platform's operating system method to grab the constructed
operating systems that are valid on the platform.
"""
-# NOTE: Might need a better way to create operating system objects
- operating_system = OperatingSystem.__new__(OperatingSystem)
- operating_system.name = os_dict['name']
- operating_system.version = os_dict['version']
- return operating_system
+ if not platform:
+ platform = sys_type()
+ if isinstance(os_name, spack.util.spack_yaml.syaml_dict) or \
+ isinstance(os_name, dict):
+ name = os_name['name']
+ version = os_name['version']
+ return platform.operating_system(name+version)
+ else:
+ return platform.operating_system(os_name)
+
-def _platform_from_dict(platform_dict):
+def _platform_from_dict(platform_name):
""" Constructs a platform from a dictionary. """
- platform = Platform.__new__(Platform)
- name, p_dict = platform_dict.items()[0]
- platform.name = name
- platform.targets = {}
- for name, t_dict in p_dict['targets'].items():
- platform.add_target(name, _target_from_dict(t_dict))
- platform.operating_sys = {}
- for name, o_dict in p_dict['operating_systems'].items():
- platform.add_operating_system(name, _operating_system_from_dict(o_dict))
- platform.priority = p_dict['priority']
- platform.front_end = p_dict['default_front_end_target']
- platform.back_end = p_dict['default_back_end_target']
- platform.default = p_dict['default_target']
- platform.front_os = p_dict['default_front_end_os']
- platform.back_os = p_dict['default_back_end_os']
- platform.default_os = p_dict['default_os']
-
- return platform
+ platform_list = all_platforms()
+ for p in platform_list:
+ if platform_name.replace("_", "").lower() == p.__name__.lower():
+ return p()
+
def arch_from_dict(d):
""" Uses _platform_from_dict, _operating_system_from_dict, _target_from_dict
@@ -472,40 +452,50 @@ def arch_from_dict(d):
else:
if d is None:
return None
- platform_dict = d['platform']
- os_dict = d['platform_os']
- target_dict = d['target']
+ platform_name = d['platform']
+ os_name = d['platform_os']
+ target_name = d['target']
- arch.platform = _platform_from_dict(platform_dict) if platform_dict else None
- arch.target = _target_from_dict(target_dict) if os_dict else None
- arch.platform_os = _operating_system_from_dict(os_dict) if os_dict else None
+ if platform_name:
+ arch.platform = _platform_from_dict(platform_name)
+ else:
+ arch.platform = None
+ if target_name:
+ arch.target = _target_from_dict(target_name, arch.platform)
+ else:
+ arch.target = None
+ if os_name:
+ arch.platform_os = _operating_system_from_dict(os_name,
+ arch.platform)
+ else:
+ arch.platform_os = None
arch.os_string = None
arch.target_string = None
return arch
+
@memoized
def all_platforms():
- modules = []
-
+ classes = []
mod_path = spack.platform_path
- mod_string = "spack.platformss"
+ parent_module = "spack.platforms"
for name in list_modules(mod_path):
- mod_name = mod_string + name
- path = join_path(mod_path, name) + ".py"
- mod = imp.load_source(mod_name, path)
+ mod_name = '%s.%s' % (parent_module, name)
class_name = mod_to_class(name)
+ mod = __import__(mod_name, fromlist=[class_name])
if not hasattr(mod, class_name):
tty.die('No class %s defined in %s' % (class_name, mod_name))
cls = getattr(mod, class_name)
if not inspect.isclass(cls):
tty.die('%s.%s is not a class' % (mod_name, class_name))
- modules.append(cls)
+ classes.append(cls)
+
+ return classes
- return modules
@memoized
def sys_type():
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 4483b9d132..7c65091d49 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -384,6 +384,13 @@ def parent_class_modules(cls):
return result
+def load_external_modules(pkg):
+ """ traverse the spec list and find any specs that have external modules.
+ """
+ for dep in list(pkg.spec.traverse()):
+ if dep.external_module:
+ load_module(dep.external_module)
+
def setup_package(pkg):
"""Execute all environment setup routines."""
spack_env = EnvironmentModifications()
@@ -407,7 +414,7 @@ def setup_package(pkg):
set_compiler_environment_variables(pkg, spack_env)
set_build_environment_variables(pkg, spack_env)
-
+ load_external_modules(pkg)
# traverse in postorder so package can use vars from its dependencies
spec = pkg.spec
for dspec in pkg.spec.traverse(order='post', root=False):
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index c76dd252d0..4b546c2cbf 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -73,16 +73,14 @@ def _to_dict(compiler):
d = {}
d['spec'] = str(compiler.spec)
d['paths'] = dict( (attr, getattr(compiler, attr, None)) for attr in _path_instance_vars )
- d['operating_system'] = compiler.operating_system.to_dict()
+ d['operating_system'] = str(compiler.operating_system)
d['modules'] = compiler.modules if compiler.modules else []
- if not compiler.alias:
- yaml_text = yaml.dump(
- d, default_flow_style=True, width=sys.maxint)
- sha = hashlib.sha1(yaml_text)
- compiler.alias = base64.b32encode(sha.digest()).lower()[:8]
+ if compiler.alias:
+ d['alias'] = compiler.alias
+
return {
- compiler.alias: d
+ 'compiler': d
}
@@ -91,11 +89,11 @@ def get_compiler_config(scope=None):
"""
def init_compiler_config():
"""Compiler search used when Spack has no compilers."""
- config = {}
compilers = find_compilers()
+ compilers_dict = []
for compiler in compilers:
- config.update(_to_dict(compiler))
- spack.config.update_config('compilers', config, scope=scope)
+ compilers_dict.append(_to_dict(compiler))
+ spack.config.update_config('compilers', compilers_dict, scope=scope)
config = spack.config.get_config('compilers', scope=scope)
# Update the configuration if there are currently no compilers
@@ -127,7 +125,7 @@ def add_compilers_to_config(compilers, scope=None):
"""
compiler_config = get_compiler_config(scope)
for compiler in compilers:
- compiler_config = _to_dict(compiler)
+ compiler_config.append(_to_dict(compiler))
spack.config.update_config('compilers', compiler_config, scope)
@@ -167,8 +165,8 @@ def all_compilers_config(scope=None):
def all_compilers(scope=None):
# Return compiler specs from the merged config.
- return [spack.spec.CompilerSpec(s['spec'])
- for s in all_compilers_config(scope).values()]
+ return [spack.spec.CompilerSpec(s['compiler']['spec'])
+ for s in all_compilers_config(scope)]
def default_compiler():
@@ -220,20 +218,20 @@ def find(compiler_spec, scope=None):
@_auto_compiler_spec
-def compilers_for_spec(compiler_spec, scope=None):
+def compilers_for_spec(compiler_spec, scope=None, **kwargs):
"""This gets all compilers that satisfy the supplied CompilerSpec.
Returns an empty list if none are found.
"""
+ platform = kwargs.get("platform", None)
config = all_compilers_config(scope)
def get_compilers(cspec):
compilers = []
- for aka, cmp in config.items():
- if cmp['spec'] != str(cspec):
+ for items in config:
+ if items['compiler']['spec'] != str(cspec):
continue
- items = cmp
- alias = aka
+ items = items['compiler']
if not ('paths' in items and all(n in items['paths'] for n in _path_instance_vars)):
raise InvalidCompilerConfigurationError(cspec)
@@ -253,10 +251,13 @@ def compilers_for_spec(compiler_spec, scope=None):
mods = []
if 'operating_system' in items:
- operating_system = spack.architecture._operating_system_from_dict( items['operating_system'] )
+ operating_system = spack.architecture._operating_system_from_dict(items['operating_system'], platform)
else:
operating_system = None
+
+ alias = items['alias'] if 'alias' in items else None
+
flags = {}
for f in spack.spec.FlagMap.valid_compiler_flags():
if f in items:
@@ -275,12 +276,13 @@ def compilers_for_spec(compiler_spec, scope=None):
@_auto_compiler_spec
-def compiler_for_spec(compiler_spec, operating_system):
+def compiler_for_spec(compiler_spec, arch):
"""Get the compiler that satisfies compiler_spec. compiler_spec must
be concrete."""
+ operating_system = arch.platform_os
assert(compiler_spec.concrete)
- compilers = [c for c in compilers_for_spec(compiler_spec)
+ compilers = [c for c in compilers_for_spec(compiler_spec, platform=arch.platform)
if c.operating_system == operating_system]
if len(compilers) < 1:
raise NoCompilerForSpecError(compiler_spec, operating_system)
@@ -334,7 +336,7 @@ class NoCompilersError(spack.error.SpackError):
class NoCompilerForSpecError(spack.error.SpackError):
def __init__(self, compiler_spec, target):
- super(NoCompilerForSpecError, self).__init__("No compilers for target %s satisfy spec %s" % (
+ super(NoCompilerForSpecError, self).__init__("No compilers for operating system %s satisfy spec %s" % (
target, compiler_spec))
class CompilerSpecInsufficientlySpecificError(spack.error.SpackError):
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 5d9715feed..1f37455c77 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -84,7 +84,8 @@ class DefaultConcretizer(object):
raise NoBuildError(spec)
def cmp_externals(a, b):
- if a.name != b.name:
+ if a.name != b.name and (not a.external or a.external_module and
+ not b.external and b.external_module):
# We're choosing between different providers, so
# maintain order from provider sort
return candidates.index(a) - candidates.index(b)
@@ -279,10 +280,12 @@ class DefaultConcretizer(object):
# Only use a matching compiler if it is of the proper style
# Takes advantage of the proper logic already existing in compiler_for_spec
# Should think whether this can be more efficient
- def _proper_compiler_style(cspec, architecture):
- compilers = spack.compilers.compilers_for_spec(cspec)
- return filter(lambda c: c.operating_system ==
- architecture.platform_os, compilers)
+ def _proper_compiler_style(cspec, arch):
+ platform = arch.platform
+ compilers = spack.compilers.compilers_for_spec(cspec,
+ platform=platform)
+ return filter(lambda c: c.operating_system ==
+ arch.platform_os, compilers)
#return compilers
@@ -367,7 +370,7 @@ class DefaultConcretizer(object):
# Include the compiler flag defaults from the config files
# This ensures that spack will detect conflicts that stem from a change
# in default compiler flags.
- compiler = spack.compilers.compiler_for_spec(spec.compiler, spec.architecture.platform_os)
+ compiler = spack.compilers.compiler_for_spec(spec.compiler, spec.architecture)
for flag in compiler.flags:
if flag not in spec.compiler_flags:
spec.compiler_flags[flag] = compiler.flags[flag]
diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py
index ec04c81787..e51016998c 100644
--- a/lib/spack/spack/config.py
+++ b/lib/spack/spack/config.py
@@ -146,11 +146,9 @@ section_schemas = {
'additionalProperties': False,
'patternProperties': {
'compilers:?': { # optional colon for overriding site config.
- 'type': 'object',
- 'default': {},
- 'additionalProperties': False,
- 'patternProperties': {
- r'\w[\w-]*': { # alias
+ 'type': 'array',
+ 'items': {
+ 'compiler': {
'type': 'object',
'additionalProperties': False,
'required': ['paths', 'spec', 'modules', 'operating_system'],
@@ -180,15 +178,10 @@ section_schemas = {
{'type' : 'null' }]},
'ldlibs': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]}}},
- 'spec': { 'type': 'string'},#r'\w[\w-]*@\w[\w-]*'
- 'operating_system': {
- 'type': 'object',
- 'required': ['name', 'version'],
- 'additionalProperties': False,
- 'properties': {
- 'name': {'type': 'string'},
- 'version': {'type': 'string'}
- }},
+ 'spec': { 'type': 'string'},
+ 'operating_system': { 'type': 'string'},
+ 'alias': { 'anyOf': [ {'type' : 'string'},
+ {'type' : 'null' }]},
'modules': { 'anyOf': [ {'type' : 'string'},
{'type' : 'null' },
{'type': 'array'},
@@ -591,8 +584,7 @@ def _merge_yaml(dest, source):
# Source list is prepended (for precedence)
if they_are(list):
- seen = set(source)
- dest[:] = source + [x for x in dest if x not in seen]
+ dest[:] = source + [x for x in dest if x not in source]
return dest
# Source dict is merged into dest.
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index e768ddf5fe..38bb7541e0 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -214,9 +214,10 @@ class Database(object):
# Add dependencies from other records in the install DB to
# form a full spec.
- for dep_hash in spec_dict[spec.name]['dependencies'].values():
- child = self._read_spec_from_yaml(dep_hash, installs, hash_key)
- spec._add_dependency(child)
+ if 'dependencies' in spec_dict[spec.name]:
+ for dep_hash in spec_dict[spec.name]['dependencies'].values():
+ child = self._read_spec_from_yaml(dep_hash, installs, hash_key)
+ spec._add_dependency(child)
# Specs from the database need to be marked concrete because
# they represent actual installations.
@@ -289,7 +290,8 @@ class Database(object):
except Exception as e:
tty.warn("Invalid database reecord:",
"file: %s" % self._index_path,
- "hash: %s" % hash_key, "cause: %s" % str(e))
+ "hash: %s" % hash_key,
+ "cause: %s: %s" % (type(e).__name__, str(e)))
raise
self._data = data
diff --git a/lib/spack/spack/operating_systems/linux_distro.py b/lib/spack/spack/operating_systems/linux_distro.py
index d0f24d842f..2e3c72719b 100644
--- a/lib/spack/spack/operating_systems/linux_distro.py
+++ b/lib/spack/spack/operating_systems/linux_distro.py
@@ -1,3 +1,4 @@
+import re
import platform as py_platform
from spack.architecture import OperatingSystem
@@ -9,7 +10,13 @@ class LinuxDistro(OperatingSystem):
platform.dist()
"""
def __init__(self):
- name = py_platform.dist()[0]
- version = py_platform.dist()[1].split(".")[0] # Grabs major version from tuple
+ distname, version, _ = py_platform.linux_distribution(
+ full_distribution_name=False)
- super(LinuxDistro, self).__init__(name, version)
+ # Grabs major version from tuple on redhat; on other platforms
+ # grab the first legal identifier in the version field. On
+ # debian you get things like 'wheezy/sid'; sid means unstable.
+ # We just record 'wheezy' and don't get quite so detailed.
+ version = re.split(r'[^\w-]', version)[0]
+
+ super(LinuxDistro, self).__init__(distname, version)
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 0edb70e4ca..1a6c289bc7 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -682,7 +682,7 @@ class Package(object):
if not self.spec.concrete:
raise ValueError("Can only get a compiler for a concrete package.")
return spack.compilers.compiler_for_spec(self.spec.compiler,
- self.spec.architecture.platform_os)
+ self.spec.architecture)
def url_version(self, version):
"""
diff --git a/lib/spack/spack/platforms/test.py b/lib/spack/spack/platforms/test.py
index 3a4f9d5f2d..8fa2585a7a 100644
--- a/lib/spack/spack/platforms/test.py
+++ b/lib/spack/spack/platforms/test.py
@@ -10,8 +10,8 @@ class Test(Platform):
back_end = 'x86_64'
default = 'x86_64'
- back_os = 'CNL'
- default_os = 'CNL'
+ back_os = 'CNL10'
+ default_os = 'CNL10'
def __init__(self):
super(Test, self).__init__('test')
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index f8bad3ff03..7718adb72c 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1124,7 +1124,7 @@ class Spec(object):
for s in self.traverse(root=False):
if s.external_module:
- compiler = spack.compilers.compiler_for_spec(s.compiler, s.architecture.platform_os)
+ compiler = spack.compilers.compiler_for_spec(s.compiler, s.architecture)
for mod in compiler.modules:
load_module(mod)
@@ -2150,10 +2150,13 @@ class SpecLexer(spack.parse.Lexer):
(r'\s+', lambda scanner, val: None)])
+# Lexer is always the same for every parser.
+_lexer = SpecLexer()
+
class SpecParser(spack.parse.Parser):
def __init__(self):
- super(SpecParser, self).__init__(SpecLexer())
+ super(SpecParser, self).__init__(_lexer)
self.previous = None
def do_parse(self):
diff --git a/lib/spack/spack/test/architecture.py b/lib/spack/spack/test/architecture.py
index f5b1068435..3d08269dee 100644
--- a/lib/spack/spack/test/architecture.py
+++ b/lib/spack/spack/test/architecture.py
@@ -3,7 +3,7 @@
"""
import unittest
import os
-import platform
+import platform as py_platform
import spack
from spack.architecture import *
from spack.spec import *
@@ -61,9 +61,9 @@ class ArchitectureTest(MockPackagesTest):
my_platform_class = CrayXc()
elif os.path.exists('/bgsys'):
my_platform_class = Bgq()
- elif 'Linux' in platform.system():
+ elif 'Linux' in py_platform.system():
my_platform_class = Linux()
- elif 'Darwin' in platform.system():
+ elif 'Darwin' in py_platform.system():
my_platform_class = Darwin()
self.assertEqual(str(output_platform_class), str(my_platform_class))
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 77ff026c7a..67b20b4084 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -23,6 +23,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import spack
+import spack.architecture
from spack.spec import Spec, CompilerSpec
from spack.version import ver
from spack.concretize import find_spec
@@ -252,7 +253,9 @@ class ConcretizeTest(MockPackagesTest):
self.assertFalse('externalprereq' in spec)
self.assertTrue(spec['externaltool'].compiler.satisfies('gcc'))
-
+ @unittest.skipIf(spack.architecture.sys_type().name == 'darwin' or
+ spack.architecture.sys_type().name == 'linux',
+ "No tcl modules on darwin/linux machines")
def test_external_package_module(self):
spec = Spec('externalmodule')
spec.concretize()
@@ -269,7 +272,7 @@ class ConcretizeTest(MockPackagesTest):
got_error = True
self.assertTrue(got_error)
-
+
def test_external_and_virtual(self):
spec = Spec('externaltest')
spec.concretize()
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index 8fffc09437..252d77e66b 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -32,8 +32,8 @@ from ordereddict_backport import OrderedDict
from spack.test.mock_packages_test import *
# Some sample compiler config data
-a_comps = {
- 'gcc473': {
+a_comps = [
+ {'compiler': {
'paths': {
"cc" : "/gcc473",
"cxx": "/g++473",
@@ -42,12 +42,9 @@ a_comps = {
},
'modules': None,
'spec': 'gcc@4.7.3',
- 'operating_system': {
- 'name': 'CNL',
- 'version': '10'
- }
- },
- 'gcc450': {
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
'paths': {
"cc" : "/gcc450",
"cxx": "/g++450",
@@ -56,12 +53,9 @@ a_comps = {
},
'modules': None,
'spec': 'gcc@4.5.0',
- 'operating_system': {
- 'name': 'CNL',
- 'version': '10'
- }
- },
- 'clang33': {
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
'paths': {
"cc" : "<overwritten>",
"cxx": "<overwritten>",
@@ -69,15 +63,12 @@ a_comps = {
"fc" : '<overwritten>' },
'modules': None,
'spec': 'clang@3.3',
- 'operating_system': {
- 'name': 'CNL',
- 'version': '10'
- }
- }
-}
-
-b_comps = {
- 'icc100': {
+ 'operating_system': 'CNL10'
+ }}
+]
+
+b_comps = [
+ {'compiler': {
'paths': {
"cc" : "/icc100",
"cxx": "/icp100",
@@ -86,12 +77,9 @@ b_comps = {
},
'modules': None,
'spec': 'icc@10.0',
- 'operating_system': {
- 'name': 'CNL',
- 'version': '10'
- }
- },
- 'icc111': {
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
'paths': {
"cc" : "/icc111",
"cxx": "/icp111",
@@ -100,12 +88,9 @@ b_comps = {
},
'modules': None,
'spec': 'icc@11.1',
- 'operating_system': {
- 'name': 'CNL',
- 'version': '10'
- }
- },
- 'clang33': {
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
'paths': {
"cc" : "<overwritten>",
"cxx": "<overwritten>",
@@ -113,12 +98,9 @@ b_comps = {
"fc" : '<overwritten>' },
'modules': None,
'spec': 'clang@3.3',
- 'operating_system': {
- 'name': 'CNL',
- 'version': '10'
- }
- }
-}
+ 'operating_system': 'CNL10'
+ }}
+]
# Some Sample repo data
repos_low = [ "/some/path" ]
@@ -143,15 +125,21 @@ class ConfigTest(MockPackagesTest):
config = spack.config.get_config('compilers')
compiler_list = ['cc', 'cxx', 'f77', 'fc']
param_list = ['modules', 'paths', 'spec', 'operating_system']
- for alias, compiler in config.items():
- if compiler['spec'] in compiler_names:
+ for compiler in config:
+ conf = compiler['compiler']
+ if conf['spec'] in compiler_names:
+ comp = None
+ for c in comps:
+ if c['compiler']['spec'] == conf['spec']:
+ comp = c['compiler']
+ break
+ if not comp:
+ self.fail('Bad config spec')
for p in param_list:
- expected = comps[alias][p]
- actual = config[alias][p]
- self.assertEqual(expected, actual)
+ self.assertEqual(conf[p], comp[p])
for c in compiler_list:
- expected = comps[alias]['paths'][c]
- actual = config[alias]['paths'][c]
+ expected = comp['paths'][c]
+ actual = conf['paths'][c]
self.assertEqual(expected, actual)
def test_write_list_in_memory(self):
diff --git a/lib/spack/spack/test/mock_packages_test.py b/lib/spack/spack/test/mock_packages_test.py
index 5561027aac..a56bd8ebdc 100644
--- a/lib/spack/spack/test/mock_packages_test.py
+++ b/lib/spack/spack/test/mock_packages_test.py
@@ -34,97 +34,127 @@ from ordereddict_backport import OrderedDict
from spack.repository import RepoPath
from spack.spec import Spec
+platform = spack.architecture.sys_type()
+
+linux_os_name = 'debian'
+linux_os_version = '6'
+
+if platform.name == 'linux':
+ linux_os = platform.operating_system("default_os")
+ linux_os_name = linux_os.name
+ linux_os_version = linux_os.version
+
mock_compiler_config = """\
compilers:
- clang3.3CNL:
+- compiler:
+ spec: clang@3.3
+ operating_system: {0}{1}
+ paths:
+ cc: /path/to/clang
+ cxx: /path/to/clang++
+ f77: None
+ fc: None
+ modules: 'None'
+- compiler:
+ spec: gcc@4.5.0
+ operating_system: {0}{1}
+ paths:
+ cc: /path/to/gcc
+ cxx: /path/to/g++
+ f77: None
+ fc: None
+ modules: 'None'
+- compiler:
spec: clang@3.3
- operating_system:
- name: CNL
- version: '10'
+ operating_system: CNL10
paths:
cc: /path/to/clang
cxx: /path/to/clang++
f77: None
fc: None
modules: 'None'
- clang3.3SUSE:
+- compiler:
spec: clang@3.3
- operating_system:
- name: SuSE
- version: '11'
+ operating_system: SuSE11
paths:
cc: /path/to/clang
cxx: /path/to/clang++
f77: None
fc: None
modules: 'None'
- clang3.3RHL:
+- compiler:
spec: clang@3.3
- operating_system:
- name: redhat
- version: '6'
+ operating_system: redhat6
paths:
cc: /path/to/clang
cxx: /path/to/clang++
f77: None
fc: None
modules: 'None'
- clang3.3OSX:
+- compiler:
spec: clang@3.3
- operating_system:
- name: yosemite
- version: '10.10'
+ operating_system: yosemite
paths:
cc: /path/to/clang
cxx: /path/to/clang++
f77: None
fc: None
modules: 'None'
- gcc4.5.0CNL:
+- compiler:
paths:
cc: /path/to/gcc
cxx: /path/to/g++
f77: /path/to/gfortran
fc: /path/to/gfortran
- operating_system:
- name: CNL
- version: '10'
+ operating_system: CNL10
spec: gcc@4.5.0
modules: 'None'
- gcc4.5.0SUSE:
+- compiler:
paths:
cc: /path/to/gcc
cxx: /path/to/g++
f77: /path/to/gfortran
fc: /path/to/gfortran
- operating_system:
- name: SuSE
- version: '11'
+ operating_system: SuSE11
spec: gcc@4.5.0
modules: 'None'
- gcc4.5.0RHL:
+- compiler:
paths:
cc: /path/to/gcc
cxx: /path/to/g++
f77: /path/to/gfortran
fc: /path/to/gfortran
- operating_system:
- name: redhat
- version: '6'
+ operating_system: redhat6
spec: gcc@4.5.0
modules: 'None'
- gcc4.5.0OSX:
+- compiler:
paths:
cc: /path/to/gcc
cxx: /path/to/g++
f77: /path/to/gfortran
fc: /path/to/gfortran
- operating_system:
- name: yosemite
- version: '10.10'
+ operating_system: yosemite
spec: gcc@4.5.0
modules: 'None'
-"""
+- compiler:
+ paths:
+ cc: /path/to/gcc
+ cxx: /path/to/g++
+ f77: /path/to/gfortran
+ fc: /path/to/gfortran
+ operating_system: elcapitan
+ spec: gcc@4.5.0
+ modules: 'None'
+- compiler:
+ spec: clang@3.3
+ operating_system: elcapitan
+ paths:
+ cc: /path/to/clang
+ cxx: /path/to/clang++
+ f77: None
+ fc: None
+ modules: 'None'
+""".format(linux_os_name, linux_os_version)
mock_packages_config = """\
packages:
diff --git a/lib/spack/spack/yaml_version_check.py b/lib/spack/spack/yaml_version_check.py
index 2d3d78ed39..c2d084d6c3 100644
--- a/lib/spack/spack/yaml_version_check.py
+++ b/lib/spack/spack/yaml_version_check.py
@@ -44,9 +44,9 @@ def check_compiler_yaml_version():
data = syaml.load(f)
if data:
- compilers = data['compilers'].items()
+ compilers = data['compilers']
if len(compilers) > 0:
- if (not isinstance(compilers, list)) or 'operating_system' not in compilers[0][1]:
+ if (not isinstance(compilers, list)) or 'operating_system' not in compilers[0]['compiler']:
new_file = os.path.join(scope.path, '_old_compilers.yaml')
tty.warn('%s in out of date compilers format. '
'Moved to %s. Spack automatically generate '