summaryrefslogtreecommitdiff
path: root/lib/spack/spack/spec.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/spec.py')
-rw-r--r--lib/spack/spack/spec.py95
1 files changed, 48 insertions, 47 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index f71d56435e..e61ffc0912 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -497,14 +497,10 @@ class Spec(object):
# package.py files for.
self._normal = kwargs.get('normal', False)
self._concrete = kwargs.get('concrete', False)
-#ifdef NEW
# Allow a spec to be constructed with an external path.
self.external = kwargs.get('external', None)
-#else /* not NEW */
- self.external = None
- self.external_module = None
-#endif /* not NEW */
+ self.external_module = kwargs.get('external_module', None)
# This allows users to construct a spec DAG with literals.
# Note that given two specs a and b, Spec(a) copies a, but
@@ -538,8 +534,10 @@ class Spec(object):
Known flags currently include "arch"
"""
valid_flags = FlagMap.valid_compiler_flags()
- if name == 'arch':
- self._set_architecture(value)
+ if name == 'os' or name == 'operating_system':
+ self._set_os(value)
+ elif name == 'target':
+ self._set_target(value)
elif name in valid_flags:
assert(self.compiler_flags is not None)
self.compiler_flags[name] = value.split()
@@ -553,12 +551,13 @@ class Spec(object):
self.compiler = compiler
- def _set_architecture(self, architecture):
- """Called by the parser to set the architecture."""
- if self.architecture: raise DuplicateArchitectureError(
- "Spec for '%s' cannot have two architectures." % self.name)
- self.architecture = architecture
+ def _set_os(self, value):
+ """Called by the parser to set the architecture operating system"""
+ self.architecture.platform_os = self.architecture.platform.operating_system(value)
+ def _set_target(self, value):
+ """Called by the parser to set the architecture target"""
+ self.architecture.target = self.architecture.platform.target(value)
def _add_dependency(self, spec):
"""Called by the parser to add another spec as a dependency."""
@@ -793,9 +792,9 @@ class Spec(object):
if self.architecture:
# TODO: Fix the target.to_dict to account for the tuple
# Want it to be a dict of dicts
- d['architecture'] = self.architecture.to_dict()
+ d['arch'] = self.architecture.to_dict()
else:
- d['architecture'] = None
+ d['arch'] = None
if self.compiler:
d.update(self.compiler.to_dict())
@@ -824,17 +823,12 @@ class Spec(object):
spec = Spec(name)
spec.namespace = node.get('namespace', None)
spec.versions = VersionList.from_dict(node)
-#ifdef NEW
- spec.architecture = node['arch']
if 'hash' in node:
spec._hash = node['hash']
-#else /* not NEW */
- # TODO: Need to fix the architecture.Target.from_dict
- spec.architecture = spack.architecture.arch_from_dict(node['architecture'])
+ spec.architecture = spack.architecture.arch_from_dict(node['arch'])
-#endif /* not NEW */
if node['compiler'] is None:
spec.compiler = None
else:
@@ -1423,9 +1417,19 @@ class Spec(object):
# TODO: Check out the logic here
if self.architecture is not None and other.architecture is not None:
- if self.architecture != other.architecture:
- raise UnsatisfiableArchitectureSpecError(self.architecture,
- other.architecture)
+ if self.architecture.platform is not None and other.architecture.platform is not None:
+ if self.architecture.platform != other.architecture.platform:
+ raise UnsatisfiableArchitectureSpecError(self.architecture,
+ other.architecture)
+ if self.architecture.platform_os is not None and other.architecture.platform_os is not None:
+ if self.architecture.platform_os != other.architecture.platform_os:
+ raise UnsatisfiableArchitectureSpecError(self.architecture,
+ other.architecture)
+ if self.architecture.target is not None and other.architecture.target is not None:
+ if self.architecture.target != other.architecture.target:
+ raise UnsatisfiableArchitectureSpecError(self.architecture,
+ other.architecture)
+
changed = False
if self.compiler is not None and other.compiler is not None:
@@ -1440,7 +1444,14 @@ class Spec(object):
changed |= self.compiler_flags.constrain(other.compiler_flags)
old = self.architecture
- self.architecture = self.architecture or other.architecture
+ if self.architecture is None or other.architecture is None:
+ self.architecture = self.architecture or other.architecture
+ elif self.architecture.platform is None or other.architecture.platform is None:
+ self.architecture.platform = self.architecture.platform or other.architecture.platform
+ elif self.architecture.platform_os is None of other.architecture.platform_os is None:
+ self.architecture.platform_os = self.architecture.platform_os or other.architecture.platform_os
+ elif self.architecture.target is None or other.architecture.target is None:
+ self.architecture.target = self.architecture.target or other.architecture.target
changed |= (self.architecture != old)
if deps:
@@ -1572,16 +1583,18 @@ class Spec(object):
# Architecture satisfaction is currently just string equality.
# If not strict, None means unconstrained.
- if isinstance(self.architecture, basestring):
- self.add_architecture_from_string(self.architecture)
- if isinstance(other.architecture, basestring):
- other.add_architecture_from_string(other.architecture)
+
# TODO: Need to make sure that comparisons can be made via classes
if self.architecture and other.architecture:
- if self.architecture != other.architecture:
+ if ((self.architecture.platform and other.architecture.platform and self.architecture.platform != other.architecture.platform) or
+ (self.architecture.platform_os and other.architecture.platform_os and self.architecture.platform_os != other.architecture.platform_os) or
+ (self.architecture.target and other.architecture.target and self.architecture.target != other.architecture.target)):
return False
- elif strict and (other.architecture and not self.architecture):
+ elif strict and ((other.architecture and not self.architecture) or
+ (other.architecture.platform and not self.architecture.platform) or
+ (other.architecture.platform_os and not self.architecture.platform_os) or
+ (other.architecture.target and not self.architecture.target)):
return False
if not self.compiler_flags.satisfies(other.compiler_flags, strict=strict):
@@ -1663,7 +1676,7 @@ class Spec(object):
self.architecture != other.architecture and self.compiler != other.compiler and \
self.variants != other.variants and self._normal != other._normal and \
self.concrete != other.concrete and self.external != other.external and \
- self.external_module != other.external_module)
+ self.external_module != other.external_module and self.compiler_flags != other.compiler_flags)
# Local node attributes get copied first.
self.name = other.name
@@ -1677,12 +1690,9 @@ class Spec(object):
self.variants = other.variants.copy()
self.variants.spec = self
self.external = other.external
+ self.external_module = other.external_module
self.namespace = other.namespace
-#ifdef NEW
self._hash = other._hash
-#else /* not NEW */
- self.external_module = other.external_module
-#endif /* not NEW */
# If we copy dependencies, preserve DAG structure in the new spec
if kwargs.get('deps', True):
@@ -1983,7 +1993,7 @@ class Spec(object):
write(fmt % str(self.variants), '+')
elif named_str == 'ARCHITECTURE':
if self.architecture:
- write(fmt % str(self.architecture), '=')
+ write(fmt % str(self.architecture), ' arch=')
elif named_str == 'SHA1':
if self.dependencies:
out.write(fmt % str(self.dag_hash(7)))
@@ -2202,14 +2212,11 @@ class SpecParser(spack.parse.Parser):
spec.name = spec_name
spec.versions = VersionList()
spec.variants = VariantMap(spec)
- spec.architecture = None
+ spec.architecture = spack.architecture.Arch()
spec.compiler = None
spec.external = None
-#ifdef NEW
- spec.compiler_flags = FlagMap(spec)
-#else /* not NEW */
spec.external_module = None
-#endif /* not NEW */
+ spec.compiler_flags = FlagMap(spec)
spec.dependents = DependencyMap()
spec.dependencies = DependencyMap()
spec.namespace = spec_namespace
@@ -2284,12 +2291,6 @@ class SpecParser(spack.parse.Parser):
self.check_identifier()
return self.token.value
- def architecture(self):
- #TODO: Make this work properly as a subcase of variant (includes adding names to grammar)
- self.expect(ID)
- return self.token.value
-
-
def version(self):
start = None
end = None