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.py127
1 files changed, 100 insertions, 27 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 4cd89f59bf..0d8fb2893b 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -101,6 +101,8 @@ import collections
import ctypes
import hashlib
import itertools
+import os
+
from operator import attrgetter
from six import StringIO
from six import string_types
@@ -115,12 +117,13 @@ import spack.store
import spack.util.spack_json as sjson
import spack.util.spack_yaml as syaml
-from llnl.util.filesystem import find_libraries
+from llnl.util.filesystem import find_headers, find_libraries, is_exe
from llnl.util.lang import *
from llnl.util.tty.color import *
from spack.build_environment import get_path_from_module, load_module
from spack.provider_index import ProviderIndex
from spack.util.crypto import prefix_bits
+from spack.util.executable import Executable
from spack.util.prefix import Prefix
from spack.util.spack_yaml import syaml_dict
from spack.util.string import *
@@ -745,9 +748,9 @@ class FlagMap(HashableMap):
class DependencyMap(HashableMap):
-
"""Each spec has a DependencyMap containing specs for its dependencies.
The DependencyMap is keyed by name. """
+
@property
def concrete(self):
return all((d.spec.concrete and d.deptypes)
@@ -757,38 +760,104 @@ class DependencyMap(HashableMap):
return "{deps: %s}" % ', '.join(str(d) for d in sorted(self.values()))
-def _libs_default_handler(descriptor, spec, cls):
- """Default handler when for ``libs`` attribute in Spec interface.
+def _command_default_handler(descriptor, spec, cls):
+ """Default handler when looking for the 'command' attribute.
- Tries to search for ``lib{spec.name}`` recursively starting from
- `spec.prefix`.
+ Tries to search for ``spec.name`` in the ``spec.prefix.bin`` directory.
- Args:
- descriptor (ForwardQueryToPackage): descriptor that triggered
- the call
+ Parameters:
+ descriptor (ForwardQueryToPackage): descriptor that triggered the call
spec (Spec): spec that is being queried
cls (type(spec)): type of spec, to match the signature of the
- descriptor `__get__` method
+ descriptor ``__get__`` method
+
+ Returns:
+ Executable: An executable of the command
+
+ Raises:
+ RuntimeError: If the command is not found
"""
- name = 'lib' + spec.name
- shared = '+shared' in spec
- return find_libraries(name, root=spec.prefix, shared=shared, recurse=True)
+ path = os.path.join(spec.prefix.bin, spec.name)
+
+ if is_exe(path):
+ return Executable(path)
+ else:
+ msg = 'Unable to locate {0} command in {1}'
+ raise RuntimeError(msg.format(spec.name, spec.prefix.bin))
-def _cppflags_default_handler(descriptor, spec, cls):
- """Default handler for the ``cppflags`` attribute in the Spec interface.
+def _headers_default_handler(descriptor, spec, cls):
+ """Default handler when looking for the 'headers' attribute.
- The default just returns ``-I{spec.prefix.include}``.
+ Tries to search for ``*.h`` files recursively starting from
+ ``spec.prefix.include``.
- Args:
- descriptor (ForwardQueryToPackage): descriptor that triggered
- the call
+ Parameters:
+ descriptor (ForwardQueryToPackage): descriptor that triggered the call
spec (Spec): spec that is being queried
+ cls (type(spec)): type of spec, to match the signature of the
+ descriptor ``__get__`` method
+
+ Returns:
+ HeaderList: The headers in ``prefix.include``
+
+ Raises:
+ RuntimeError: If no headers are found
+ """
+ headers = find_headers('*', root=spec.prefix.include, recurse=True)
+
+ if headers:
+ return headers
+ else:
+ msg = 'Unable to locate {0} headers in {1}'
+ raise RuntimeError(msg.format(spec.name, spec.prefix.include))
+
+
+def _libs_default_handler(descriptor, spec, cls):
+ """Default handler when looking for the 'libs' attribute.
+ Tries to search for ``lib{spec.name}`` recursively starting from
+ ``spec.prefix``.
+
+ Parameters:
+ descriptor (ForwardQueryToPackage): descriptor that triggered the call
+ spec (Spec): spec that is being queried
cls (type(spec)): type of spec, to match the signature of the
descriptor ``__get__`` method
+
+ Returns:
+ LibraryList: The libraries found
+
+ Raises:
+ RuntimeError: If no libraries are found
"""
- return '-I' + spec.prefix.include
+ name = 'lib' + spec.name
+
+ if '+shared' in spec:
+ libs = find_libraries(
+ name, root=spec.prefix, shared=True, recurse=True
+ )
+ elif '~shared' in spec:
+ libs = find_libraries(
+ name, root=spec.prefix, shared=False, recurse=True
+ )
+ else:
+ # Prefer shared
+ libs = find_libraries(
+ name, root=spec.prefix, shared=True, recurse=True
+ )
+ if libs:
+ return libs
+
+ libs = find_libraries(
+ name, root=spec.prefix, shared=False, recurse=True
+ )
+
+ if libs:
+ return libs
+ else:
+ msg = 'Unable to recursively locate {0} libraries in {1}'
+ raise RuntimeError(msg.format(spec.name, spec.prefix))
class ForwardQueryToPackage(object):
@@ -797,7 +866,7 @@ class ForwardQueryToPackage(object):
def __init__(self, attribute_name, default_handler=None):
"""Create a new descriptor.
- Args:
+ Parameters:
attribute_name (str): name of the attribute to be
searched for in the Package instance
default_handler (callable, optional): default function to be
@@ -815,7 +884,7 @@ class ForwardQueryToPackage(object):
"""Retrieves the property from Package using a well defined chain
of responsibility.
- The order of call is :
+ The order of call is:
1. if the query was through the name of a virtual package try to
search for the attribute `{virtual_name}_{attribute_name}`
@@ -885,17 +954,21 @@ class ForwardQueryToPackage(object):
class SpecBuildInterface(ObjectWrapper):
+ command = ForwardQueryToPackage(
+ 'command',
+ default_handler=_command_default_handler
+ )
+
+ headers = ForwardQueryToPackage(
+ 'headers',
+ default_handler=_headers_default_handler
+ )
libs = ForwardQueryToPackage(
'libs',
default_handler=_libs_default_handler
)
- cppflags = ForwardQueryToPackage(
- 'cppflags',
- default_handler=_cppflags_default_handler
- )
-
def __init__(self, spec, name, query_parameters):
super(SpecBuildInterface, self).__init__(spec)