diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/architecture.py | 218 | ||||
-rw-r--r-- | lib/spack/spack/build_environment.py | 9 | ||||
-rw-r--r-- | lib/spack/spack/compilers/__init__.py | 46 | ||||
-rw-r--r-- | lib/spack/spack/concretize.py | 15 | ||||
-rw-r--r-- | lib/spack/spack/config.py | 24 | ||||
-rw-r--r-- | lib/spack/spack/database.py | 10 | ||||
-rw-r--r-- | lib/spack/spack/operating_systems/linux_distro.py | 13 | ||||
-rw-r--r-- | lib/spack/spack/package.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/platforms/test.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/spec.py | 7 | ||||
-rw-r--r-- | lib/spack/spack/test/architecture.py | 6 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 7 | ||||
-rw-r--r-- | lib/spack/spack/test/config.py | 84 | ||||
-rw-r--r-- | lib/spack/spack/test/mock_packages_test.py | 96 | ||||
-rw-r--r-- | lib/spack/spack/yaml_version_check.py | 4 |
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 ' |