summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralalazo <massimiliano.culpo@googlemail.com>2016-06-18 13:31:29 +0200
committeralalazo <massimiliano.culpo@googlemail.com>2016-06-18 13:31:29 +0200
commita17d1efe7c738d08718fb46ae7a04d52c1a63dc1 (patch)
treea166e21e9410c4bbe9dd709dc34ccede3cc2e372
parent30c9d976f6e7b74b6713215e8f7c7924a9f43f43 (diff)
parent62b2f2a7c9d54fb864e6aae91f1f47a1b35d1828 (diff)
downloadspack-a17d1efe7c738d08718fb46ae7a04d52c1a63dc1.tar.gz
spack-a17d1efe7c738d08718fb46ae7a04d52c1a63dc1.tar.bz2
spack-a17d1efe7c738d08718fb46ae7a04d52c1a63dc1.tar.xz
spack-a17d1efe7c738d08718fb46ae7a04d52c1a63dc1.zip
Merge branch 'develop' of https://github.com/LLNL/spack into features/source_diffs_in_environment_modifications
Conflicts: lib/spack/spack/test/environment.py
-rw-r--r--.flake82
-rwxr-xr-xbin/spack3
-rwxr-xr-xlib/spack/env/cc44
-rw-r--r--lib/spack/llnl/util/tty/__init__.py4
-rw-r--r--lib/spack/llnl/util/tty/colify.py9
-rw-r--r--lib/spack/spack/__init__.py2
-rw-r--r--lib/spack/spack/abi.py5
-rw-r--r--lib/spack/spack/architecture.py506
-rw-r--r--lib/spack/spack/build_environment.py90
-rw-r--r--lib/spack/spack/cmd/arch.py6
-rw-r--r--lib/spack/spack/cmd/compiler.py9
-rw-r--r--lib/spack/spack/cmd/find.py21
-rw-r--r--lib/spack/spack/cmd/uninstall.py13
-rw-r--r--lib/spack/spack/compiler.py83
-rw-r--r--lib/spack/spack/compilers/__init__.py243
-rw-r--r--lib/spack/spack/compilers/clang.py2
-rw-r--r--lib/spack/spack/compilers/craype.py58
-rw-r--r--lib/spack/spack/compilers/gcc.py7
-rw-r--r--lib/spack/spack/compilers/intel.py3
-rw-r--r--lib/spack/spack/compilers/pgi.py7
-rw-r--r--lib/spack/spack/compilers/xl.py4
-rw-r--r--lib/spack/spack/concretize.py115
-rw-r--r--lib/spack/spack/config.py64
-rw-r--r--lib/spack/spack/database.py16
-rw-r--r--lib/spack/spack/directives.py2
-rw-r--r--lib/spack/spack/directory_layout.py5
-rw-r--r--lib/spack/spack/hooks/licensing.py5
-rw-r--r--lib/spack/spack/operating_systems/__init__.py0
-rw-r--r--lib/spack/spack/operating_systems/cnl.py62
-rw-r--r--lib/spack/spack/operating_systems/linux_distro.py22
-rw-r--r--lib/spack/spack/operating_systems/mac_os.py29
-rw-r--r--lib/spack/spack/package.py18
-rw-r--r--lib/spack/spack/platforms/__init__.py0
-rw-r--r--lib/spack/spack/platforms/bgq.py18
-rw-r--r--lib/spack/spack/platforms/cray_xc.py46
-rw-r--r--lib/spack/spack/platforms/darwin.py26
-rw-r--r--lib/spack/spack/platforms/linux.py24
-rw-r--r--lib/spack/spack/platforms/test.py28
-rw-r--r--lib/spack/spack/spec.py294
-rw-r--r--lib/spack/spack/test/__init__.py3
-rw-r--r--lib/spack/spack/test/architecture.py112
-rw-r--r--lib/spack/spack/test/concretize.py14
-rw-r--r--lib/spack/spack/test/config.py124
-rw-r--r--lib/spack/spack/test/environment.py4
-rw-r--r--lib/spack/spack/test/mock_packages_test.py119
-rw-r--r--lib/spack/spack/test/modules.py19
-rw-r--r--lib/spack/spack/test/multimethod.py27
-rw-r--r--lib/spack/spack/test/operating_system.py55
-rw-r--r--lib/spack/spack/test/spec_dag.py7
-rw-r--r--lib/spack/spack/test/spec_semantics.py69
-rw-r--r--lib/spack/spack/test/spec_syntax.py3
-rw-r--r--lib/spack/spack/test/versions.py54
-rw-r--r--lib/spack/spack/util/executable.py1
-rw-r--r--lib/spack/spack/version.py158
-rw-r--r--lib/spack/spack/yaml_version_check.py55
-rw-r--r--var/spack/mock_configs/site_spackconfig/compilers.yaml40
-rw-r--r--var/spack/packages/adios/package.py38
-rw-r--r--var/spack/packages/mxml/package.py26
-rw-r--r--var/spack/repos/builtin.mock/packages/externalmodule/package.py37
-rw-r--r--var/spack/repos/builtin.mock/packages/multimethod/package.py42
-rw-r--r--var/spack/repos/builtin/packages/bertini/package.py50
-rw-r--r--var/spack/repos/builtin/packages/binutils/package.py3
-rw-r--r--var/spack/repos/builtin/packages/boost/package.py79
-rw-r--r--var/spack/repos/builtin/packages/c-blosc/package.py51
-rw-r--r--var/spack/repos/builtin/packages/caliper/package.py2
-rw-r--r--var/spack/repos/builtin/packages/daal/package.py28
-rw-r--r--var/spack/repos/builtin/packages/espresso/package.py26
-rw-r--r--var/spack/repos/builtin/packages/hdf5-blosc/package.py206
-rw-r--r--var/spack/repos/builtin/packages/hpl/package.py119
-rw-r--r--var/spack/repos/builtin/packages/intel-parallel-studio/package.py144
-rw-r--r--var/spack/repos/builtin/packages/intel/package.py125
-rw-r--r--var/spack/repos/builtin/packages/ipp/package.py26
-rw-r--r--var/spack/repos/builtin/packages/libpciaccess/package.py2
-rw-r--r--var/spack/repos/builtin/packages/libpthread-stubs/package.py39
-rw-r--r--var/spack/repos/builtin/packages/libxau/package.py44
-rw-r--r--var/spack/repos/builtin/packages/libxcb/package.py7
-rw-r--r--var/spack/repos/builtin/packages/llvm/package.py12
-rw-r--r--var/spack/repos/builtin/packages/lmod/package.py26
-rw-r--r--var/spack/repos/builtin/packages/lua-luafilesystem/package.py51
-rw-r--r--var/spack/repos/builtin/packages/lua/package.py9
-rw-r--r--var/spack/repos/builtin/packages/mkl/package.py28
-rw-r--r--var/spack/repos/builtin/packages/openmpi/package.py2
-rw-r--r--var/spack/repos/builtin/packages/openssl/package.py2
-rw-r--r--var/spack/repos/builtin/packages/pcre/intel.patch12
-rw-r--r--var/spack/repos/builtin/packages/pcre/package.py3
-rw-r--r--var/spack/repos/builtin/packages/py-astropy/package.py35
-rw-r--r--var/spack/repos/builtin/packages/py-beautifulsoup4/package.py41
-rw-r--r--var/spack/repos/builtin/packages/py-emcee/package.py41
-rw-r--r--var/spack/repos/builtin/packages/py-h5py/package.py39
-rw-r--r--var/spack/repos/builtin/packages/py-iminuit/package.py46
-rw-r--r--var/spack/repos/builtin/packages/py-nestle/package.py44
-rw-r--r--var/spack/repos/builtin/packages/py-sncosmo/package.py51
-rw-r--r--var/spack/repos/builtin/packages/py-wcsaxes/package.py43
-rw-r--r--var/spack/repos/builtin/packages/python/package.py193
-rw-r--r--var/spack/repos/builtin/packages/serf/package.py11
-rw-r--r--var/spack/repos/builtin/packages/trilinos/package.py207
-rw-r--r--var/spack/repos/builtin/packages/xorg-util-macros/package.py38
-rw-r--r--var/spack/repos/builtin/packages/xproto/package.py41
98 files changed, 3918 insertions, 910 deletions
diff --git a/.flake8 b/.flake8
index 12ae2efa80..286522bc48 100644
--- a/.flake8
+++ b/.flake8
@@ -19,5 +19,5 @@
# - F999: name name be undefined or undefined from star imports.
#
[flake8]
-ignore = E221,E241,E731,F403,F821,F999
+ignore = E221,E241,E731,F403,F821,F999,F405
max-line-length = 79
diff --git a/bin/spack b/bin/spack
index 3544feb10a..9b1276a866 100755
--- a/bin/spack
+++ b/bin/spack
@@ -138,6 +138,9 @@ def main():
import spack.util.debug as debug
debug.register_interrupt_handler()
+ from spack.yaml_version_check import check_yaml_versions
+ check_yaml_versions()
+
spack.spack_working_dir = working_dir
if args.mock:
from spack.repository import RepoPath
diff --git a/lib/spack/env/cc b/lib/spack/env/cc
index 9758b74f37..1e405ae6e9 100755
--- a/lib/spack/env/cc
+++ b/lib/spack/env/cc
@@ -174,6 +174,28 @@ if [[ -z $command ]]; then
die "ERROR: Compiler '$SPACK_COMPILER_SPEC' does not support compiling $language programs."
fi
+#
+# Filter '.' and Spack environment directories out of PATH so that
+# this script doesn't just call itself
+#
+IFS=':' read -ra env_path <<< "$PATH"
+IFS=':' read -ra spack_env_dirs <<< "$SPACK_ENV_PATH"
+spack_env_dirs+=("" ".")
+PATH=""
+for dir in "${env_path[@]}"; do
+ addpath=true
+ for env_dir in "${spack_env_dirs[@]}"; do
+ if [[ $dir == $env_dir ]]; then
+ addpath=false
+ break
+ fi
+ done
+ if $addpath; then
+ PATH="${PATH:+$PATH:}$dir"
+ fi
+done
+export PATH
+
if [[ $mode == vcheck ]]; then
exec ${command} "$@"
fi
@@ -286,28 +308,6 @@ unset LD_LIBRARY_PATH
unset LD_RUN_PATH
unset DYLD_LIBRARY_PATH
-#
-# Filter '.' and Spack environment directories out of PATH so that
-# this script doesn't just call itself
-#
-IFS=':' read -ra env_path <<< "$PATH"
-IFS=':' read -ra spack_env_dirs <<< "$SPACK_ENV_PATH"
-spack_env_dirs+=("" ".")
-PATH=""
-for dir in "${env_path[@]}"; do
- addpath=true
- for env_dir in "${spack_env_dirs[@]}"; do
- if [[ $dir == $env_dir ]]; then
- addpath=false
- break
- fi
- done
- if $addpath; then
- PATH="${PATH:+$PATH:}$dir"
- fi
-done
-export PATH
-
full_command=("$command" "${args[@]}")
# In test command mode, write out full command for Spack tests.
diff --git a/lib/spack/llnl/util/tty/__init__.py b/lib/spack/llnl/util/tty/__init__.py
index c638b113fd..ee81e11a20 100644
--- a/lib/spack/llnl/util/tty/__init__.py
+++ b/lib/spack/llnl/util/tty/__init__.py
@@ -64,12 +64,14 @@ def info(message, *args, **kwargs):
format = kwargs.get('format', '*b')
stream = kwargs.get('stream', sys.stdout)
wrap = kwargs.get('wrap', False)
+ break_long_words = kwargs.get('break_long_words', False)
cprint("@%s{==>} %s" % (format, cescape(str(message))), stream=stream)
for arg in args:
if wrap:
lines = textwrap.wrap(
- str(arg), initial_indent=indent, subsequent_indent=indent)
+ str(arg), initial_indent=indent, subsequent_indent=indent,
+ break_long_words=break_long_words)
for line in lines:
stream.write(line + '\n')
else:
diff --git a/lib/spack/llnl/util/tty/colify.py b/lib/spack/llnl/util/tty/colify.py
index 429ba45882..81a83691d7 100644
--- a/lib/spack/llnl/util/tty/colify.py
+++ b/lib/spack/llnl/util/tty/colify.py
@@ -198,8 +198,13 @@ def colify(elts, **options):
for col in xrange(cols):
elt = col * rows + row
width = config.widths[col] + cextra(elts[elt])
- fmt = '%%-%ds' % width
- output.write(fmt % elts[elt])
+ if col < cols - 1:
+ fmt = '%%-%ds' % width
+ output.write(fmt % elts[elt])
+ else:
+ # Don't pad the rightmost column (sapces can wrap on
+ # small teriminals if one line is overlong)
+ output.write(elts[elt])
output.write("\n")
row += 1
diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py
index 8c6e0ba527..75ddca1abc 100644
--- a/lib/spack/spack/__init__.py
+++ b/lib/spack/spack/__init__.py
@@ -39,7 +39,9 @@ spack_file = join_path(spack_root, "bin", "spack")
lib_path = join_path(spack_root, "lib", "spack")
build_env_path = join_path(lib_path, "env")
module_path = join_path(lib_path, "spack")
+platform_path = join_path(module_path, 'platforms')
compilers_path = join_path(module_path, "compilers")
+operating_system_path = join_path(module_path, 'operating_systems')
test_path = join_path(module_path, "test")
hooks_path = join_path(module_path, "hooks")
var_path = join_path(spack_root, "var", "spack")
diff --git a/lib/spack/spack/abi.py b/lib/spack/spack/abi.py
index 91d1d2003d..38cff62af4 100644
--- a/lib/spack/spack/abi.py
+++ b/lib/spack/spack/abi.py
@@ -35,8 +35,9 @@ class ABI(object):
The current implementation is rather rough and could be improved."""
def architecture_compatible(self, parent, child):
- """Returns true iff the parent and child specs have ABI compatible architectures."""
- return not parent.architecture or not child.architecture or parent.architecture == child.architecture
+ """Returns true iff the parent and child specs have ABI compatible targets."""
+ return not parent.architecture or not child.architecture \
+ or parent.architecture == child.architecture
@memoized
diff --git a/lib/spack/spack/architecture.py b/lib/spack/spack/architecture.py
index b14cb2bea2..cbac7b41d6 100644
--- a/lib/spack/spack/architecture.py
+++ b/lib/spack/spack/architecture.py
@@ -22,68 +22,498 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
+"""
+This module contains all the elements that are required to create an
+architecture object. These include, the target processor, the operating system,
+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
+detection.
+
+There are two different types of compiler detection:
+ 1. Through the $PATH env variable (front-end detection)
+ 2. Through the tcl module system. (back-end 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.
+
+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
+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
+
+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.
+"""
import os
-import re
-import platform
+import imp
+import inspect
-from llnl.util.lang import memoized
+from llnl.util.lang import memoized, list_modules, key_ordering
+from llnl.util.filesystem import join_path
+import llnl.util.tty as tty
import spack
+import spack.compilers
+from spack.util.naming import mod_to_class
+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__("Invalid sys_type value for Spack: " + sys_type)
+ super(InvalidSysTypeError, self).__init__(
+ "Invalid sys_type value for Spack: " + sys_type)
class NoSysTypeError(serr.SpackError):
def __init__(self):
- super(NoSysTypeError,
- self).__init__("Could not determine sys_type for this machine.")
+ super(NoSysTypeError, self).__init__(
+ "Could not determine sys_type for this machine.")
+
+
+@key_ordering
+class Target(object):
+ """ Target is the processor of the host machine.
+ The host machine may have different front-end and back-end targets,
+ especially if it is a Cray machine. The target will have a name and
+ also the module_name (e.g craype-compiler). Targets will also
+ recognize which platform they came from using the set_platform method.
+ Targets will have compiler finding strategies
+ """
+
+ def __init__(self, name, module_name=None):
+ self.name = name # case of cray "ivybridge" but if it's x86_64
+ self.module_name = module_name # craype-ivybridge
+
+ # Sets only the platform name to avoid recursiveness
+
+ def _cmp_key(self):
+ return (self.name, self.module_name)
+
+ def __repr__(self):
+ return self.__str__()
+
+ def __str__(self):
+ return self.name
+
+
+@key_ordering
+class Platform(object):
+ """ Abstract class that each type of Platform will subclass.
+ Will return a instance of it once it
+ is returned
+ """
+
+ priority = None # Subclass sets number. Controls detection order
+ front_end = None
+ back_end = None
+ default = None # The default back end target. On cray ivybridge
+
+ front_os = None
+ back_os = None
+ default_os = None
+
+ def __init__(self, name):
+ self.targets = {}
+ self.operating_sys = {}
+ self.name = name
+
+ 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
+ that is reserved by spack as an alias.
+ """
+ if name in ['frontend', 'fe', 'backend', 'be', 'default_target']:
+ raise ValueError(
+ "%s is a spack reserved alias "
+ "and cannot be the name of a target" % name)
+ self.targets[name] = target
+
+ def target(self, name):
+ """This is a getter method for the target dictionary
+ that handles defaulting based on the values provided by default,
+ front-end, and back-end. This can be overwritten
+ by a subclass for which we want to provide further aliasing options.
+ """
+ if name == 'default_target':
+ name = self.default
+ elif name == 'frontend' or name == 'fe':
+ name = self.front_end
+ elif name == 'backend' or name == 'be':
+ name = self.back_end
+
+ return self.targets.get(name, None)
+
+ def add_operating_system(self, name, os_class):
+ """ Add the operating_system class object into the
+ platform.operating_sys dictionary
+ """
+ if name in ['frontend', 'fe', 'backend', 'be', 'default_os']:
+ raise ValueError(
+ "%s is a spack reserved alias "
+ "and cannot be the name of an OS" % name)
+ self.operating_sys[name] = os_class
+
+ def operating_system(self, name):
+ if name == 'default_os':
+ name = self.default_os
+ if name == 'frontend' or name == "fe":
+ name = self.front_os
+ if name == 'backend' or name == 'be':
+ name = self.back_os
+
+ return self.operating_sys.get(name, None)
+
+
+ @classmethod
+ def detect(self):
+ """ Subclass is responsible for implementing this method.
+ Returns True if the Platform class detects that
+ it is the current platform
+ and False if it's not.
+ """
+ raise NotImplementedError()
+
+
+ def __repr__(self):
+ return self.__str__()
+
+
+ def __str__(self):
+ 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()))
+ return (self.name,
+ self.default,
+ self.front_end,
+ self.back_end,
+ self.default_os,
+ self.front_os,
+ self.back_os,
+ t_keys,
+ o_keys)
+
+
+@key_ordering
+class OperatingSystem(object):
+ """ Operating System will be like a class similar to platform extended
+ by subclasses for the specifics. Operating System will contain the
+ compiler finding logic. Instead of calling two separate methods to
+ find compilers we call find_compilers method for each operating system
+ """
+
+ def __init__(self, name, version):
+ self.name = name
+ self.version = version
+
+ def __str__(self):
+ return self.name + self.version
+
+ def __repr__(self):
+ return self.__str__()
+
+ def _cmp_key(self):
+ return (self.name, self.version)
+ def find_compilers(self, *paths):
+ """
+ Return a list of compilers found in the suppied paths.
+ This invokes the find() method for each Compiler class,
+ and appends the compilers detected to a list.
+ """
+ if not paths:
+ paths = get_path('PATH')
+ # Make sure path elements exist, and include /bin directories
+ # under prefixes.
+ filtered_path = []
+ for p in paths:
+ # Eliminate symlinks and just take the real directories.
+ p = os.path.realpath(p)
+ if not os.path.isdir(p):
+ continue
+ filtered_path.append(p)
-def get_sys_type_from_spack_globals():
- """Return the SYS_TYPE from spack globals, or None if it isn't set."""
- if not hasattr(spack, "sys_type"):
- return None
- elif hasattr(spack.sys_type, "__call__"):
- return spack.sys_type()
+ # Check for a bin directory, add it if it exists
+ bin = join_path(p, 'bin')
+ if os.path.isdir(bin):
+ filtered_path.append(os.path.realpath(bin))
+
+ # Once the paths are cleaned up, do a search for each type of
+ # 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)
+
+ # 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)
+ return clist
+
+ def find_compiler(self, cmp_cls, *path):
+ """Try to find the given type of compiler in the user's
+ environment. For each set of compilers found, this returns
+ compiler objects with the cc, cxx, f77, fc paths and the
+ version filled in.
+
+ This will search for compilers with the names in cc_names,
+ cxx_names, etc. and it will group them if they have common
+ prefixes, suffixes, and versions. e.g., gcc-mp-4.7 would
+ be grouped with g++-mp-4.7 and gfortran-mp-4.7.
+ """
+ dicts = parmap(
+ lambda t: cmp_cls._find_matches_in_path(*t),
+ [(cmp_cls.cc_names, cmp_cls.cc_version) + tuple(path),
+ (cmp_cls.cxx_names, cmp_cls.cxx_version) + tuple(path),
+ (cmp_cls.f77_names, cmp_cls.f77_version) + tuple(path),
+ (cmp_cls.fc_names, cmp_cls.fc_version) + tuple(path)])
+
+ all_keys = set()
+ for d in dicts:
+ all_keys.update(d)
+
+ compilers = {}
+ for k in all_keys:
+ ver, pre, suf = k
+
+ # Skip compilers with unknown version.
+ if ver == 'unknown':
+ continue
+
+ paths = tuple(pn[k] if k in pn else None for pn in dicts)
+ spec = spack.spec.CompilerSpec(cmp_cls.name, ver)
+
+ if ver in compilers:
+ prev = compilers[ver]
+
+ # 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])
+ 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.
+ if newcount <= prevcount:
+ continue
+
+ compilers[ver] = cmp_cls(spec, self, paths)
+
+ return list(compilers.values())
+
+ def to_dict(self):
+ d = {}
+ d['name'] = self.name
+ d['version'] = self.version
+ return d
+
+@key_ordering
+class Arch(object):
+ "Architecture is now a class to help with setting attributes"
+
+ def __init__(self, platform=None, platform_os=None, target=None):
+ self.platform = platform
+ if platform and platform_os:
+ platform_os = self.platform.operating_system(platform_os)
+ self.platform_os = platform_os
+ if platform and target:
+ target = self.platform.target(target)
+ self.target = target
+
+ # Hooks for parser to use when platform is set after target or os
+ self.target_string = None
+ self.os_string = None
+
+ @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)))
+
+ def __str__(self):
+ if self.platform or self.platform_os or self.target:
+ if self.platform.name == 'darwin':
+ os_name = self.platform_os.name if self.platform_os else "None"
+ else:
+ os_name = str(self.platform_os)
+
+ return (str(self.platform) + "-" +
+ os_name + "-" + str(self.target))
+ else:
+ return ''
+
+
+ def __contains__(self, string):
+ return string in str(self)
+
+
+ def _cmp_key(self):
+ 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 = {}
+ 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_name, platform=None):
+ """ Creates new instance of target and assigns all the attributes of
+ that target from the dictionary
+ """
+ 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.
+ """
+ if not platform:
+ platform = sys_type()
+ if isinstance(os_name, dict):
+ name = os_name['name']
+ version = os_name['version']
+ return platform.operating_system(name+version)
else:
- return spack.sys_type
+ return platform.operating_system(os_name)
+
+def _platform_from_dict(platform_name):
+ """ Constructs a platform from a dictionary. """
+ platform_list = all_platforms()
+ for p in platform_list:
+ if platform_name.replace("_", "").lower() == p.__name__.lower():
+ return p()
-def get_sys_type_from_environment():
- """Return $SYS_TYPE or None if it's not defined."""
- return os.environ.get('SYS_TYPE')
+def arch_from_dict(d):
+ """ Uses _platform_from_dict, _operating_system_from_dict, _target_from_dict
+ helper methods to recreate the arch tuple from the dictionary read from
+ a yaml file
+ """
+ arch = Arch()
-def get_sys_type_from_platform():
- """Return the architecture from Python's platform module."""
- sys_type = platform.system() + '-' + platform.machine()
- sys_type = re.sub(r'[^\w-]', '_', sys_type)
- return sys_type.lower()
+ if isinstance(d, basestring):
+ # We have an old spec using a string for the architecture
+ arch.platform = Platform('spack_compatibility')
+ arch.platform_os = OperatingSystem('unknown', '')
+ arch.target = Target(d)
+
+ arch.os_string = None
+ arch.target_string = None
+ else:
+ if d is None:
+ return None
+ platform_name = d['platform']
+ os_name = d['platform_os']
+ target_name = d['target']
+
+ 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 sys_type():
- """Returns a SysType for the current machine."""
- methods = [get_sys_type_from_spack_globals, get_sys_type_from_environment,
- get_sys_type_from_platform]
+def all_platforms():
+ classes = []
+ mod_path = spack.platform_path
+ parent_module = "spack.platforms"
+
+ for name in list_modules(mod_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))
+
+ classes.append(cls)
- # search for a method that doesn't return None
- sys_type = None
- for method in methods:
- sys_type = method()
- if sys_type:
- break
+ return classes
- # Couldn't determine the sys_type for this machine.
- if sys_type is None:
- return "unknown_arch"
- if not isinstance(sys_type, basestring):
- raise InvalidSysTypeError(sys_type)
+@memoized
+def sys_type():
+ """ Gather a list of all available subclasses of platforms.
+ Sorts the list according to their priority looking. Priority is
+ an arbitrarily set number. Detects platform either using uname or
+ a file path (/opt/cray...)
+ """
+ # Try to create a Platform object using the config file FIRST
+ platform_list = all_platforms()
+ platform_list.sort(key=lambda a: a.priority)
- return sys_type
+ for platform in platform_list:
+ if platform.detect():
+ return platform()
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index d87aaa6285..7c65091d49 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -113,9 +113,66 @@ class MakeExecutable(Executable):
return super(MakeExecutable, self).__call__(*args, **kwargs)
+def load_module(mod):
+ """Takes a module name and removes modules until it is possible to
+ load that module. It then loads the provided module. Depends on the
+ modulecmd implementation of modules used in cray and lmod.
+ """
+ #Create an executable of the module command that will output python code
+ modulecmd = which('modulecmd')
+ modulecmd.add_default_arg('python')
+
+ # Read the module and remove any conflicting modules
+ # We do this without checking that they are already installed
+ # for ease of programming because unloading a module that is not
+ # loaded does nothing.
+ text = modulecmd('show', mod, output=str, error=str).split()
+ for i, word in enumerate(text):
+ if word == 'conflict':
+ exec(compile(modulecmd('unload', text[i+1], output=str, error=str), '<string>', 'exec'))
+ # Load the module now that there are no conflicts
+ load = modulecmd('load', mod, output=str, error=str)
+ exec(compile(load, '<string>', 'exec'))
+
+def get_path_from_module(mod):
+ """Inspects a TCL module for entries that indicate the absolute path
+ at which the library supported by said module can be found.
+ """
+ # Create a modulecmd executable
+ modulecmd = which('modulecmd')
+ modulecmd.add_default_arg('python')
+
+ # Read the module
+ text = modulecmd('show', mod, output=str, error=str).split('\n')
+ # If it lists its package directory, return that
+ for line in text:
+ if line.find(mod.upper()+'_DIR') >= 0:
+ words = line.split()
+ return words[2]
+
+ # If it lists a -rpath instruction, use that
+ for line in text:
+ rpath = line.find('-rpath/')
+ if rpath >= 0:
+ return line[rpath+6:line.find('/lib')]
+
+ # If it lists a -L instruction, use that
+ for line in text:
+ L = line.find('-L/')
+ if L >= 0:
+ return line[L+2:line.find('/lib')]
+
+ # If it sets the LD_LIBRARY_PATH or CRAY_LD_LIBRARY_PATH, use that
+ for line in text:
+ if line.find('LD_LIBRARY_PATH') >= 0:
+ words = line.split()
+ path = words[2]
+ return path[:path.find('/lib')]
+ # Unable to find module path
+ return None
def set_compiler_environment_variables(pkg, env):
- assert pkg.spec.concrete
+ assert(pkg.spec.concrete)
compiler = pkg.compiler
flags = pkg.spec.compiler_flags
@@ -154,6 +211,10 @@ def set_compiler_environment_variables(pkg, env):
env.set('SPACK_' + flag.upper(), ' '.join(f for f in flags[flag]))
env.set('SPACK_COMPILER_SPEC', str(pkg.spec.compiler))
+
+ for mod in compiler.modules:
+ load_module(mod)
+
return env
@@ -212,13 +273,15 @@ def set_build_environment_variables(pkg, env):
env.set(SPACK_DEBUG_LOG_DIR, spack.spack_working_dir)
# Add any pkgconfig directories to PKG_CONFIG_PATH
- pkg_config_dirs = []
- for p in dep_prefixes:
- for maybe in ('lib', 'lib64', 'share'):
- pcdir = join_path(p, maybe, 'pkgconfig')
+ for pre in dep_prefixes:
+ for directory in ('lib', 'lib64', 'share'):
+ pcdir = join_path(pre, directory, 'pkgconfig')
if os.path.isdir(pcdir):
- pkg_config_dirs.append(pcdir)
- env.set_path('PKG_CONFIG_PATH', pkg_config_dirs)
+ #pkg_config_dirs.append(pcdir)
+ env.prepend_path('PKG_CONFIG_PATH',pcdir)
+
+ if pkg.spec.architecture.target.module_name:
+ load_module(pkg.spec.architecture.target.module_name)
return env
@@ -301,6 +364,10 @@ def get_rpaths(pkg):
if os.path.isdir(d.prefix.lib))
rpaths.extend(d.prefix.lib64 for d in pkg.spec.dependencies.values()
if os.path.isdir(d.prefix.lib64))
+ # Second module is our compiler mod name. We use that to get rpaths from
+ # module show output.
+ if pkg.compiler.modules and len(pkg.compiler.modules) > 1:
+ rpaths.append(get_path_from_module(pkg.compiler.modules[1]))
return rpaths
@@ -317,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()
@@ -340,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/cmd/arch.py b/lib/spack/spack/cmd/arch.py
index dc96dd0faa..cf2f96fd21 100644
--- a/lib/spack/spack/cmd/arch.py
+++ b/lib/spack/spack/cmd/arch.py
@@ -28,8 +28,4 @@ import spack.architecture as architecture
description = "Print the architecture for this machine"
def arch(parser, args):
- configured_sys_type = architecture.get_sys_type_from_spack_globals()
- if not configured_sys_type:
- configured_sys_type = "autodetect"
- print "Configured sys_type: %s" % configured_sys_type
- print "Autodetected default sys_type: %s" % architecture.sys_type()
+ print architecture.sys_type()
diff --git a/lib/spack/spack/cmd/compiler.py b/lib/spack/spack/cmd/compiler.py
index dc7731a290..030aa77c30 100644
--- a/lib/spack/spack/cmd/compiler.py
+++ b/lib/spack/spack/cmd/compiler.py
@@ -69,8 +69,8 @@ def setup_parser(subparser):
help="Configuration scope to read from.")
-def compiler_find(args):
- """Search either $PATH or a list of paths for compilers and add them
+def compiler_add(args):
+ """Search either $PATH or a list of paths OR MODULES for compilers and add them
to Spack's configuration."""
paths = args.add_paths
if not paths:
@@ -121,6 +121,8 @@ def compiler_info(args):
print "\tcxx = %s" % c.cxx
print "\tf77 = %s" % c.f77
print "\tfc = %s" % c.fc
+ print "\tmodules = %s" % c.modules
+ print "\toperating system = %s" % c.operating_system
def compiler_list(args):
@@ -135,8 +137,7 @@ def compiler_list(args):
def compiler(parser, args):
- action = { 'add' : compiler_find,
- 'find' : compiler_find,
+ action = { 'add' : compiler_add,
'remove' : compiler_remove,
'rm' : compiler_remove,
'info' : compiler_info,
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 93c10a910f..3ec671f93f 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -31,6 +31,7 @@ import spack.spec
from llnl.util.lang import *
from llnl.util.tty.colify import *
from llnl.util.tty.color import *
+from llnl.util.lang import *
description = "Find installed spack packages"
@@ -85,6 +86,11 @@ def setup_parser(subparser):
action='store_true',
dest='missing',
help='Show missing dependencies as well as installed specs.')
+ subparser.add_argument(
+ '-v', '--variants',
+ action='store_true',
+ dest='variants',
+ help='Show variants in output (can be long)')
subparser.add_argument('-M', '--only-missing',
action='store_true',
dest='only_missing',
@@ -106,6 +112,8 @@ def display_specs(specs, **kwargs):
mode = kwargs.get('mode', 'short')
hashes = kwargs.get('long', False)
namespace = kwargs.get('namespace', False)
+ flags = kwargs.get('show_flags', False)
+ variants = kwargs.get('variants', False)
hlen = 7
if kwargs.get('very_long', False):
@@ -113,10 +121,9 @@ def display_specs(specs, **kwargs):
hlen = None
nfmt = '.' if namespace else '_'
- format_string = '$%s$@$+' % nfmt
- flags = kwargs.get('show_flags', False)
- if flags:
- format_string = '$%s$@$%%+$+' % nfmt
+ ffmt = '$%+' if flags else ''
+ vfmt = '$+' if variants else ''
+ format_string = '$%s$@%s%s' % (nfmt, ffmt, vfmt)
# Make a dict with specs keyed by architecture and compiler.
index = index_by(specs, ('architecture', 'compiler'))
@@ -162,7 +169,7 @@ def display_specs(specs, **kwargs):
string = ""
if hashes:
string += gray_hash(s, hlen) + ' '
- string += s.format('$-%s$@$+' % nfmt, color=True)
+ string += s.format('$-%s$@%s' % (nfmt, vfmt), color=True)
return string
@@ -236,4 +243,6 @@ def find(parser, args):
mode=args.mode,
long=args.long,
very_long=args.very_long,
- show_flags=args.show_flags)
+ show_flags=args.show_flags,
+ namespace=args.namespace,
+ variants=args.variants)
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
index 9fdf3045b2..a6f08d09ed 100644
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -39,6 +39,13 @@ error_message = """You can either:
b) use spack uninstall -a to uninstall ALL matching specs.
"""
+# Arguments for display_specs when we find ambiguity
+display_args = {
+ 'long': True,
+ 'show_flags': True,
+ 'variants':True
+}
+
def ask_for_confirmation(message):
while True:
@@ -92,7 +99,7 @@ def concretize_specs(specs, allow_multiple_matches=False, force=False):
if not allow_multiple_matches and len(matching) > 1:
tty.error("%s matches multiple packages:" % spec)
print()
- display_specs(matching, long=True, show_flags=True)
+ display_specs(matching, **display_args)
print()
has_errors = True
@@ -172,7 +179,7 @@ def uninstall(parser, args):
tty.error("Will not uninstall %s" % spec.format("$_$@$%@$#", color=True))
print('')
print("The following packages depend on it:")
- display_specs(lst, long=True)
+ display_specs(lst, **display_args)
print('')
has_error = True
elif args.dependents:
@@ -186,7 +193,7 @@ def uninstall(parser, args):
if not args.yes_to_all:
tty.msg("The following packages will be uninstalled : ")
print('')
- display_specs(uninstall_list, long=True, show_flags=True)
+ display_specs(uninstall_list, **display_args)
print('')
ask_for_confirmation('Do you want to proceed ? ')
diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index 2ae305f201..ce4555bc56 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -33,6 +33,7 @@ from llnl.util.filesystem import join_path
import spack.error
import spack.spec
+import spack.architecture
from spack.util.multiproc import parmap
from spack.util.executable import *
from spack.util.environment import get_path
@@ -107,19 +108,32 @@ class Compiler(object):
@property
def fc_rpath_arg(self):
return '-Wl,-rpath,'
+ # Cray PrgEnv name that can be used to load this compiler
+ PrgEnv = None
+ # Name of module used to switch versions of this compiler
+ PrgEnv_compiler = None
-
- def __init__(self, cspec, cc, cxx, f77, fc, **kwargs):
+ def __init__(self, cspec, operating_system,
+ paths, modules=[], alias=None, **kwargs):
def check(exe):
if exe is None:
return None
_verify_executables(exe)
return exe
- self.cc = check(cc)
- self.cxx = check(cxx)
- self.f77 = check(f77)
- self.fc = check(fc)
+ self.cc = check(paths[0])
+ self.cxx = check(paths[1])
+ if len(paths) > 2:
+ self.f77 = check(paths[2])
+ if len(paths) == 3:
+ self.fc = self.f77
+ else:
+ self.fc = check(paths[3])
+
+ #self.cc = check(cc)
+ #self.cxx = check(cxx)
+ #self.f77 = check(f77)
+ #self.fc = check(fc)
# Unfortunately have to make sure these params are accepted
# in the same order they are returned by sorted(flags)
@@ -130,8 +144,10 @@ class Compiler(object):
if value is not None:
self.flags[flag] = value.split()
+ self.operating_system = operating_system
self.spec = cspec
-
+ self.modules = modules
+ self.alias = alias
@property
def version(self):
@@ -258,57 +274,6 @@ class Compiler(object):
successful.reverse()
return dict(((v, p, s), path) for v, p, s, path in successful)
- @classmethod
- def find(cls, *path):
- """Try to find this type of compiler in the user's
- environment. For each set of compilers found, this returns
- compiler objects with the cc, cxx, f77, fc paths and the
- version filled in.
-
- This will search for compilers with the names in cc_names,
- cxx_names, etc. and it will group them if they have common
- prefixes, suffixes, and versions. e.g., gcc-mp-4.7 would
- be grouped with g++-mp-4.7 and gfortran-mp-4.7.
- """
- dicts = parmap(
- lambda t: cls._find_matches_in_path(*t),
- [(cls.cc_names, cls.cc_version) + tuple(path),
- (cls.cxx_names, cls.cxx_version) + tuple(path),
- (cls.f77_names, cls.f77_version) + tuple(path),
- (cls.fc_names, cls.fc_version) + tuple(path)])
-
- all_keys = set()
- for d in dicts:
- all_keys.update(d)
-
- compilers = {}
- for k in all_keys:
- ver, pre, suf = k
-
- # Skip compilers with unknown version.
- if ver == 'unknown':
- continue
-
- paths = tuple(pn[k] if k in pn else None for pn in dicts)
- spec = spack.spec.CompilerSpec(cls.name, ver)
-
- if ver in compilers:
- prev = compilers[ver]
-
- # 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])
- 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.
- if newcount <= prevcount:
- continue
-
- compilers[ver] = cls(spec, *paths)
-
- return list(compilers.values())
-
-
def __repr__(self):
"""Return a string representation of the compiler toolchain."""
return self.__str__()
@@ -317,7 +282,7 @@ class Compiler(object):
def __str__(self):
"""Return a string representation of the compiler toolchain."""
return "%s(%s)" % (
- self.name, '\n '.join((str(s) for s in (self.cc, self.cxx, self.f77, self.fc))))
+ self.name, '\n '.join((str(s) for s in (self.cc, self.cxx, self.f77, self.fc, self.modules, str(self.operating_system)))))
class CompilerAccessError(spack.error.SpackError):
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index 7c951ae8bc..4b546c2cbf 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -28,6 +28,11 @@ system and configuring Spack to use multiple compilers.
import imp
import os
import platform
+import copy
+import hashlib
+import base64
+import yaml
+import sys
from llnl.util.lang import memoized, list_modules
from llnl.util.filesystem import join_path
@@ -45,7 +50,8 @@ from spack.util.naming import mod_to_class
from spack.util.environment import get_path
_imported_compilers_module = 'spack.compilers'
-_required_instance_vars = ['cc', 'cxx', 'f77', 'fc']
+_path_instance_vars = ['cc', 'cxx', 'f77', 'fc']
+_other_instance_vars = ['modules', 'operating_system']
# TODO: customize order in config file
if platform.system() == 'Darwin':
@@ -64,107 +70,103 @@ def _auto_compiler_spec(function):
def _to_dict(compiler):
"""Return a dict version of compiler suitable to insert in YAML."""
+ d = {}
+ d['spec'] = str(compiler.spec)
+ d['paths'] = dict( (attr, getattr(compiler, attr, None)) for attr in _path_instance_vars )
+ d['operating_system'] = str(compiler.operating_system)
+ d['modules'] = compiler.modules if compiler.modules else []
+
+ if compiler.alias:
+ d['alias'] = compiler.alias
+
return {
- str(compiler.spec) : dict(
- (attr, getattr(compiler, attr, None))
- for attr in _required_instance_vars)
+ 'compiler': d
}
-def get_compiler_config(arch=None, scope=None):
+def get_compiler_config(scope=None):
"""Return the compiler configuration for the specified architecture.
"""
- # Check whether we're on a front-end (native) architecture.
- my_arch = spack.architecture.sys_type()
- if arch is None:
- arch = my_arch
-
def init_compiler_config():
"""Compiler search used when Spack has no compilers."""
- config[arch] = {}
- compilers = find_compilers(*get_path('PATH'))
+ compilers = find_compilers()
+ compilers_dict = []
for compiler in compilers:
- config[arch].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
# configured. Avoid updating automatically if there ARE site
# compilers configured but no user ones.
- if arch == my_arch and arch not in config:
+# if (isinstance(arch, basestring) or arch == my_arch) and arch not in config:
+ if not config:
if scope is None:
# We know no compilers were configured in any scope.
init_compiler_config()
+ config = spack.config.get_config('compilers', scope=scope)
elif scope == 'user':
# Check the site config and update the user config if
# nothing is configured at the site level.
site_config = spack.config.get_config('compilers', scope='site')
if not site_config:
init_compiler_config()
+ config = spack.config.get_config('compilers', scope=scope)
- return config[arch] if arch in config else {}
+ return config
-def add_compilers_to_config(compilers, arch=None, scope=None):
+def add_compilers_to_config(compilers, scope=None):
"""Add compilers to the config for the specified architecture.
Arguments:
- compilers: a list of Compiler objects.
- - arch: arch to add compilers for.
- scope: configuration scope to modify.
"""
- if arch is None:
- arch = spack.architecture.sys_type()
-
- compiler_config = get_compiler_config(arch, scope)
+ compiler_config = get_compiler_config(scope)
for compiler in compilers:
- compiler_config[str(compiler.spec)] = dict(
- (c, getattr(compiler, c, "None"))
- for c in _required_instance_vars)
+ compiler_config.append(_to_dict(compiler))
- update = { arch : compiler_config }
- spack.config.update_config('compilers', update, scope)
+ spack.config.update_config('compilers', compiler_config, scope)
@_auto_compiler_spec
-def remove_compiler_from_config(compiler_spec, arch=None, scope=None):
+def remove_compiler_from_config(compiler_spec, scope=None):
"""Remove compilers from the config, by spec.
Arguments:
- compiler_specs: a list of CompilerSpec objects.
- - arch: arch to add compilers for.
- scope: configuration scope to modify.
"""
- if arch is None:
- arch = spack.architecture.sys_type()
-
- compiler_config = get_compiler_config(arch, scope)
- del compiler_config[str(compiler_spec)]
- update = { arch : compiler_config }
+ compiler_config = get_compiler_config(scope)
+ matches = [(a,c) for (a,c) in compiler_config.items() if c['spec'] == compiler_spec]
+ if len(matches) == 1:
+ del compiler_config[matches[0][0]]
+ else:
+ CompilerSpecInsufficientlySpecificError(compiler_spec)
- spack.config.update_config('compilers', update, scope)
+ spack.config.update_config('compilers', compiler_config, scope)
+_cache_config_file = {}
-def all_compilers_config(arch=None, scope=None):
+def all_compilers_config(scope=None):
"""Return a set of specs for all the compiler versions currently
available to build with. These are instances of CompilerSpec.
"""
# Get compilers for this architecture.
- arch_config = get_compiler_config(arch, scope)
+ global _cache_config_file #Create a cache of the config file so we don't load all the time.
- # Merge 'all' compilers with arch-specific ones.
- # Arch-specific compilers have higher precedence.
- merged_config = get_compiler_config('all', scope=scope)
- merged_config = spack.config._merge_yaml(merged_config, arch_config)
-
- return merged_config
+ if not _cache_config_file:
+ _cache_config_file = get_compiler_config(scope)
+ return _cache_config_file
+ else:
+ return _cache_config_file
-def all_compilers(arch=None, scope=None):
+def all_compilers(scope=None):
# Return compiler specs from the merged config.
- return [spack.spec.CompilerSpec(s)
- for s in all_compilers_config(arch, scope)]
+ return [spack.spec.CompilerSpec(s['compiler']['spec'])
+ for s in all_compilers_config(scope)]
def default_compiler():
@@ -179,37 +181,19 @@ def default_compiler():
return sorted(versions)[-1]
-def find_compilers(*path):
+def find_compilers():
"""Return a list of compilers found in the suppied paths.
- This invokes the find() method for each Compiler class,
- and appends the compilers detected to a list.
+ This invokes the find_compilers() method for each operating
+ system associated with the host platform, and appends
+ the compilers detected to a list.
"""
- # Make sure path elements exist, and include /bin directories
- # under prefixes.
- filtered_path = []
- for p in path:
- # Eliminate symlinks and just take the real directories.
- p = os.path.realpath(p)
- if not os.path.isdir(p):
- continue
- filtered_path.append(p)
-
- # Check for a bin directory, add it if it exists
- bin = join_path(p, 'bin')
- if os.path.isdir(bin):
- filtered_path.append(os.path.realpath(bin))
-
- # Once the paths are cleaned up, do a search for each type of
- # compiler. We can spawn a bunch of parallel searches to reduce
- # the overhead of spelunking all these directories.
- types = all_compiler_types()
- compiler_lists = parmap(lambda cls: cls.find(*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)
- return clist
+ # Find compilers for each operating system class
+ oss = all_os_classes()
+ compiler_lists = []
+ for os in oss:
+ compiler_lists.extend(os.find_compilers())
+ return compiler_lists
def supported_compilers():
"""Return a set of names of compilers supported by Spack.
@@ -227,51 +211,83 @@ def supported(compiler_spec):
@_auto_compiler_spec
-def find(compiler_spec, arch=None, scope=None):
+def find(compiler_spec, scope=None):
"""Return specs of available compilers that match the supplied
compiler spec. Return an list if nothing found."""
- return [c for c in all_compilers(arch, scope) if c.satisfies(compiler_spec)]
+ return [c for c in all_compilers(scope) if c.satisfies(compiler_spec)]
@_auto_compiler_spec
-def compilers_for_spec(compiler_spec, arch=None, 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.
"""
- config = all_compilers_config(arch, scope)
+ platform = kwargs.get("platform", None)
+ config = all_compilers_config(scope)
+
+ def get_compilers(cspec):
+ compilers = []
+
+ for items in config:
+ if items['compiler']['spec'] != str(cspec):
+ continue
+ items = items['compiler']
+
+ if not ('paths' in items and all(n in items['paths'] for n in _path_instance_vars)):
+ raise InvalidCompilerConfigurationError(cspec)
+
+ cls = class_for_compiler_name(cspec.name)
- def get_compiler(cspec):
- items = config[str(cspec)]
+ compiler_paths = []
+ for c in _path_instance_vars:
+ compiler_path = items['paths'][c]
+ if compiler_path != "None":
+ compiler_paths.append(compiler_path)
+ else:
+ compiler_paths.append(None)
- if not all(n in items for n in _required_instance_vars):
- raise InvalidCompilerConfigurationError(cspec)
+ mods = items.get('modules')
+ if mods == 'None':
+ mods = []
- cls = class_for_compiler_name(cspec.name)
- compiler_paths = []
- for c in _required_instance_vars:
- compiler_path = items[c]
- if compiler_path != "None":
- compiler_paths.append(compiler_path)
+ if 'operating_system' in items:
+ operating_system = spack.architecture._operating_system_from_dict(items['operating_system'], platform)
else:
- compiler_paths.append(None)
+ operating_system = None
- flags = {}
- for f in spack.spec.FlagMap.valid_compiler_flags():
- if f in items:
- flags[f] = items[f]
- return cls(cspec, *compiler_paths, **flags)
- matches = find(compiler_spec, arch, scope)
- return [get_compiler(cspec) for cspec in matches]
+ alias = items['alias'] if 'alias' in items else None
+
+ flags = {}
+ for f in spack.spec.FlagMap.valid_compiler_flags():
+ if f in items:
+ flags[f] = items[f]
+
+ compilers.append(cls(cspec, operating_system, compiler_paths, mods, alias, **flags))
+
+ return compilers
+
+ matches = set(find(compiler_spec, scope))
+ compilers = []
+ for cspec in matches:
+ compilers.extend(get_compilers(cspec))
+ return compilers
+# return [get_compilers(cspec) for cspec in matches]
@_auto_compiler_spec
-def compiler_for_spec(compiler_spec):
+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 = compilers_for_spec(compiler_spec)
- assert(len(compilers) == 1)
+
+ 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)
+ if len(compilers) > 1:
+ raise CompilerSpecInsufficientlySpecificError(compiler_spec)
return compilers[0]
@@ -289,6 +305,19 @@ def class_for_compiler_name(compiler_name):
return cls
+def all_os_classes():
+ """
+ Return the list of classes for all operating systems available on
+ this platform
+ """
+ classes = []
+
+ platform = spack.architecture.sys_type()
+ for os_class in platform.operating_sys.values():
+ classes.append(os_class)
+
+ return classes
+
def all_compiler_types():
return [class_for_compiler_name(c) for c in supported_compilers()]
@@ -298,9 +327,19 @@ class InvalidCompilerConfigurationError(spack.error.SpackError):
super(InvalidCompilerConfigurationError, self).__init__(
"Invalid configuration for [compiler \"%s\"]: " % compiler_spec,
"Compiler configuration must contain entries for all compilers: %s"
- % _required_instance_vars)
+ % _path_instance_vars)
class NoCompilersError(spack.error.SpackError):
def __init__(self):
super(NoCompilersError, self).__init__("Spack could not find any compilers!")
+
+class NoCompilerForSpecError(spack.error.SpackError):
+ def __init__(self, compiler_spec, target):
+ super(NoCompilerForSpecError, self).__init__("No compilers for operating system %s satisfy spec %s" % (
+ target, compiler_spec))
+
+class CompilerSpecInsufficientlySpecificError(spack.error.SpackError):
+ def __init__(self, compiler_spec):
+ super(CompilerSpecInsufficientlySpecificError, self).__init__("Multiple compilers satisfy spec %s",
+ compiler_spec)
diff --git a/lib/spack/spack/compilers/clang.py b/lib/spack/spack/compilers/clang.py
index 072bcd065f..00b406d820 100644
--- a/lib/spack/spack/compilers/clang.py
+++ b/lib/spack/spack/compilers/clang.py
@@ -73,7 +73,7 @@ class Clang(Compiler):
return "-std=c++11"
@classmethod
- def default_version(self, comp):
+ def default_version(cls, comp):
"""The '--version' option works for clang compilers.
On most platforms, output looks like this::
diff --git a/lib/spack/spack/compilers/craype.py b/lib/spack/spack/compilers/craype.py
new file mode 100644
index 0000000000..4ba8b110ec
--- /dev/null
+++ b/lib/spack/spack/compilers/craype.py
@@ -0,0 +1,58 @@
+##############################################################################}
+# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://scalability-llnl.github.io/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License (as published by
+# the Free Software Foundation) version 2.1 dated February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+import llnl.util.tty as tty
+
+#from spack.build_environment import load_module
+from spack.compiler import *
+#from spack.version import ver
+
+class Craype(Compiler):
+ # Subclasses use possible names of C compiler
+ cc_names = ['cc']
+
+ # Subclasses use possible names of C++ compiler
+ cxx_names = ['CC']
+
+ # Subclasses use possible names of Fortran 77 compiler
+ f77_names = ['ftn']
+
+ # Subclasses use possible names of Fortran 90 compiler
+ fc_names = ['ftn']
+
+ # MacPorts builds gcc versions with prefixes and -mp-X.Y suffixes.
+ suffixes = [r'-mp-\d\.\d']
+
+ PrgEnv = 'PrgEnv-cray'
+ PrgEnv_compiler = 'craype'
+
+ link_paths = { 'cc' : 'cc',
+ 'cxx' : 'c++',
+ 'f77' : 'f77',
+ 'fc' : 'fc'}
+
+ @classmethod
+ def default_version(cls, comp):
+ return get_compiler_version(comp, r'([Vv]ersion).*(\d+(\.\d+)+)')
+
diff --git a/lib/spack/spack/compilers/gcc.py b/lib/spack/spack/compilers/gcc.py
index 164bddeb3f..3f552eaece 100644
--- a/lib/spack/spack/compilers/gcc.py
+++ b/lib/spack/spack/compilers/gcc.py
@@ -49,6 +49,9 @@ class Gcc(Compiler):
'f77' : 'gcc/gfortran',
'fc' : 'gcc/gfortran' }
+ PrgEnv = 'PrgEnv-gnu'
+ PrgEnv_compiler = 'gcc'
+
@property
def openmp_flag(self):
return "-fopenmp"
@@ -74,9 +77,9 @@ class Gcc(Compiler):
return get_compiler_version(
fc, '-dumpversion',
# older gfortran versions don't have simple dumpversion output.
- r'(?:GNU Fortran \(GCC\))?(\d+\.\d+(?:\.\d+)?)')
+ r'(?:GNU Fortran \(GCC\))?(\d+\.\d+(?:\.\d+)?)', module)
@classmethod
def f77_version(cls, f77):
- return cls.fc_version(f77)
+ return cls.fc_version(f77, module)
diff --git a/lib/spack/spack/compilers/intel.py b/lib/spack/spack/compilers/intel.py
index 5007ece645..6cad03ff47 100644
--- a/lib/spack/spack/compilers/intel.py
+++ b/lib/spack/spack/compilers/intel.py
@@ -45,6 +45,9 @@ class Intel(Compiler):
'f77' : 'intel/ifort',
'fc' : 'intel/ifort' }
+ PrgEnv = 'PrgEnv-intel'
+ PrgEnv_compiler = 'intel'
+
@property
def openmp_flag(self):
if self.version < ver('16.0'):
diff --git a/lib/spack/spack/compilers/pgi.py b/lib/spack/spack/compilers/pgi.py
index d42148dc49..6d36d8bfa6 100644
--- a/lib/spack/spack/compilers/pgi.py
+++ b/lib/spack/spack/compilers/pgi.py
@@ -44,6 +44,12 @@ class Pgi(Compiler):
'f77' : 'pgi/pgfortran',
'fc' : 'pgi/pgfortran' }
+
+
+ PrgEnv = 'PrgEnv-pgi'
+ PrgEnv_compiler = 'pgi'
+
+
@property
def openmp_flag(self):
return "-mp"
@@ -52,7 +58,6 @@ class Pgi(Compiler):
def cxx11_flag(self):
return "-std=c++11"
-
@classmethod
def default_version(cls, comp):
"""The '-V' option works for all the PGI compilers.
diff --git a/lib/spack/spack/compilers/xl.py b/lib/spack/spack/compilers/xl.py
index bda2de4b87..b1431436ad 100644
--- a/lib/spack/spack/compilers/xl.py
+++ b/lib/spack/spack/compilers/xl.py
@@ -56,8 +56,9 @@ class Xl(Compiler):
else:
return "-qlanglvl=extended0x"
+
@classmethod
- def default_version(self, comp):
+ def default_version(cls, comp):
"""The '-qversion' is the standard option fo XL compilers.
Output looks like this::
@@ -83,6 +84,7 @@ class Xl(Compiler):
return get_compiler_version(
comp, '-qversion',r'([0-9]?[0-9]\.[0-9])')
+
@classmethod
def fc_version(cls, fc):
"""The fortran and C/C++ versions of the XL compiler are always two units apart.
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 4f78bfc347..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)
@@ -187,31 +188,64 @@ class DefaultConcretizer(object):
return True # Things changed
+ def _concretize_operating_system(self, spec):
+ platform = spec.architecture.platform
+ if spec.architecture.platform_os is not None and isinstance(
+ spec.architecture.platform_os,spack.architecture.OperatingSystem):
+ return False
- 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:
+ if spec.root.architecture and spec.root.architecture.platform_os:
+ if isinstance(spec.root.architecture.platform_os,spack.architecture.OperatingSystem):
+ spec.architecture.platform_os = spec.root.architecture.platform_os
+ else:
+ spec.architecture.platform_os = spec.architecture.platform.operating_system('default_os')
+ return True #changed
+
+ def _concretize_target(self, spec):
+ platform = spec.architecture.platform
+ if spec.architecture.target is not None and isinstance(
+ spec.architecture.target, spack.architecture.Target):
return False
+ if spec.root.architecture and spec.root.architecture.target:
+ if isinstance(spec.root.architecture.target,spack.architecture.Target):
+ spec.architecture.target = spec.root.architecture.target
+ else:
+ spec.architecture.target = spec.architecture.platform.target('default_target')
+ return True #changed
- if spec.root.architecture:
- spec.architecture = spec.root.architecture
+ def _concretize_platform(self, spec):
+ if spec.architecture.platform is not None and isinstance(
+ spec.architecture.platform, spack.architecture.Platform):
+ return False
+ if spec.root.architecture and spec.root.architecture.platform:
+ if isinstance(spec.root.architecture.platform,spack.architecture.Platform):
+ spec.architecture.platform = spec.root.architecture.platform
else:
- spec.architecture = spack.architecture.sys_type()
+ spec.architecture.platform = spack.architecture.sys_type()
+ return True #changed?
+
+ def concretize_architecture(self, spec):
+ """If the spec is empty provide the defaults of the platform. If the
+ architecture is not a basestring, then check if either the platform,
+ target or operating system are concretized. If any of the fields are
+ changed then return True. If everything is concretized (i.e the
+ architecture attribute is a namedtuple of classes) then return False.
+ If the target is a string type, then convert the string into a
+ concretized architecture. If it has no architecture and the root of the
+ DAG has an architecture, then use the root otherwise use the defaults
+ on the platform.
+ """
+ if spec.architecture is None:
+ # Set the architecture to all defaults
+ spec.architecture = spack.architecture.Arch()
+ return True
+
+ # Concretize the operating_system and target based of the spec
+ ret = any((self._concretize_platform(spec),
+ self._concretize_operating_system(spec),
+ self._concretize_target(spec)))
+ return ret
- assert(spec.architecture is not None)
- return True # changed
def concretize_variants(self, spec):
@@ -238,6 +272,23 @@ class DefaultConcretizer(object):
build with the compiler that will be used by libraries that
link to this one, to maximize compatibility.
"""
+ # Pass on concretizing the compiler if the target is not yet determined
+ if not spec.architecture.platform_os:
+ #Although this usually means changed, this means awaiting other changes
+ return True
+
+ # 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, 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
+
+
all_compilers = spack.compilers.all_compilers()
if (spec.compiler and
@@ -247,6 +298,7 @@ class DefaultConcretizer(object):
#Find the another spec that has a compiler, or the root if none do
other_spec = spec if spec.compiler else find_spec(spec, lambda(x) : x.compiler)
+
if not other_spec:
other_spec = spec.root
other_compiler = other_spec.compiler
@@ -265,7 +317,12 @@ class DefaultConcretizer(object):
raise UnavailableCompilerVersionError(other_compiler)
# copy concrete version into other_compiler
- spec.compiler = matches[0].copy()
+ index = 0
+ while not _proper_compiler_style(matches[index], spec.architecture):
+ index += 1
+ if index == len(matches) - 1:
+ raise NoValidVersionError(spec)
+ spec.compiler = matches[index].copy()
assert(spec.compiler.concrete)
return True # things changed.
@@ -276,15 +333,21 @@ class DefaultConcretizer(object):
compiler is used, defaulting to no compiler flags in the spec.
Default specs set at the compiler level will still be added later.
"""
+
+
+ if not spec.architecture.platform_os:
+ #Although this usually means changed, this means awaiting other changes
+ return True
+
ret = False
for flag in spack.spec.FlagMap.valid_compiler_flags():
try:
nearest = next(p for p in spec.traverse(direction='parents')
if ((p.compiler == spec.compiler and p is not spec)
and flag in p.compiler_flags))
- if ((not flag in spec.compiler_flags) or
- sorted(spec.compiler_flags[flag]) != sorted(nearest.compiler_flags[flag])):
- if flag in spec.compiler_flags:
+ if not flag in spec.compiler_flags or \
+ not (sorted(spec.compiler_flags[flag]) >= sorted(nearest.compiler_flags[flag])):
+ if flag in spec.compiler_flags:
spec.compiler_flags[flag] = list(set(spec.compiler_flags[flag]) |
set(nearest.compiler_flags[flag]))
else:
@@ -307,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)
+ 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 88544aa7bb..db0787edc6 100644
--- a/lib/spack/spack/config.py
+++ b/lib/spack/spack/config.py
@@ -135,7 +135,7 @@ from yaml.error import MarkedYAMLError
# Hacked yaml for configuration files preserves line numbers.
import spack.util.spack_yaml as syaml
-
+from spack.build_environment import get_path_from_module
"""Dict from section names -> schema for that section."""
section_schemas = {
@@ -146,18 +146,17 @@ section_schemas = {
'additionalProperties': False,
'patternProperties': {
'compilers:?': { # optional colon for overriding site config.
- 'type': 'object',
- 'default': {},
- 'additionalProperties': False,
- 'patternProperties': {
- r'\w[\w-]*': { # architecture
+ 'type': 'array',
+ 'items': {
+ 'compiler': {
'type': 'object',
'additionalProperties': False,
- 'patternProperties': {
- r'\w[\w-]*@\w[\w-]*': { # compiler spec
+ 'required': ['paths', 'spec', 'modules', 'operating_system'],
+ 'properties': {
+ 'paths': {
'type': 'object',
- 'additionalProperties': False,
'required': ['cc', 'cxx', 'f77', 'fc'],
+ 'additionalProperties': False,
'properties': {
'cc': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]},
@@ -167,20 +166,27 @@ section_schemas = {
{'type' : 'null' }]},
'fc': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]},
- 'fflags': { 'anyOf': [ {'type' : 'string' },
- {'type' : 'null' }]},
- 'cppflags': { 'anyOf': [ {'type' : 'string' },
+ 'cflags': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]},
- 'cflags': { 'anyOf': [ {'type' : 'string' },
+ 'cxxflags': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]},
- 'cxxflags': { 'anyOf': [ {'type' : 'string' },
+ 'fflags': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]},
- 'ldflags': { 'anyOf': [ {'type' : 'string' },
+ 'cppflags': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]},
- 'ldlibs': { 'anyOf': [ {'type' : 'string' },
+ 'ldflags': { 'anyOf': [ {'type' : 'string' },
{'type' : 'null' }]},
- },},},},},},},},
-
+ 'ldlibs': { 'anyOf': [ {'type' : 'string' },
+ {'type' : 'null' }]}}},
+ 'spec': { 'type': 'string'},
+ 'operating_system': { 'type': 'string'},
+ 'alias': { 'anyOf': [ {'type' : 'string'},
+ {'type' : 'null' }]},
+ 'modules': { 'anyOf': [ {'type' : 'string'},
+ {'type' : 'null' },
+ {'type': 'array'},
+ ]}
+ },},},},},},
'mirrors': {
'$schema': 'http://json-schema.org/schema#',
'title': 'Spack mirror configuration file schema',
@@ -206,7 +212,6 @@ section_schemas = {
'default': [],
'items': {
'type': 'string'},},},},
-
'packages': {
'$schema': 'http://json-schema.org/schema#',
'title': 'Spack package configuration file schema',
@@ -236,6 +241,10 @@ section_schemas = {
'type': 'boolean',
'default': True,
},
+ 'modules': {
+ 'type' : 'object',
+ 'default' : {},
+ },
'providers': {
'type': 'object',
'default': {},
@@ -575,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.
@@ -679,7 +687,8 @@ def spec_externals(spec):
external_specs = []
pkg_paths = allpkgs.get(name, {}).get('paths', None)
- if not pkg_paths:
+ pkg_modules = allpkgs.get(name, {}).get('modules', None)
+ if (not pkg_paths) and (not pkg_modules):
return []
for external_spec, path in pkg_paths.iteritems():
@@ -690,6 +699,17 @@ def spec_externals(spec):
external_spec = spack.spec.Spec(external_spec, external=path)
if external_spec.satisfies(spec):
external_specs.append(external_spec)
+
+ for external_spec, module in pkg_modules.iteritems():
+ if not module:
+ continue
+
+ path = get_path_from_module(module)
+
+ external_spec = spack.spec.Spec(external_spec, external=path, external_module=module)
+ if external_spec.satisfies(spec):
+ external_specs.append(external_spec)
+
return external_specs
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index e768ddf5fe..f941346bb1 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
@@ -309,7 +311,11 @@ class Database(object):
for spec in directory_layout.all_specs():
# Create a spec for each known package and add it.
path = directory_layout.path_for_spec(spec)
- self._add(spec, path, directory_layout)
+ old_info = old_data.get(spec.dag_hash())
+ explicit = False
+ if old_info is not None:
+ explicit = old_info.explicit
+ self._add(spec, path, directory_layout, explicit=explicit)
self._check_ref_counts()
diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index 51b26773e2..ca8f21dc08 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -257,7 +257,7 @@ def variant(pkg, name, default=False, description=""):
"""Define a variant for the package. Packager can specify a default
value (on or off) as well as a text description."""
- default = bool(default)
+ default = default
description = str(description).strip()
if not re.match(spack.spec.identifier_re, name):
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index 32d27d7bd0..7e20365b0f 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -165,7 +165,7 @@ class DirectoryLayout(object):
class YamlDirectoryLayout(DirectoryLayout):
"""Lays out installation directories like this::
<install root>/
- <architecture>/
+ <target>/
<compiler>-<compiler version>/
<name>-<version>-<variants>-<hash>
@@ -207,8 +207,7 @@ class YamlDirectoryLayout(DirectoryLayout):
spec.version,
spec.dag_hash(self.hash_len))
- path = join_path(
- spec.architecture,
+ path = join_path(spec.architecture,
"%s-%s" % (spec.compiler.name, spec.compiler.version),
dir_name)
diff --git a/lib/spack/spack/hooks/licensing.py b/lib/spack/spack/hooks/licensing.py
index 0f63b0e05a..9010b84154 100644
--- a/lib/spack/spack/hooks/licensing.py
+++ b/lib/spack/spack/hooks/licensing.py
@@ -26,7 +26,7 @@ import os
import spack
import llnl.util.tty as tty
-from llnl.util.filesystem import join_path
+from llnl.util.filesystem import join_path, mkdirp
def pre_install(pkg):
@@ -154,6 +154,9 @@ def symlink_license(pkg):
target = pkg.global_license_file
for filename in pkg.license_files:
link_name = join_path(pkg.prefix, filename)
+ license_dir = os.path.dirname(link_name)
+ if not os.path.exists(license_dir):
+ mkdirp(license_dir)
if os.path.exists(target):
os.symlink(target, link_name)
tty.msg("Added local symlink %s to global license file" %
diff --git a/lib/spack/spack/operating_systems/__init__.py b/lib/spack/spack/operating_systems/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/spack/spack/operating_systems/__init__.py
diff --git a/lib/spack/spack/operating_systems/cnl.py b/lib/spack/spack/operating_systems/cnl.py
new file mode 100644
index 0000000000..c160a60be8
--- /dev/null
+++ b/lib/spack/spack/operating_systems/cnl.py
@@ -0,0 +1,62 @@
+import re
+import os
+
+from spack.architecture import OperatingSystem
+from spack.util.executable import *
+import spack.spec
+from spack.util.multiproc import parmap
+import spack.compilers
+
+class Cnl(OperatingSystem):
+ """ Compute Node Linux (CNL) is the operating system used for the Cray XC
+ series super computers. It is a very stripped down version of GNU/Linux.
+ Any compilers found through this operating system will be used with
+ modules. If updated, user must make sure that version and name are
+ updated to indicate that OS has been upgraded (or downgraded)
+ """
+ def __init__(self):
+ name = 'CNL'
+ version = '10'
+ super(Cnl, self).__init__(name, version)
+
+
+ def find_compilers(self, *paths):
+ types = spack.compilers.all_compiler_types()
+ compiler_lists = parmap(lambda cmp_cls: self.find_compiler(cmp_cls, *paths), 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)
+ return clist
+
+
+ def find_compiler(self, cmp_cls, *paths):
+ compilers = []
+ if cmp_cls.PrgEnv:
+ if not cmp_cls.PrgEnv_compiler:
+ tty.die('Must supply PrgEnv_compiler with PrgEnv')
+
+ modulecmd = which('modulecmd')
+ modulecmd.add_default_arg('python')
+
+ # Save the environment variable to restore later
+ old_modulepath = os.environ['MODULEPATH']
+ # if given any explicit paths, search them for module files too
+ if paths:
+ module_paths = ':' + ':'.join(p for p in paths)
+ os.environ['MODULEPATH'] = module_paths
+
+ output = modulecmd('avail', cmp_cls.PrgEnv_compiler, output=str, error=str)
+ matches = re.findall(r'(%s)/([\d\.]+[\d])' % cmp_cls.PrgEnv_compiler, output)
+ for name, version in matches:
+ v = version
+ comp = cmp_cls(spack.spec.CompilerSpec(name + '@' + v), self,
+ ['cc', 'CC', 'ftn'], [cmp_cls.PrgEnv, name +'/' + v])
+
+ compilers.append(comp)
+
+ # Restore modulepath environment variable
+ if paths:
+ os.environ['MODULEPATH'] = old_modulepath
+
+ return compilers
diff --git a/lib/spack/spack/operating_systems/linux_distro.py b/lib/spack/spack/operating_systems/linux_distro.py
new file mode 100644
index 0000000000..2e3c72719b
--- /dev/null
+++ b/lib/spack/spack/operating_systems/linux_distro.py
@@ -0,0 +1,22 @@
+import re
+import platform as py_platform
+from spack.architecture import OperatingSystem
+
+class LinuxDistro(OperatingSystem):
+ """ This class will represent the autodetected operating system
+ for a Linux System. Since there are many different flavors of
+ Linux, this class will attempt to encompass them all through
+ autodetection using the python module platform and the method
+ platform.dist()
+ """
+ def __init__(self):
+ distname, version, _ = py_platform.linux_distribution(
+ full_distribution_name=False)
+
+ # 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/operating_systems/mac_os.py b/lib/spack/spack/operating_systems/mac_os.py
new file mode 100644
index 0000000000..f35b3ca577
--- /dev/null
+++ b/lib/spack/spack/operating_systems/mac_os.py
@@ -0,0 +1,29 @@
+import platform as py_platform
+from spack.architecture import OperatingSystem
+
+class MacOs(OperatingSystem):
+ """This class represents the macOS operating system. This will be
+ auto detected using the python platform.mac_ver. The macOS
+ platform will be represented using the major version operating
+ system name, i.e el capitan, yosemite...etc.
+ """
+
+ def __init__(self):
+ """ Autodetects the mac version from a dictionary. Goes back as
+ far as 10.6 snowleopard. If the user has an older mac then
+ the version will just be a generic mac_os.
+ """
+ mac_releases = {'10.6': "snowleopard",
+ "10.7": "lion",
+ "10.8": "mountainlion",
+ "10.9": "mavericks",
+ "10.10": "yosemite",
+ "10.11": "elcapitan",
+ "10.12": "sierra"}
+
+ mac_ver = py_platform.mac_ver()[0][:-2]
+ name = mac_releases.get(mac_ver, "macos")
+ super(MacOs, self).__init__(name, mac_ver)
+
+ def __str__(self):
+ return self.name
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 2e7d8a7709..98fd51b262 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -398,13 +398,19 @@ class Package(object):
spack.repo.get(self.extendee_spec)._check_extendable()
@property
+ def global_license_dir(self):
+ """Returns the directory where global license files for all
+ packages are stored."""
+ spack_root = ancestor(__file__, 4)
+ return join_path(spack_root, 'etc', 'spack', 'licenses')
+
+ @property
def global_license_file(self):
- """Returns the path where a global license file should be stored."""
+ """Returns the path where a global license file for this
+ particular package should be stored."""
if not self.license_files:
return
- spack_root = ancestor(__file__, 4)
- global_license_dir = join_path(spack_root, 'etc', 'spack', 'licenses')
- return join_path(global_license_dir, self.name,
+ return join_path(self.global_license_dir, self.name,
os.path.basename(self.license_files[0]))
@property
@@ -676,11 +682,13 @@ class Package(object):
return self.spec.prefix
@property
+ #TODO: Change this to architecture
def compiler(self):
"""Get the spack.compiler.Compiler object used to build this package"""
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)
+ return spack.compilers.compiler_for_spec(self.spec.compiler,
+ self.spec.architecture)
def url_version(self, version):
"""
diff --git a/lib/spack/spack/platforms/__init__.py b/lib/spack/spack/platforms/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/spack/spack/platforms/__init__.py
diff --git a/lib/spack/spack/platforms/bgq.py b/lib/spack/spack/platforms/bgq.py
new file mode 100644
index 0000000000..e0eb76f336
--- /dev/null
+++ b/lib/spack/spack/platforms/bgq.py
@@ -0,0 +1,18 @@
+import os
+from spack.architecture import Platform, Target
+
+class Bgq(Platform):
+ priority = 30
+ front_end = 'power7'
+ back_end = 'powerpc'
+ default = 'powerpc'
+
+ def __init__(self):
+ super(Bgq, self).__init__('bgq')
+ self.add_target(self.front_end, Target(self.front_end))
+ self.add_target(self.back_end, Target(self.back_end,))
+
+ @classmethod
+ def detect(self):
+ return os.path.exists('/bgsys')
+
diff --git a/lib/spack/spack/platforms/cray_xc.py b/lib/spack/spack/platforms/cray_xc.py
new file mode 100644
index 0000000000..e710303e23
--- /dev/null
+++ b/lib/spack/spack/platforms/cray_xc.py
@@ -0,0 +1,46 @@
+import os
+from spack.architecture import Platform, Target
+from spack.operating_systems.linux_distro import LinuxDistro
+from spack.operating_systems.cnl import Cnl
+
+class CrayXc(Platform):
+ priority = 20
+ front_end = 'sandybridge'
+ back_end = 'ivybridge'
+ default = 'ivybridge'
+
+ front_os = "SuSE11"
+ back_os = "CNL10"
+ default_os = "CNL10"
+
+ def __init__(self):
+ ''' Since cori doesn't have ivybridge as a front end it's better
+ if we use CRAY_CPU_TARGET as the default. This will ensure
+ that if we're on a XC-40 or XC-30 then we can detect the target
+ '''
+ super(CrayXc, self).__init__('cray_xc')
+
+ # Handle the default here so we can check for a key error
+ if 'CRAY_CPU_TARGET' in os.environ:
+ self.default = os.environ['CRAY_CPU_TARGET']
+
+ # Change the defaults to haswell if we're on an XC40
+ if self.default == 'haswell':
+ self.front_end = self.default
+ self.back_end = self.default
+
+ # Could switch to use modules and fe targets for front end
+ # Currently using compilers by path for front end.
+ self.add_target('sandybridge', Target('sandybridge'))
+ self.add_target('ivybridge',
+ Target('ivybridge', 'craype-ivybridge'))
+ self.add_target('haswell',
+ Target('haswell','craype-haswell'))
+
+ self.add_operating_system('SuSE11', LinuxDistro())
+ self.add_operating_system('CNL10', Cnl())
+
+ @classmethod
+ def detect(self):
+ return os.path.exists('/opt/cray/craype')
+
diff --git a/lib/spack/spack/platforms/darwin.py b/lib/spack/spack/platforms/darwin.py
new file mode 100644
index 0000000000..d47dd640f9
--- /dev/null
+++ b/lib/spack/spack/platforms/darwin.py
@@ -0,0 +1,26 @@
+import subprocess
+from spack.architecture import Platform, Target
+from spack.operating_systems.mac_os import MacOs
+
+class Darwin(Platform):
+ priority = 89
+ front_end = 'x86_64'
+ back_end = 'x86_64'
+ default = 'x86_64'
+
+ def __init__(self):
+ super(Darwin, self).__init__('darwin')
+ self.add_target(self.default, Target(self.default))
+ mac_os = MacOs()
+
+ self.default_os = str(mac_os)
+ self.front_os = str(mac_os)
+ self.back_os = str(mac_os)
+
+ self.add_operating_system(str(mac_os), mac_os)
+
+ @classmethod
+ def detect(self):
+ platform = subprocess.Popen(['uname', '-a'], stdout = subprocess.PIPE)
+ platform, _ = platform.communicate()
+ return 'darwin' in platform.strip().lower()
diff --git a/lib/spack/spack/platforms/linux.py b/lib/spack/spack/platforms/linux.py
new file mode 100644
index 0000000000..4d8adac384
--- /dev/null
+++ b/lib/spack/spack/platforms/linux.py
@@ -0,0 +1,24 @@
+import subprocess
+from spack.architecture import Platform, Target
+from spack.operating_systems.linux_distro import LinuxDistro
+
+class Linux(Platform):
+ priority = 90
+ front_end = 'x86_64'
+ back_end = 'x86_64'
+ default = 'x86_64'
+
+ def __init__(self):
+ super(Linux, self).__init__('linux')
+ self.add_target(self.default, Target(self.default))
+ linux_dist = LinuxDistro()
+ self.default_os = str(linux_dist)
+ self.front_os = self.default_os
+ self.back_os = self.default_os
+ self.add_operating_system(str(linux_dist), linux_dist)
+
+ @classmethod
+ def detect(self):
+ platform = subprocess.Popen(['uname', '-a'], stdout = subprocess.PIPE)
+ platform, _ = platform.communicate()
+ return 'linux' in platform.strip().lower()
diff --git a/lib/spack/spack/platforms/test.py b/lib/spack/spack/platforms/test.py
new file mode 100644
index 0000000000..8fa2585a7a
--- /dev/null
+++ b/lib/spack/spack/platforms/test.py
@@ -0,0 +1,28 @@
+import subprocess
+from spack.architecture import Platform, Target
+from spack.operating_systems.linux_distro import LinuxDistro
+from spack.operating_systems.cnl import Cnl
+
+
+class Test(Platform):
+ priority = 1000000
+ front_end = 'x86_32'
+ back_end = 'x86_64'
+ default = 'x86_64'
+
+ back_os = 'CNL10'
+ default_os = 'CNL10'
+
+ def __init__(self):
+ super(Test, self).__init__('test')
+ self.add_target(self.default, Target(self.default))
+ self.add_target(self.front_end, Target(self.front_end))
+
+ self.add_operating_system(self.default_os, Cnl())
+ linux_dist = LinuxDistro()
+ self.front_os = linux_dist.name
+ self.add_operating_system(self.front_os, linux_dist)
+
+ @classmethod
+ def detect(self):
+ return True
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 16b61236a9..54219ec1b4 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1,4 +1,4 @@
-#
+##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
@@ -18,10 +18,10 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
"""
Spack allows very fine-grained control over how packages are installed and
over how they are built and configured. To make this easy, it has its own
@@ -96,8 +96,10 @@ specs to avoid ambiguity. Both are provided because ~ can cause shell
expansion when it is the first character in an id typed on the command line.
"""
import sys
+import itertools
import hashlib
import base64
+import imp
from StringIO import StringIO
from operator import attrgetter
import yaml
@@ -106,16 +108,22 @@ from yaml.error import MarkedYAMLError
import llnl.util.tty as tty
from llnl.util.lang import *
from llnl.util.tty.color import *
+from llnl.util.filesystem import join_path
import spack
+import spack.architecture
import spack.parse
import spack.error
import spack.compilers as compilers
+# TODO: move display_specs to some other location.
+from spack.cmd.find import display_specs
from spack.version import *
from spack.util.string import *
from spack.util.prefix import Prefix
+from spack.util.naming import mod_to_class
from spack.virtual import ProviderIndex
+from spack.build_environment import get_path_from_module, load_module
# Valid pattern for an identifier in Spack
identifier_re = r'\w[\w-]*'
@@ -165,7 +173,6 @@ def colorize_spec(spec):
"""Returns a spec colorized according to the colors specified in
color_formats."""
class insert_color:
-
def __init__(self):
self.last = None
@@ -183,11 +190,9 @@ def colorize_spec(spec):
@key_ordering
class CompilerSpec(object):
-
"""The CompilerSpec field represents the compiler or range of compiler
versions that a package should be built with. CompilerSpecs have a
name and a version list. """
-
def __init__(self, *args):
nargs = len(args)
if nargs == 1:
@@ -293,7 +298,6 @@ class VariantSpec(object):
on the particular package being built, and each named variant can
be enabled or disabled.
"""
-
def __init__(self, name, value):
self.name = name
self.value = value
@@ -488,7 +492,8 @@ class Spec(object):
self._concrete = kwargs.get('concrete', False)
# Allow a spec to be constructed with an external path.
- self.external = kwargs.get('external', None)
+ self.external = kwargs.get('external', None)
+ 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
@@ -520,8 +525,33 @@ class Spec(object):
Known flags currently include "arch"
"""
valid_flags = FlagMap.valid_compiler_flags()
- if name == 'arch':
- self._set_architecture(value)
+ if name == 'arch' or name == 'architecture':
+ parts = value.split('-')
+ if len(parts) == 3:
+ platform, op_sys, target = parts
+ else:
+ platform, op_sys, target = None, None, value
+
+ assert(self.architecture.platform is None)
+ assert(self.architecture.platform_os is None)
+ assert(self.architecture.target is None)
+ assert(self.architecture.os_string is None)
+ assert(self.architecture.target_string is None)
+ self._set_platform(platform)
+ self._set_os(op_sys)
+ self._set_target(target)
+ elif name == 'platform':
+ self._set_platform(value)
+ elif name == 'os' or name == 'operating_system':
+ if self.architecture.platform:
+ self._set_os(value)
+ else:
+ self.architecture.os_string = value
+ elif name == 'target':
+ if self.architecture.platform:
+ self._set_target(value)
+ else:
+ self.architecture.target_string = value
elif name in valid_flags:
assert(self.compiler_flags is not None)
self.compiler_flags[name] = value.split()
@@ -535,12 +565,49 @@ class Spec(object):
"Spec for '%s' cannot have two compilers." % self.name)
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_platform(self, value):
+ """Called by the parser to set the architecture platform"""
+ if isinstance(value, basestring):
+ mod_path = spack.platform_path
+ mod_string = 'spack.platformss'
+ names = list_modules(mod_path)
+ if value in names:
+ # Create a platform object from the name
+ mod_name = mod_string + value
+ path = join_path(mod_path, value) + '.py'
+ mod = imp.load_source(mod_name, path)
+ class_name = mod_to_class(value)
+ 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))
+ platform = cls()
+ else:
+ tty.die("No platform class %s defined." % value)
+ else:
+ # The value is a platform
+ platform = value
+
+ self.architecture.platform = platform
+
+ # Set os and target if we previously got strings for them
+ if self.architecture.os_string:
+ self._set_os(self.architecture.os_string)
+ self.architecture.os_string = None
+ if self.architecture.target_string:
+ self._set_target(self.architecture.target_string)
+ self.architecture.target_string = None
+
+ def _set_os(self, value):
+ """Called by the parser to set the architecture operating system"""
+ if self.architecture.platform:
+ self.architecture.platform_os = self.architecture.platform.operating_system(value)
+
+ def _set_target(self, value):
+ """Called by the parser to set the architecture target"""
+ if self.architecture.platform:
+ self.architecture.target = self.architecture.platform.target(value)
def _add_dependency(self, spec):
"""Called by the parser to add another spec as a dependency."""
@@ -612,15 +679,15 @@ class Spec(object):
if self._concrete:
return True
- self._concrete = bool(not self.virtual and
- self.namespace is not None and
- self.versions.concrete and
- self.variants.concrete and
- self.architecture and
- self.compiler and
- self.compiler.concrete and
- self.compiler_flags.concrete and
- self.dependencies.concrete)
+ self._concrete = bool(not self.virtual
+ and self.namespace is not None
+ and self.versions.concrete
+ and self.variants.concrete
+ and self.architecture
+ and self.architecture.concrete
+ and self.compiler and self.compiler.concrete
+ and self.compiler_flags.concrete
+ and self.dependencies.concrete)
return self._concrete
def traverse(self, visited=None, d=0, **kwargs):
@@ -658,7 +725,7 @@ class Spec(object):
in the traversal.
root [=True]
- If false, this won't yield the root node, just its descendents.
+ If False, this won't yield the root node, just its descendents.
direction [=children|parents]
If 'children', does a traversal of this spec's children. If
@@ -753,10 +820,10 @@ class Spec(object):
params.update(dict((name, value)
for name, value in self.compiler_flags.items()))
d = {
- 'parameters': params,
- 'arch': self.architecture,
- 'dependencies': dict((d, self.dependencies[d].dag_hash())
- for d in sorted(self.dependencies)),
+ 'parameters' : params,
+ 'arch' : self.architecture,
+ 'dependencies' : dict((d, self.dependencies[d].dag_hash())
+ for d in sorted(self.dependencies))
}
# Older concrete specs do not have a namespace. Omit for
@@ -764,6 +831,13 @@ class Spec(object):
if not self.concrete or self.namespace:
d['namespace'] = self.namespace
+ if self.architecture:
+ # TODO: Fix the target.to_dict to account for the tuple
+ # Want it to be a dict of dicts
+ d['arch'] = self.architecture.to_dict()
+ else:
+ d['arch'] = None
+
if self.compiler:
d.update(self.compiler.to_dict())
else:
@@ -789,11 +863,12 @@ class Spec(object):
spec = Spec(name)
spec.namespace = node.get('namespace', None)
spec.versions = VersionList.from_dict(node)
- spec.architecture = node['arch']
if 'hash' in node:
spec._hash = node['hash']
+ spec.architecture = spack.architecture.arch_from_dict(node['arch'])
+
if node['compiler'] is None:
spec.compiler = None
else:
@@ -866,12 +941,10 @@ class Spec(object):
# Concretize deps first -- this is a bottom-up process.
for name in sorted(self.dependencies.keys()):
- changed |= self.dependencies[
- name]._concretize_helper(presets, visited)
+ changed |= self.dependencies[name]._concretize_helper(presets, visited)
if self.name in presets:
changed |= self.constrain(presets[self.name])
-
else:
# Concretize virtual dependencies last. Because they're added
# to presets below, their constraints will all be merged, but we'll
@@ -936,11 +1009,12 @@ class Spec(object):
"""
# Make an index of stuff this spec already provides
self_index = ProviderIndex(self.traverse(), restrict=True)
-
changed = False
done = False
+
while not done:
done = True
+
for spec in list(self.traverse()):
replacement = None
if spec.virtual:
@@ -979,24 +1053,25 @@ class Spec(object):
continue
# If replacement is external then trim the dependencies
- if replacement.external:
+ if replacement.external or replacement.external_module:
if (spec.dependencies):
changed = True
spec.dependencies = DependencyMap()
replacement.dependencies = DependencyMap()
+ replacement.architecture = self.architecture
# TODO: could this and the stuff in _dup be cleaned up?
def feq(cfield, sfield):
return (not cfield) or (cfield == sfield)
- if replacement is spec or (
- feq(replacement.name, spec.name) and
- feq(replacement.versions, spec.versions) and
- feq(replacement.compiler, spec.compiler) and
- feq(replacement.architecture, spec.architecture) and
- feq(replacement.dependencies, spec.dependencies) and
- feq(replacement.variants, spec.variants) and
- feq(replacement.external, spec.external)):
+ if replacement is spec or (feq(replacement.name, spec.name) and
+ feq(replacement.versions, spec.versions) and
+ feq(replacement.compiler, spec.compiler) and
+ feq(replacement.architecture, spec.architecture) and
+ feq(replacement.dependencies, spec.dependencies) and
+ feq(replacement.variants, spec.variants) and
+ feq(replacement.external, spec.external) and
+ feq(replacement.external_module, spec.external_module)):
continue
# Refine this spec to the candidate. This uses
# replace_with AND dup so that it can work in
@@ -1053,6 +1128,15 @@ class Spec(object):
if s.namespace is None:
s.namespace = spack.repo.repo_for_pkg(s.name).namespace
+
+ for s in self.traverse(root=False):
+ if s.external_module:
+ compiler = spack.compilers.compiler_for_spec(s.compiler, s.architecture)
+ for mod in compiler.modules:
+ load_module(mod)
+
+ s.external = get_path_from_module(s.external_module)
+
# Mark everything in the spec as concrete, as well.
self._mark_concrete()
@@ -1253,7 +1337,7 @@ class Spec(object):
# if we descend into a virtual spec, there's nothing more
# to normalize. Concretize will finish resolving it later.
- if self.virtual or self.external:
+ if self.virtual or self.external or self.external_module:
return False
# Combine constraints from package deps with constraints from
@@ -1300,7 +1384,6 @@ class Spec(object):
# Ensure first that all packages & compilers in the DAG exist.
self.validate_names()
-
# Get all the dependencies into one DependencyMap
spec_deps = self.flat_dependencies(copy=False)
@@ -1378,10 +1461,21 @@ class Spec(object):
raise UnsatisfiableVariantSpecError(self.variants[v],
other.variants[v])
+ # 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:
@@ -1395,9 +1489,17 @@ class Spec(object):
changed |= self.compiler_flags.constrain(other.compiler_flags)
- old = self.architecture
- self.architecture = self.architecture or other.architecture
- changed |= (self.architecture != old)
+ old = str(self.architecture)
+ if self.architecture is None or other.architecture is None:
+ self.architecture = self.architecture or other.architecture
+ else:
+ if self.architecture.platform is None or other.architecture.platform is None:
+ self.architecture.platform = self.architecture.platform or other.architecture.platform
+ if self.architecture.platform_os is None or other.architecture.platform_os is None:
+ self.architecture.platform_os = self.architecture.platform_os or other.architecture.platform_os
+ if self.architecture.target is None or other.architecture.target is None:
+ self.architecture.target = self.architecture.target or other.architecture.target
+ changed |= (str(self.architecture) != old)
if deps:
changed |= self._constrain_dependencies(other)
@@ -1524,9 +1626,14 @@ class Spec(object):
# Architecture satisfaction is currently just string equality.
# If not strict, None means unconstrained.
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(
@@ -1601,20 +1708,17 @@ class Spec(object):
Options:
dependencies[=True]
- Whether deps should be copied too. Set to false to copy a
+ Whether deps should be copied too. Set to False to copy a
spec but not its dependencies.
"""
# We don't count dependencies as changes here
changed = True
if hasattr(self, 'name'):
- changed = (self.name != other.name and
- self.versions != other.versions and
- 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)
+ changed = (self.name != other.name and self.versions != other.versions and \
+ 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 and self.compiler_flags != other.compiler_flags)
# Local node attributes get copied first.
self.name = other.name
@@ -1628,6 +1732,7 @@ 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
self._hash = other._hash
@@ -1648,6 +1753,7 @@ class Spec(object):
self._normal = other._normal
self._concrete = other._concrete
self.external = other.external
+ self.external_module = other.external_module
return changed
def copy(self, **kwargs):
@@ -1752,6 +1858,7 @@ class Spec(object):
self.compiler,
self.compiler_flags)
+
def eq_node(self, other):
"""Equality with another spec, not including dependencies."""
return self._cmp_node() == other._cmp_node()
@@ -1862,7 +1969,7 @@ class Spec(object):
if self.variants:
write(fmt % str(self.variants), c)
elif c == '=':
- if self.architecture:
+ if self.architecture and str(self.architecture):
write(fmt % (' arch' + c + str(self.architecture)), c)
elif c == '#':
out.write('-' + fmt % (self.dag_hash(7)))
@@ -1920,8 +2027,8 @@ class Spec(object):
if self.variants:
write(fmt % str(self.variants), '+')
elif named_str == 'ARCHITECTURE':
- if self.architecture:
- write(fmt % str(self.architecture), '=')
+ if self.architecture and str(self.architecture):
+ write(fmt % str(self.architecture), ' arch=')
elif named_str == 'SHA1':
if self.dependencies:
out.write(fmt % str(self.dag_hash(7)))
@@ -1946,6 +2053,41 @@ class Spec(object):
def dep_string(self):
return ''.join("^" + dep.format() for dep in self.sorted_deps())
+
+ def __cmp__(self, other):
+ #Package name sort order is not configurable, always goes alphabetical
+ if self.name != other.name:
+ return cmp(self.name, other.name)
+
+ #Package version is second in compare order
+ pkgname = self.name
+ if self.versions != other.versions:
+ return spack.pkgsort.version_compare(pkgname,
+ self.versions, other.versions)
+
+ #Compiler is third
+ if self.compiler != other.compiler:
+ return spack.pkgsort.compiler_compare(pkgname,
+ self.compiler, other.compiler)
+
+ #Variants
+ if self.variants != other.variants:
+ return spack.pkgsort.variant_compare(pkgname,
+ self.variants, other.variants)
+
+ #Target
+ if self.architecture != other.architecture:
+ return spack.pkgsort.architecture_compare(pkgname,
+ self.architecture, other.architecture)
+
+ #Dependency is not configurable
+ if self.dependencies != other.dependencies:
+ return -1 if self.dependencies < other.dependencies else 1
+
+ #Equal specs
+ return 0
+
+
def __str__(self):
return self.format() + self.dep_string()
@@ -2026,7 +2168,6 @@ class SpecParser(spack.parse.Parser):
def do_parse(self):
specs = []
-
try:
while self.next:
# TODO: clean this parsing up a bit
@@ -2070,6 +2211,12 @@ class SpecParser(spack.parse.Parser):
except spack.parse.ParseError, e:
raise SpecParseError(e)
+
+ # If the spec has an os or a target and no platform, give it the default platform
+ for spec in specs:
+ for s in spec.traverse():
+ if s.architecture.os_string or s.architecture.target_string:
+ s._set_platform(spack.architecture.sys_type())
return specs
def parse_compiler(self, text):
@@ -2111,9 +2258,10 @@ 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
+ spec.external_module = None
spec.compiler_flags = FlagMap(spec)
spec.dependents = DependencyMap()
spec.dependencies = DependencyMap()
@@ -2189,12 +2337,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
diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py
index 891dc873fd..97f142e746 100644
--- a/lib/spack/spack/test/__init__.py
+++ b/lib/spack/spack/test/__init__.py
@@ -31,7 +31,8 @@ from llnl.util.filesystem import join_path
from llnl.util.tty.colify import colify
from spack.test.tally_plugin import Tally
"""Names of tests to be included in Spack's test suite"""
-test_names = ['versions', 'url_parse', 'url_substitution', 'packages', 'stage',
+
+test_names = ['architecture', 'versions', 'url_parse', 'url_substitution', 'packages', 'stage',
'spec_syntax', 'spec_semantics', 'spec_dag', 'concretize',
'multimethod', 'install', 'package_sanity', 'config',
'directory_layout', 'pattern', 'python_version', 'git_fetch',
diff --git a/lib/spack/spack/test/architecture.py b/lib/spack/spack/test/architecture.py
new file mode 100644
index 0000000000..a6847c5744
--- /dev/null
+++ b/lib/spack/spack/test/architecture.py
@@ -0,0 +1,112 @@
+""" Test checks if the architecture class is created correctly and also that
+ the functions are looking for the correct architecture name
+"""
+import unittest
+import os
+import platform as py_platform
+import spack
+from spack.architecture import *
+from spack.spec import *
+from spack.platforms.cray_xc import CrayXc
+from spack.platforms.linux import Linux
+from spack.platforms.bgq import Bgq
+from spack.platforms.darwin import Darwin
+
+from spack.test.mock_packages_test import *
+
+#class ArchitectureTest(unittest.TestCase):
+class ArchitectureTest(MockPackagesTest):
+
+ def setUp(self):
+ super(ArchitectureTest, self).setUp()
+ self.platform = sys_type()
+
+ def tearDown(self):
+ super(ArchitectureTest, self).tearDown()
+
+ def test_dict_functions_for_architecture(self):
+ arch = Arch()
+ arch.platform = spack.architecture.sys_type()
+ arch.platform_os = arch.platform.operating_system('default_os')
+ arch.target = arch.platform.target('default_target')
+
+ d = arch.to_dict()
+
+ new_arch = spack.architecture.arch_from_dict(d)
+
+ self.assertEqual(arch, new_arch)
+
+ self.assertTrue( isinstance(arch, Arch) )
+ self.assertTrue( isinstance(arch.platform, Platform) )
+ self.assertTrue( isinstance(arch.platform_os, OperatingSystem) )
+ self.assertTrue( isinstance(arch.target, Target) )
+ self.assertTrue( isinstance(new_arch, Arch) )
+ self.assertTrue( isinstance(new_arch.platform, Platform) )
+ self.assertTrue( isinstance(new_arch.platform_os, OperatingSystem) )
+ self.assertTrue( isinstance(new_arch.target, Target) )
+
+
+ def test_sys_type(self):
+ output_platform_class = sys_type()
+ my_arch_class = None
+ if os.path.exists('/opt/cray/craype'):
+ my_platform_class = CrayXc()
+ elif os.path.exists('/bgsys'):
+ my_platform_class = Bgq()
+ elif 'Linux' in py_platform.system():
+ my_platform_class = Linux()
+ elif 'Darwin' in py_platform.system():
+ my_platform_class = Darwin()
+
+ self.assertEqual(str(output_platform_class), str(my_platform_class))
+
+ def test_user_front_end_input(self):
+ """Test when user inputs just frontend that both the frontend target
+ and frontend operating system match
+ """
+ frontend_os = self.platform.operating_system("frontend")
+ frontend_target = self.platform.target("frontend")
+ frontend_spec = Spec("libelf os=frontend target=frontend")
+ frontend_spec.concretize()
+ self.assertEqual(frontend_os, frontend_spec.architecture.platform_os)
+ self.assertEqual(frontend_target, frontend_spec.architecture.target)
+
+ def test_user_back_end_input(self):
+ """Test when user inputs backend that both the backend target and
+ backend operating system match
+ """
+ backend_os = self.platform.operating_system("backend")
+ backend_target = self.platform.target("backend")
+ backend_spec = Spec("libelf os=backend target=backend")
+ backend_spec.concretize()
+ self.assertEqual(backend_os, backend_spec.architecture.platform_os)
+ self.assertEqual(backend_target, backend_spec.architecture.target)
+
+ def test_user_defaults(self):
+ default_os = self.platform.operating_system("default_os")
+ default_target = self.platform.target("default_target")
+
+ default_spec = Spec("libelf") # default is no args
+ default_spec.concretize()
+ self.assertEqual(default_os, default_spec.architecture.platform_os)
+ self.assertEqual(default_target, default_spec.architecture.target)
+
+ def test_user_input_combination(self):
+ os_list = self.platform.operating_sys.keys()
+ target_list = self.platform.targets.keys()
+ additional = ["fe", "be", "frontend", "backend"]
+
+ os_list.extend(additional)
+ target_list.extend(additional)
+
+ combinations = itertools.product(os_list, target_list)
+ results = []
+ for arch in combinations:
+ o,t = arch
+ spec = Spec("libelf os=%s target=%s" % (o, t))
+ spec.concretize()
+ results.append(spec.architecture.platform_os == self.platform.operating_system(o))
+ results.append(spec.architecture.target == self.platform.target(t))
+ res = all(results)
+
+ self.assertTrue(res)
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 963481054e..ab201f406a 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
@@ -253,6 +254,19 @@ class ConcretizeTest(MockPackagesTest):
self.assertTrue(spec['externaltool'].compiler.satisfies('gcc'))
+ def test_external_package_module(self):
+ # No tcl modules on darwin/linux machines
+ # TODO: improved way to check for this.
+ if (spack.architecture.sys_type().name == 'darwin' or
+ spack.architecture.sys_type().name == 'linux'):
+ return
+
+ spec = Spec('externalmodule')
+ spec.concretize()
+ self.assertEqual(spec['externalmodule'].external_module, 'external-module')
+ self.assertFalse('externalprereq' in spec)
+ self.assertTrue(spec['externalmodule'].compiler.satisfies('gcc'))
+
def test_nobuild_package(self):
got_error = False
spec = Spec('externaltool%clang')
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index eff482f4c6..252d77e66b 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -32,45 +32,75 @@ from ordereddict_backport import OrderedDict
from spack.test.mock_packages_test import *
# Some sample compiler config data
-a_comps = {
- "x86_64_E5v2_IntelIB": {
- "gcc@4.7.3" : {
+a_comps = [
+ {'compiler': {
+ 'paths': {
"cc" : "/gcc473",
"cxx": "/g++473",
"f77": None,
- "fc" : None },
- "gcc@4.5.0" : {
+ "fc" : None
+ },
+ 'modules': None,
+ 'spec': 'gcc@4.7.3',
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
+ 'paths': {
"cc" : "/gcc450",
"cxx": "/g++450",
- "f77": "/gfortran",
- "fc" : "/gfortran" },
- "clang@3.3" : {
+ "f77": 'gfortran',
+ "fc" : 'gfortran'
+ },
+ 'modules': None,
+ 'spec': 'gcc@4.5.0',
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
+ 'paths': {
"cc" : "<overwritten>",
"cxx": "<overwritten>",
- "f77": "<overwritten>",
- "fc" : "<overwritten>" }
- }
-}
-
-b_comps = {
- "x86_64_E5v3": {
- "icc@10.0" : {
+ "f77": '<overwritten>',
+ "fc" : '<overwritten>' },
+ 'modules': None,
+ 'spec': 'clang@3.3',
+ 'operating_system': 'CNL10'
+ }}
+]
+
+b_comps = [
+ {'compiler': {
+ 'paths': {
"cc" : "/icc100",
- "cxx": "/icc100",
+ "cxx": "/icp100",
"f77": None,
- "fc" : None },
- "icc@11.1" : {
+ "fc" : None
+ },
+ 'modules': None,
+ 'spec': 'icc@10.0',
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
+ 'paths': {
"cc" : "/icc111",
"cxx": "/icp111",
- "f77": "/ifort",
- "fc" : "/ifort" },
- "clang@3.3" : {
- "cc" : "/clang",
- "cxx": "/clang++",
- "f77": None,
- "fc" : None}
- }
-}
+ "f77": 'ifort',
+ "fc" : 'ifort'
+ },
+ 'modules': None,
+ 'spec': 'icc@11.1',
+ 'operating_system': 'CNL10'
+ }},
+ {'compiler': {
+ 'paths': {
+ "cc" : "<overwritten>",
+ "cxx": "<overwritten>",
+ "f77": '<overwritten>',
+ "fc" : '<overwritten>' },
+ 'modules': None,
+ 'spec': 'clang@3.3',
+ 'operating_system': 'CNL10'
+ }}
+]
# Some Sample repo data
repos_low = [ "/some/path" ]
@@ -89,15 +119,28 @@ class ConfigTest(MockPackagesTest):
super(ConfigTest, self).tearDown()
shutil.rmtree(self.tmp_dir, True)
- def check_config(self, comps, arch, *compiler_names):
+
+ def check_config(self, comps, *compiler_names):
"""Check that named compilers in comps match Spack's config."""
config = spack.config.get_config('compilers')
compiler_list = ['cc', 'cxx', 'f77', 'fc']
- for key in compiler_names:
- for c in compiler_list:
- expected = comps[arch][key][c]
- actual = config[arch][key][c]
- self.assertEqual(expected, actual)
+ param_list = ['modules', 'paths', 'spec', 'operating_system']
+ 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:
+ self.assertEqual(conf[p], comp[p])
+ for c in compiler_list:
+ expected = comp['paths'][c]
+ actual = conf['paths'][c]
+ self.assertEqual(expected, actual)
def test_write_list_in_memory(self):
spack.config.update_config('repos', repos_low, 'test_low_priority')
@@ -111,8 +154,9 @@ class ConfigTest(MockPackagesTest):
spack.config.update_config('compilers', b_comps, 'test_high_priority')
# Make sure the config looks how we expect.
- self.check_config(a_comps, 'x86_64_E5v2_IntelIB', 'gcc@4.7.3', 'gcc@4.5.0')
- self.check_config(b_comps, 'x86_64_E5v3', 'icc@10.0', 'icc@11.1', 'clang@3.3')
+ self.check_config(a_comps, 'gcc@4.7.3', 'gcc@4.5.0')
+ self.check_config(b_comps, 'icc@10.0', 'icc@11.1', 'clang@3.3')
+
def test_write_key_to_disk(self):
# Write b_comps "on top of" a_comps.
@@ -123,8 +167,8 @@ class ConfigTest(MockPackagesTest):
spack.config.clear_config_caches()
# Same check again, to ensure consistency.
- self.check_config(a_comps, 'x86_64_E5v2_IntelIB', 'gcc@4.7.3', 'gcc@4.5.0')
- self.check_config(b_comps, 'x86_64_E5v3', 'icc@10.0', 'icc@11.1', 'clang@3.3')
+ self.check_config(a_comps, 'gcc@4.7.3', 'gcc@4.5.0')
+ self.check_config(b_comps, 'icc@10.0', 'icc@11.1', 'clang@3.3')
def test_write_to_same_priority_file(self):
# Write b_comps in the same file as a_comps.
@@ -135,5 +179,5 @@ class ConfigTest(MockPackagesTest):
spack.config.clear_config_caches()
# Same check again, to ensure consistency.
- self.check_config(a_comps, 'x86_64_E5v2_IntelIB', 'gcc@4.7.3', 'gcc@4.5.0')
- self.check_config(b_comps, 'x86_64_E5v3', 'icc@10.0', 'icc@11.1', 'clang@3.3')
+ self.check_config(a_comps, 'gcc@4.7.3', 'gcc@4.5.0')
+ self.check_config(b_comps, 'icc@10.0', 'icc@11.1', 'clang@3.3')
diff --git a/lib/spack/spack/test/environment.py b/lib/spack/spack/test/environment.py
index 219c68e5a8..f3644cb0b7 100644
--- a/lib/spack/spack/test/environment.py
+++ b/lib/spack/spack/test/environment.py
@@ -35,12 +35,14 @@ from spack.environment import RemovePath, PrependPath, AppendPath
class EnvironmentTest(unittest.TestCase):
def setUp(self):
- os.environ.clear()
os.environ['UNSET_ME'] = 'foo'
os.environ['EMPTY_PATH_LIST'] = ''
os.environ['PATH_LIST'] = '/path/second:/path/third'
os.environ['REMOVE_PATH_LIST'] = '/a/b:/duplicate:/a/c:/remove/this:/a/d:/duplicate/:/f/g' # NOQA: ignore=E501
+ def tearDown(self):
+ pass
+
def test_set(self):
env = EnvironmentModifications()
env.set('A', 'dummy value')
diff --git a/lib/spack/spack/test/mock_packages_test.py b/lib/spack/spack/test/mock_packages_test.py
index 595667bf35..a56bd8ebdc 100644
--- a/lib/spack/spack/test/mock_packages_test.py
+++ b/lib/spack/spack/test/mock_packages_test.py
@@ -34,20 +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:
- all:
- clang@3.3:
+- compiler:
+ spec: clang@3.3
+ operating_system: {0}{1}
+ paths:
cc: /path/to/clang
cxx: /path/to/clang++
f77: None
fc: None
- gcc@4.5.0:
+ 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: CNL10
+ paths:
+ cc: /path/to/clang
+ cxx: /path/to/clang++
+ f77: None
+ fc: None
+ modules: 'None'
+- compiler:
+ spec: clang@3.3
+ operating_system: SuSE11
+ paths:
+ cc: /path/to/clang
+ cxx: /path/to/clang++
+ f77: None
+ fc: None
+ modules: 'None'
+- compiler:
+ spec: clang@3.3
+ operating_system: redhat6
+ paths:
+ cc: /path/to/clang
+ cxx: /path/to/clang++
+ f77: None
+ fc: None
+ modules: 'None'
+- compiler:
+ spec: clang@3.3
+ operating_system: yosemite
+ paths:
+ cc: /path/to/clang
+ cxx: /path/to/clang++
+ f77: None
+ fc: None
+ modules: 'None'
+- compiler:
+ paths:
cc: /path/to/gcc
cxx: /path/to/g++
f77: /path/to/gfortran
fc: /path/to/gfortran
-"""
+ operating_system: CNL10
+ 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: SuSE11
+ 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: redhat6
+ 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: 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:
@@ -60,6 +167,10 @@ packages:
paths:
externalvirtual@2.0%clang@3.3: /path/to/external_virtual_clang
externalvirtual@1.0%gcc@4.5.0: /path/to/external_virtual_gcc
+ externalmodule:
+ buildable: False
+ modules:
+ externalmodule@1.0%gcc@4.5.0: external-module
"""
class MockPackagesTest(unittest.TestCase):
diff --git a/lib/spack/spack/test/modules.py b/lib/spack/spack/test/modules.py
index c73badf8f2..582e067860 100644
--- a/lib/spack/spack/test/modules.py
+++ b/lib/spack/spack/test/modules.py
@@ -73,7 +73,7 @@ configuration_alter_environment = {
'all': {
'filter': {'environment_blacklist': ['CMAKE_PREFIX_PATH']}
},
- 'arch=x86-linux': {
+ 'platform=test target=x86_64': {
'environment': {'set': {'FOO': 'foo'},
'unset': ['BAR']}
}
@@ -116,6 +116,7 @@ class TclTests(MockPackagesTest):
def get_modulefile_content(self, spec):
spec.concretize()
+ print spec, '&&&&&'
generator = spack.modules.TclModule(spec)
generator.write()
content = FILE_REGISTRY[generator.file_name].split('\n')
@@ -123,27 +124,28 @@ class TclTests(MockPackagesTest):
def test_simple_case(self):
spack.modules.CONFIGURATION = configuration_autoload_direct
- spec = spack.spec.Spec('mpich@3.0.4 arch=x86-linux')
+ spec = spack.spec.Spec('mpich@3.0.4')
content = self.get_modulefile_content(spec)
self.assertTrue('module-whatis "mpich @3.0.4"' in content)
def test_autoload(self):
spack.modules.CONFIGURATION = configuration_autoload_direct
- spec = spack.spec.Spec('mpileaks arch=x86-linux')
+ spec = spack.spec.Spec('mpileaks')
content = self.get_modulefile_content(spec)
self.assertEqual(len([x for x in content if 'is-loaded' in x]), 2)
self.assertEqual(len([x for x in content if 'module load ' in x]), 2)
spack.modules.CONFIGURATION = configuration_autoload_all
- spec = spack.spec.Spec('mpileaks arch=x86-linux')
+ spec = spack.spec.Spec('mpileaks')
content = self.get_modulefile_content(spec)
self.assertEqual(len([x for x in content if 'is-loaded' in x]), 5)
self.assertEqual(len([x for x in content if 'module load ' in x]), 5)
def test_alter_environment(self):
spack.modules.CONFIGURATION = configuration_alter_environment
- spec = spack.spec.Spec('mpileaks arch=x86-linux')
+ spec = spack.spec.Spec('mpileaks platform=test target=x86_64')
content = self.get_modulefile_content(spec)
+ print content
self.assertEqual(
len([x
for x in content
@@ -152,8 +154,9 @@ class TclTests(MockPackagesTest):
len([x for x in content if 'setenv FOO "foo"' in x]), 1)
self.assertEqual(len([x for x in content if 'unsetenv BAR' in x]), 1)
- spec = spack.spec.Spec('libdwarf arch=x64-linux')
+ spec = spack.spec.Spec('libdwarf %clang platform=test target=x86_32')
content = self.get_modulefile_content(spec)
+ print content
self.assertEqual(
len([x
for x in content
@@ -164,14 +167,14 @@ class TclTests(MockPackagesTest):
def test_blacklist(self):
spack.modules.CONFIGURATION = configuration_blacklist
- spec = spack.spec.Spec('mpileaks arch=x86-linux')
+ spec = spack.spec.Spec('mpileaks')
content = self.get_modulefile_content(spec)
self.assertEqual(len([x for x in content if 'is-loaded' in x]), 1)
self.assertEqual(len([x for x in content if 'module load ' in x]), 1)
def test_conflicts(self):
spack.modules.CONFIGURATION = configuration_conflicts
- spec = spack.spec.Spec('mpileaks arch=x86-linux')
+ spec = spack.spec.Spec('mpileaks')
content = self.get_modulefile_content(spec)
self.assertEqual(
len([x for x in content if x.startswith('conflict')]), 2)
diff --git a/lib/spack/spack/test/multimethod.py b/lib/spack/spack/test/multimethod.py
index a33656adcc..034e6b3923 100644
--- a/lib/spack/spack/test/multimethod.py
+++ b/lib/spack/spack/test/multimethod.py
@@ -92,21 +92,18 @@ class MultiMethodTest(MockPackagesTest):
self.assertEqual(pkg.has_a_default(), 'default')
- def test_architecture_match(self):
- pkg = spack.repo.get('multimethod arch=x86_64')
- self.assertEqual(pkg.different_by_architecture(), 'x86_64')
-
- pkg = spack.repo.get('multimethod arch=ppc64')
- self.assertEqual(pkg.different_by_architecture(), 'ppc64')
-
- pkg = spack.repo.get('multimethod arch=ppc32')
- self.assertEqual(pkg.different_by_architecture(), 'ppc32')
-
- pkg = spack.repo.get('multimethod arch=arm64')
- self.assertEqual(pkg.different_by_architecture(), 'arm64')
-
- pkg = spack.repo.get('multimethod arch=macos')
- self.assertRaises(NoSuchMethodError, pkg.different_by_architecture)
+ def test_target_match(self):
+ platform = spack.architecture.sys_type()
+ targets = platform.targets.values()
+ for target in targets[:-1]:
+ pkg = spack.repo.get('multimethod target='+target.name)
+ self.assertEqual(pkg.different_by_target(), target.name)
+
+ pkg = spack.repo.get('multimethod target='+targets[-1].name)
+ if len(targets) == 1:
+ self.assertEqual(pkg.different_by_target(), targets[-1].name)
+ else:
+ self.assertRaises(NoSuchMethodError, pkg.different_by_target)
def test_dependency_match(self):
diff --git a/lib/spack/spack/test/operating_system.py b/lib/spack/spack/test/operating_system.py
new file mode 100644
index 0000000000..ed5f6ff8ad
--- /dev/null
+++ b/lib/spack/spack/test/operating_system.py
@@ -0,0 +1,55 @@
+""" Test checks if the operating_system class is created correctly and that
+the functions are using the correct operating_system. Also checks whether
+the operating_system correctly uses the compiler_strategy
+"""
+
+import unittest
+import os
+import platform
+from spack.platforms.cray_xc import CrayXc
+from spack.platforms.linux import Linux
+from spack.platforms.darwin import Darwin
+from spack.operating_system.linux_distro import LinuxDistro
+from spack.operating_system.mac_os import MacOs
+from spack.operating_system.cnl import ComputeNodeLinux
+
+class TestOperatingSystem(unittest.TestCase):
+
+ def setUp(self):
+ cray_xc = CrayXc()
+ linux = Linux()
+ darwin = Darwin()
+ self.cray_operating_sys = cray_xc.operating_system('front_os')
+ self.cray_default_os = cray_xc.operating_system('default_os')
+ self.cray_back_os = cray_xc.operating_system('back_os')
+ self.darwin_operating_sys = darwin.operating_system('default_os')
+ self.linux_operating_sys = linux.operating_system('default_os')
+
+ def test_cray_front_end_operating_system(self):
+ self.assertIsInstance(self.cray_operating_sys, LinuxDistro)
+
+ def test_cray_front_end_compiler_strategy(self):
+ self.assertEquals(self.cray_operating_sys.compiler_strategy, "PATH")
+
+ def test_cray_back_end_operating_system(self):
+ self.assertIsInstance(self.cray_back_os,ComputeNodeLinux)
+
+ def test_cray_back_end_compiler_strategy(self):
+ self.assertEquals(self.cray_back_os.compiler_strategy, "MODULES")
+
+ def test_linux_operating_system(self):
+ self.assertIsInstance(self.linux_operating_sys, LinuxDistro)
+
+ def test_linux_compiler_strategy(self):
+ self.assertEquals(self.linux_operating_sys.compiler_strategy, "PATH")
+
+
+ def test_cray_front_end_compiler_list(self):
+ """ Operating systems will now be in charge of finding compilers.
+ So, depending on which operating system you want to build for
+ or which operating system you are on, then you could detect
+ compilers in a certain way. Cray linux environment on the front
+ end is just a regular linux distro whereas the Cray linux compute
+ node is a stripped down version which modules are important
+ """
+ self.assertEquals(True, False)
diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py
index 52f4f7395e..712f07ac4d 100644
--- a/lib/spack/spack/test/spec_dag.py
+++ b/lib/spack/spack/test/spec_dag.py
@@ -29,6 +29,7 @@ You can find the dummy packages here::
spack/lib/spack/spack/test/mock_packages
"""
import spack
+import spack.architecture
import spack.package
from llnl.util.lang import list_modules
@@ -241,8 +242,10 @@ class SpecDagTest(MockPackagesTest):
def test_unsatisfiable_architecture(self):
- self.set_pkg_dep('mpileaks', 'mpich arch=bgqos_0')
- spec = Spec('mpileaks ^mpich arch=sles_10_ppc64 ^callpath ^dyninst ^libelf ^libdwarf')
+ platform = spack.architecture.sys_type()
+
+ self.set_pkg_dep('mpileaks', 'mpich platform=test target=be')
+ spec = Spec('mpileaks ^mpich platform=test target=fe ^callpath ^dyninst ^libelf ^libdwarf')
self.assertRaises(spack.spec.UnsatisfiableArchitectureSpecError, spec.normalize)
diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py
index 0cb78b90ed..9876bfd5a8 100644
--- a/lib/spack/spack/test/spec_semantics.py
+++ b/lib/spack/spack/test/spec_semantics.py
@@ -23,6 +23,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import unittest
+import spack.architecture
from spack.spec import *
from spack.test.mock_packages_test import *
@@ -107,7 +108,8 @@ class SpecSematicsTest(MockPackagesTest):
def test_satisfies_namespaced_dep(self):
- """Ensure spec from same or unspecified namespace satisfies namespace constraint."""
+ """Ensure spec from same or unspecified namespace satisfies namespace
+ constraint."""
self.check_satisfies('mpileaks ^builtin.mock.mpich', '^mpich')
self.check_satisfies('mpileaks ^builtin.mock.mpich', '^mpi')
@@ -139,11 +141,16 @@ class SpecSematicsTest(MockPackagesTest):
def test_satisfies_architecture(self):
- self.check_satisfies('foo arch=chaos_5_x86_64_ib', ' arch=chaos_5_x86_64_ib')
- self.check_satisfies('foo arch=bgqos_0', ' arch=bgqos_0')
-
- self.check_unsatisfiable('foo arch=bgqos_0', ' arch=chaos_5_x86_64_ib')
- self.check_unsatisfiable('foo arch=chaos_5_x86_64_ib', ' arch=bgqos_0')
+ platform = spack.architecture.sys_type()
+ self.check_satisfies(
+ 'foo platform=test target=frontend os=frontend',
+ 'platform=test target=frontend os=frontend')
+ self.check_satisfies(
+ 'foo platform=test target=backend os=backend',
+ 'platform=test target=backend', 'platform=test os=backend')
+ self.check_satisfies(
+ 'foo platform=test target=default_target os=default_os',
+ 'platform=test target=default_target os=default_os')
def test_satisfies_dependencies(self):
@@ -158,10 +165,14 @@ class SpecSematicsTest(MockPackagesTest):
self.check_satisfies('mpileaks^mpich@2.0', '^mpich@1:3')
self.check_unsatisfiable('mpileaks^mpich@1.2', '^mpich@2.0')
- self.check_satisfies('mpileaks^mpich@2.0^callpath@1.5', '^mpich@1:3^callpath@1.4:1.6')
- self.check_unsatisfiable('mpileaks^mpich@4.0^callpath@1.5', '^mpich@1:3^callpath@1.4:1.6')
- self.check_unsatisfiable('mpileaks^mpich@2.0^callpath@1.7', '^mpich@1:3^callpath@1.4:1.6')
- self.check_unsatisfiable('mpileaks^mpich@4.0^callpath@1.7', '^mpich@1:3^callpath@1.4:1.6')
+ self.check_satisfies(
+ 'mpileaks^mpich@2.0^callpath@1.5', '^mpich@1:3^callpath@1.4:1.6')
+ self.check_unsatisfiable(
+ 'mpileaks^mpich@4.0^callpath@1.5', '^mpich@1:3^callpath@1.4:1.6')
+ self.check_unsatisfiable(
+ 'mpileaks^mpich@2.0^callpath@1.7', '^mpich@1:3^callpath@1.4:1.6')
+ self.check_unsatisfiable(
+ 'mpileaks^mpich@4.0^callpath@1.7', '^mpich@1:3^callpath@1.4:1.6')
def test_satisfies_virtual_dependencies(self):
@@ -350,10 +361,13 @@ class SpecSematicsTest(MockPackagesTest):
self.check_constrain('libelf cflags="-O3" cppflags="-Wall"', 'libelf cflags="-O3"', 'libelf cflags="-O3" cppflags="-Wall"')
- def test_constrain_arch(self):
- self.check_constrain('libelf arch=bgqos_0', 'libelf arch=bgqos_0', 'libelf arch=bgqos_0')
- self.check_constrain('libelf arch=bgqos_0', 'libelf', 'libelf arch=bgqos_0')
-
+ def test_constrain_architecture(self):
+ self.check_constrain('libelf target=default_target os=default_os',
+ 'libelf target=default_target os=default_os',
+ 'libelf target=default_target os=default_os')
+ self.check_constrain('libelf target=default_target os=default_os',
+ 'libelf',
+ 'libelf target=default_target os=default_os')
def test_constrain_compiler(self):
self.check_constrain('libelf %gcc@4.4.7', 'libelf %gcc@4.4.7', 'libelf %gcc@4.4.7')
@@ -369,9 +383,8 @@ class SpecSematicsTest(MockPackagesTest):
self.check_invalid_constraint('libelf debug=2', 'libelf debug=1')
self.check_invalid_constraint('libelf cppflags="-O3"', 'libelf cppflags="-O2"')
-
- self.check_invalid_constraint('libelf arch=bgqos_0', 'libelf arch=x86_54')
-
+ self.check_invalid_constraint('libelf platform=test target=be os=be',
+ 'libelf target=fe os=fe')
def test_constrain_changed(self):
self.check_constrain_changed('libelf', '@1.0')
@@ -382,7 +395,10 @@ class SpecSematicsTest(MockPackagesTest):
self.check_constrain_changed('libelf', '~debug')
self.check_constrain_changed('libelf', 'debug=2')
self.check_constrain_changed('libelf', 'cppflags="-O3"')
- self.check_constrain_changed('libelf', ' arch=bgqos_0')
+
+ platform = spack.architecture.sys_type()
+ self.check_constrain_changed('libelf', 'target='+platform.target('default_target').name)
+ self.check_constrain_changed('libelf', 'os='+platform.operating_system('default_os').name)
def test_constrain_not_changed(self):
@@ -395,9 +411,10 @@ class SpecSematicsTest(MockPackagesTest):
self.check_constrain_not_changed('libelf~debug', '~debug')
self.check_constrain_not_changed('libelf debug=2', 'debug=2')
self.check_constrain_not_changed('libelf cppflags="-O3"', 'cppflags="-O3"')
- self.check_constrain_not_changed('libelf arch=bgqos_0', ' arch=bgqos_0')
- self.check_constrain_not_changed('libelf^foo', 'libelf^foo')
- self.check_constrain_not_changed('libelf^foo^bar', 'libelf^foo^bar')
+
+ platform = spack.architecture.sys_type()
+ default_target = platform.target('default_target').name
+ self.check_constrain_not_changed('libelf target='+default_target, 'target='+default_target)
def test_constrain_dependency_changed(self):
@@ -407,8 +424,10 @@ class SpecSematicsTest(MockPackagesTest):
self.check_constrain_changed('libelf^foo%gcc', 'libelf^foo%gcc@4.5')
self.check_constrain_changed('libelf^foo', 'libelf^foo+debug')
self.check_constrain_changed('libelf^foo', 'libelf^foo~debug')
- self.check_constrain_changed('libelf^foo', 'libelf^foo cppflags="-O3"')
- self.check_constrain_changed('libelf^foo', 'libelf^foo arch=bgqos_0')
+
+ platform = spack.architecture.sys_type()
+ default_target = platform.target('default_target').name
+ self.check_constrain_changed('libelf^foo', 'libelf^foo target='+default_target)
def test_constrain_dependency_not_changed(self):
@@ -419,5 +438,7 @@ class SpecSematicsTest(MockPackagesTest):
self.check_constrain_not_changed('libelf^foo+debug', 'libelf^foo+debug')
self.check_constrain_not_changed('libelf^foo~debug', 'libelf^foo~debug')
self.check_constrain_not_changed('libelf^foo cppflags="-O3"', 'libelf^foo cppflags="-O3"')
- self.check_constrain_not_changed('libelf^foo arch=bgqos_0', 'libelf^foo arch=bgqos_0')
+ platform = spack.architecture.sys_type()
+ default_target = platform.target('default_target').name
+ self.check_constrain_not_changed('libelf^foo target='+default_target, 'libelf^foo target='+default_target)
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index c4e4c9cdfe..4a534d7b5c 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -58,7 +58,7 @@ class SpecSyntaxTest(unittest.TestCase):
# ================================================================================
# Parse checks
# ================================================================================
- def check_parse(self, expected, spec=None):
+ def check_parse(self, expected, spec=None, remove_arch=True):
"""Assert that the provided spec is able to be parsed.
If this is called with one argument, it assumes that the string is
canonical (i.e., no spaces and ~ instead of - for variants) and that it
@@ -70,6 +70,7 @@ class SpecSyntaxTest(unittest.TestCase):
if spec is None:
spec = expected
output = spack.spec.parse(spec)
+
parsed = (" ".join(str(spec) for spec in output))
self.assertEqual(expected, parsed)
diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py
index a026403e2e..4624f901c8 100644
--- a/lib/spack/spack/test/versions.py
+++ b/lib/spack/spack/test/versions.py
@@ -43,7 +43,6 @@ class VersionsTest(unittest.TestCase):
self.assertFalse(a > b)
self.assertFalse(a >= b)
-
def assert_ver_gt(self, a, b):
a, b = ver(a), ver(b)
self.assertTrue(a > b)
@@ -53,7 +52,6 @@ class VersionsTest(unittest.TestCase):
self.assertFalse(a < b)
self.assertFalse(a <= b)
-
def assert_ver_eq(self, a, b):
a, b = ver(a), ver(b)
self.assertFalse(a > b)
@@ -63,55 +61,43 @@ class VersionsTest(unittest.TestCase):
self.assertFalse(a < b)
self.assertTrue(a <= b)
-
def assert_in(self, needle, haystack):
self.assertTrue(ver(needle) in ver(haystack))
-
def assert_not_in(self, needle, haystack):
self.assertFalse(ver(needle) in ver(haystack))
-
def assert_canonical(self, canonical_list, version_list):
self.assertEqual(ver(canonical_list), ver(version_list))
-
def assert_overlaps(self, v1, v2):
self.assertTrue(ver(v1).overlaps(ver(v2)))
-
def assert_no_overlap(self, v1, v2):
self.assertFalse(ver(v1).overlaps(ver(v2)))
-
def assert_satisfies(self, v1, v2):
self.assertTrue(ver(v1).satisfies(ver(v2)))
-
def assert_does_not_satisfy(self, v1, v2):
self.assertFalse(ver(v1).satisfies(ver(v2)))
-
def check_intersection(self, expected, a, b):
self.assertEqual(ver(expected), ver(a).intersection(ver(b)))
-
def check_union(self, expected, a, b):
self.assertEqual(ver(expected), ver(a).union(ver(b)))
-
def test_two_segments(self):
self.assert_ver_eq('1.0', '1.0')
self.assert_ver_lt('1.0', '2.0')
self.assert_ver_gt('2.0', '1.0')
-
def test_three_segments(self):
self.assert_ver_eq('2.0.1', '2.0.1')
self.assert_ver_lt('2.0', '2.0.1')
self.assert_ver_gt('2.0.1', '2.0')
-
def test_alpha(self):
# TODO: not sure whether I like this. 2.0.1a is *usually*
# TODO: less than 2.0.1, but special-casing it makes version
@@ -120,7 +106,6 @@ class VersionsTest(unittest.TestCase):
self.assert_ver_gt('2.0.1a', '2.0.1')
self.assert_ver_lt('2.0.1', '2.0.1a')
-
def test_patch(self):
self.assert_ver_eq('5.5p1', '5.5p1')
self.assert_ver_lt('5.5p1', '5.5p2')
@@ -129,7 +114,6 @@ class VersionsTest(unittest.TestCase):
self.assert_ver_lt('5.5p1', '5.5p10')
self.assert_ver_gt('5.5p10', '5.5p1')
-
def test_num_alpha_with_no_separator(self):
self.assert_ver_lt('10xyz', '10.1xyz')
self.assert_ver_gt('10.1xyz', '10xyz')
@@ -137,7 +121,6 @@ class VersionsTest(unittest.TestCase):
self.assert_ver_lt('xyz10', 'xyz10.1')
self.assert_ver_gt('xyz10.1', 'xyz10')
-
def test_alpha_with_dots(self):
self.assert_ver_eq('xyz.4', 'xyz.4')
self.assert_ver_lt('xyz.4', '8')
@@ -145,30 +128,25 @@ class VersionsTest(unittest.TestCase):
self.assert_ver_lt('xyz.4', '2')
self.assert_ver_gt('2', 'xyz.4')
-
def test_nums_and_patch(self):
self.assert_ver_lt('5.5p2', '5.6p1')
self.assert_ver_gt('5.6p1', '5.5p2')
self.assert_ver_lt('5.6p1', '6.5p1')
self.assert_ver_gt('6.5p1', '5.6p1')
-
def test_rc_versions(self):
self.assert_ver_gt('6.0.rc1', '6.0')
self.assert_ver_lt('6.0', '6.0.rc1')
-
def test_alpha_beta(self):
self.assert_ver_gt('10b2', '10a1')
self.assert_ver_lt('10a2', '10b2')
-
def test_double_alpha(self):
self.assert_ver_eq('1.0aa', '1.0aa')
self.assert_ver_lt('1.0a', '1.0aa')
self.assert_ver_gt('1.0aa', '1.0a')
-
def test_padded_numbers(self):
self.assert_ver_eq('10.0001', '10.0001')
self.assert_ver_eq('10.0001', '10.1')
@@ -176,24 +154,20 @@ class VersionsTest(unittest.TestCase):
self.assert_ver_lt('10.0001', '10.0039')
self.assert_ver_gt('10.0039', '10.0001')
-
def test_close_numbers(self):
self.assert_ver_lt('4.999.9', '5.0')
self.assert_ver_gt('5.0', '4.999.9')
-
def test_date_stamps(self):
self.assert_ver_eq('20101121', '20101121')
self.assert_ver_lt('20101121', '20101122')
self.assert_ver_gt('20101122', '20101121')
-
def test_underscores(self):
self.assert_ver_eq('2_0', '2_0')
self.assert_ver_eq('2.0', '2_0')
self.assert_ver_eq('2_0', '2.0')
-
def test_rpm_oddities(self):
self.assert_ver_eq('1b.fc17', '1b.fc17')
self.assert_ver_lt('1b.fc17', '1.fc17')
@@ -202,7 +176,6 @@ class VersionsTest(unittest.TestCase):
self.assert_ver_gt('1g.fc17', '1.fc17')
self.assert_ver_lt('1.fc17', '1g.fc17')
-
# Stuff below here is not taken from RPM's tests and is
# unique to spack
def test_version_ranges(self):
@@ -214,7 +187,6 @@ class VersionsTest(unittest.TestCase):
self.assert_ver_lt('1.2:1.4', '1.5:1.6')
self.assert_ver_gt('1.5:1.6', '1.2:1.4')
-
def test_contains(self):
self.assert_in('1.3', '1.2:1.4')
self.assert_in('1.2.5', '1.2:1.4')
@@ -233,7 +205,6 @@ class VersionsTest(unittest.TestCase):
self.assert_in('1.4.1', '1.2.7:1.4')
self.assert_not_in('1.4.1', '1.2.7:1.4.0')
-
def test_in_list(self):
self.assert_in('1.2', ['1.5', '1.2', '1.3'])
self.assert_in('1.2.5', ['1.5', '1.2:1.3'])
@@ -245,7 +216,6 @@ class VersionsTest(unittest.TestCase):
self.assert_not_in('1.2.5:1.5', ['1.5', '1.2:1.3'])
self.assert_not_in('1.1:1.2.5', ['1.5', '1.2:1.3'])
-
def test_ranges_overlap(self):
self.assert_overlaps('1.2', '1.2')
self.assert_overlaps('1.2.1', '1.2.1')
@@ -262,7 +232,6 @@ class VersionsTest(unittest.TestCase):
self.assert_overlaps(':', '1.6:1.9')
self.assert_overlaps('1.6:1.9', ':')
-
def test_overlap_with_containment(self):
self.assert_in('1.6.5', '1.6')
self.assert_in('1.6.5', ':1.6')
@@ -273,7 +242,6 @@ class VersionsTest(unittest.TestCase):
self.assert_not_in(':1.6', '1.6.5')
self.assert_in('1.6.5', ':1.6')
-
def test_lists_overlap(self):
self.assert_overlaps('1.2b:1.7,5', '1.6:1.9,1')
self.assert_overlaps('1,2,3,4,5', '3,4,5,6,7')
@@ -287,7 +255,6 @@ class VersionsTest(unittest.TestCase):
self.assert_no_overlap('1,2,3,4,5', '6,7')
self.assert_no_overlap('1,2,3,4,5', '6:7')
-
def test_canonicalize_list(self):
self.assert_canonical(['1.2', '1.3', '1.4'],
['1.2', '1.3', '1.3', '1.4'])
@@ -316,7 +283,6 @@ class VersionsTest(unittest.TestCase):
self.assert_canonical([':'],
[':,1.3, 1.3.1,1.3.9,1.4 : 1.5 , 1.3 : 1.4'])
-
def test_intersection(self):
self.check_intersection('2.5',
'1.0:2.5', '2.5:3.0')
@@ -325,12 +291,11 @@ class VersionsTest(unittest.TestCase):
self.check_intersection('0:1', ':', '0:1')
self.check_intersection(['1.0', '2.5:2.7'],
- ['1.0:2.7'], ['2.5:3.0','1.0'])
+ ['1.0:2.7'], ['2.5:3.0', '1.0'])
self.check_intersection(['2.5:2.7'],
- ['1.1:2.7'], ['2.5:3.0','1.0'])
+ ['1.1:2.7'], ['2.5:3.0', '1.0'])
self.check_intersection(['0:1'], [':'], ['0:1'])
-
def test_intersect_with_containment(self):
self.check_intersection('1.6.5', '1.6.5', ':1.6')
self.check_intersection('1.6.5', ':1.6', '1.6.5')
@@ -338,7 +303,6 @@ class VersionsTest(unittest.TestCase):
self.check_intersection('1.6:1.6.5', ':1.6.5', '1.6')
self.check_intersection('1.6:1.6.5', '1.6', ':1.6.5')
-
def test_union_with_containment(self):
self.check_union(':1.6', '1.6.5', ':1.6')
self.check_union(':1.6', ':1.6', '1.6.5')
@@ -346,8 +310,6 @@ class VersionsTest(unittest.TestCase):
self.check_union(':1.6', ':1.6.5', '1.6')
self.check_union(':1.6', '1.6', ':1.6.5')
-
- def test_union_with_containment(self):
self.check_union(':', '1.0:', ':2.0')
self.check_union('1:4', '1:3', '2:4')
@@ -356,7 +318,6 @@ class VersionsTest(unittest.TestCase):
# Tests successor/predecessor case.
self.check_union('1:4', '1:2', '3:4')
-
def test_basic_version_satisfaction(self):
self.assert_satisfies('4.7.3', '4.7.3')
@@ -372,7 +333,6 @@ class VersionsTest(unittest.TestCase):
self.assert_does_not_satisfy('4.8', '4.9')
self.assert_does_not_satisfy('4', '4.9')
-
def test_basic_version_satisfaction_in_lists(self):
self.assert_satisfies(['4.7.3'], ['4.7.3'])
@@ -388,7 +348,6 @@ class VersionsTest(unittest.TestCase):
self.assert_does_not_satisfy(['4.8'], ['4.9'])
self.assert_does_not_satisfy(['4'], ['4.9'])
-
def test_version_range_satisfaction(self):
self.assert_satisfies('4.7b6', '4.3:4.7')
self.assert_satisfies('4.3.0', '4.3:4.7')
@@ -400,7 +359,6 @@ class VersionsTest(unittest.TestCase):
self.assert_satisfies('4.7b6', '4.3:4.7')
self.assert_does_not_satisfy('4.8.0', '4.3:4.7')
-
def test_version_range_satisfaction_in_lists(self):
self.assert_satisfies(['4.7b6'], ['4.3:4.7'])
self.assert_satisfies(['4.3.0'], ['4.3:4.7'])
@@ -423,3 +381,11 @@ class VersionsTest(unittest.TestCase):
self.assert_satisfies('4.8.0', '4.2, 4.3:4.8')
self.assert_satisfies('4.8.2', '4.2, 4.3:4.8')
+
+ def test_formatted_strings(self):
+ versions = '1.2.3', '1_2_3', '1-2-3'
+ for item in versions:
+ v = Version(item)
+ self.assertEqual(v.dotted, '1.2.3')
+ self.assertEqual(v.dashed, '1-2-3')
+ self.assertEqual(v.underscored, '1_2_3')
diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py
index 38b778fa00..14b56e8d6c 100644
--- a/lib/spack/spack/util/executable.py
+++ b/lib/spack/spack/util/executable.py
@@ -165,6 +165,7 @@ class Executable(object):
raise ProcessError("Command exited with status %d:" %
proc.returncode, cmd_line)
+
if output is str or error is str:
result = ''
if output is str:
diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py
index 247f6d2362..858d581472 100644
--- a/lib/spack/spack/version.py
+++ b/lib/spack/spack/version.py
@@ -43,16 +43,16 @@ be called on any of the types::
intersection
concrete
"""
-import os
-import sys
import re
from bisect import bisect_left
from functools import wraps
+
from functools_backport import total_ordering
# Valid version characters
VALID_VERSION = r'[A-Za-z0-9_.-]'
+
def int_if_int(string):
"""Convert a string to int if possible. Otherwise, return a string."""
try:
@@ -62,10 +62,11 @@ def int_if_int(string):
def coerce_versions(a, b):
- """Convert both a and b to the 'greatest' type between them, in this order:
+ """
+ Convert both a and b to the 'greatest' type between them, in this order:
Version < VersionRange < VersionList
- This is used to simplify comparison operations below so that we're always
- comparing things that are of the same type.
+ This is used to simplify comparison operations below so that we're always
+ comparing things that are of the same type.
"""
order = (Version, VersionRange, VersionList)
ta, tb = type(a), type(b)
@@ -105,6 +106,7 @@ def coerced(method):
@total_ordering
class Version(object):
"""Class to represent versions"""
+
def __init__(self, string):
string = str(string)
@@ -124,6 +126,17 @@ class Version(object):
# last element of separators is ''
self.separators = tuple(re.split(segment_regex, string)[1:-1])
+ @property
+ def dotted(self):
+ return '.'.join(str(x) for x in self.version)
+
+ @property
+ def underscored(self):
+ return '_'.join(str(x) for x in self.version)
+
+ @property
+ def dashed(self):
+ return '-'.join(str(x) for x in self.version)
def up_to(self, index):
"""Return a version string up to the specified component, exclusive.
@@ -131,15 +144,12 @@ class Version(object):
"""
return '.'.join(str(x) for x in self[:index])
-
def lowest(self):
return self
-
def highest(self):
return self
-
@coerced
def satisfies(self, other):
"""A Version 'satisfies' another if it is at least as specific and has a
@@ -147,11 +157,10 @@ class Version(object):
gcc@4.7 so that when a user asks to build with gcc@4.7, we can find
a suitable compiler.
"""
- nself = len(self.version)
+ nself = len(self.version)
nother = len(other.version)
return nother <= nself and self.version[:nother] == other.version
-
def wildcard(self):
"""Create a regex that will match variants of this version string."""
def a_or_n(seg):
@@ -181,28 +190,22 @@ class Version(object):
wc += '(?:[a-z]|alpha|beta)?)?' * (len(segments) - 1)
return wc
-
def __iter__(self):
return iter(self.version)
-
def __getitem__(self, idx):
return tuple(self.version[idx])
-
def __repr__(self):
return self.string
-
def __str__(self):
return self.string
-
@property
def concrete(self):
return self
-
@coerced
def __lt__(self, other):
"""Version comparison is designed for consistency with the way RPM
@@ -235,28 +238,23 @@ class Version(object):
# If the common prefix is equal, the one with more segments is bigger.
return len(self.version) < len(other.version)
-
@coerced
def __eq__(self, other):
return (other is not None and
type(other) == Version and self.version == other.version)
-
def __ne__(self, other):
return not (self == other)
-
def __hash__(self):
return hash(self.version)
-
@coerced
def __contains__(self, other):
if other is None:
return False
return other.version[:len(self.version)] == self.version
-
def is_predecessor(self, other):
"""True if the other version is the immediate predecessor of this one.
That is, NO versions v exist such that:
@@ -269,16 +267,13 @@ class Version(object):
ol = other.version[-1]
return type(sl) == int and type(ol) == int and (ol - sl == 1)
-
def is_successor(self, other):
return other.is_predecessor(self)
-
@coerced
def overlaps(self, other):
return self in other or other in self
-
@coerced
def union(self, other):
if self == other or other in self:
@@ -288,7 +283,6 @@ class Version(object):
else:
return VersionList([self, other])
-
@coerced
def intersection(self, other):
if self == other:
@@ -299,6 +293,7 @@ class Version(object):
@total_ordering
class VersionRange(object):
+
def __init__(self, start, end):
if isinstance(start, basestring):
start = Version(start)
@@ -310,15 +305,12 @@ class VersionRange(object):
if start and end and end < start:
raise ValueError("Invalid Version range: %s" % self)
-
def lowest(self):
return self.start
-
def highest(self):
return self.end
-
@coerced
def __lt__(self, other):
"""Sort VersionRanges lexicographically so that they are ordered first
@@ -331,28 +323,24 @@ class VersionRange(object):
s, o = self, other
if s.start != o.start:
- return s.start is None or (o.start is not None and s.start < o.start)
+ return s.start is None or (o.start is not None and s.start < o.start) # NOQA: ignore=E501
return (s.end != o.end and
o.end is None or (s.end is not None and s.end < o.end))
-
@coerced
def __eq__(self, other):
return (other is not None and
type(other) == VersionRange and
self.start == other.start and self.end == other.end)
-
def __ne__(self, other):
return not (self == other)
-
@property
def concrete(self):
return self.start if self.start == self.end else None
-
@coerced
def __contains__(self, other):
if other is None:
@@ -373,57 +361,55 @@ class VersionRange(object):
other.end in self.end)))
return in_upper
-
@coerced
def satisfies(self, other):
- """A VersionRange satisfies another if some version in this range
- would satisfy some version in the other range. To do this it must
- either:
- a) Overlap with the other range
- b) The start of this range satisfies the end of the other range.
-
- This is essentially the same as overlaps(), but overlaps assumes
- that its arguments are specific. That is, 4.7 is interpreted as
- 4.7.0.0.0.0... . This funciton assumes that 4.7 woudl be satisfied
- by 4.7.3.5, etc.
-
- Rationale:
- If a user asks for gcc@4.5:4.7, and a package is only compatible with
- gcc@4.7.3:4.8, then that package should be able to build under the
- constraints. Just using overlaps() would not work here.
-
- Note that we don't need to check whether the end of this range
- would satisfy the start of the other range, because overlaps()
- already covers that case.
-
- Note further that overlaps() is a symmetric operation, while
- satisfies() is not.
+ """
+ A VersionRange satisfies another if some version in this range
+ would satisfy some version in the other range. To do this it must
+ either:
+ a) Overlap with the other range
+ b) The start of this range satisfies the end of the other range.
+
+ This is essentially the same as overlaps(), but overlaps assumes
+ that its arguments are specific. That is, 4.7 is interpreted as
+ 4.7.0.0.0.0... . This funciton assumes that 4.7 woudl be satisfied
+ by 4.7.3.5, etc.
+
+ Rationale:
+ If a user asks for gcc@4.5:4.7, and a package is only compatible with
+ gcc@4.7.3:4.8, then that package should be able to build under the
+ constraints. Just using overlaps() would not work here.
+
+ Note that we don't need to check whether the end of this range
+ would satisfy the start of the other range, because overlaps()
+ already covers that case.
+
+ Note further that overlaps() is a symmetric operation, while
+ satisfies() is not.
"""
return (self.overlaps(other) or
# if either self.start or other.end are None, then this can't
# satisfy, or overlaps() would've taken care of it.
self.start and other.end and self.start.satisfies(other.end))
-
@coerced
def overlaps(self, other):
- return ((self.start == None or other.end is None or
+ return ((self.start is None or other.end is None or
self.start <= other.end or
other.end in self.start or self.start in other.end) and
- (other.start is None or self.end == None or
+ (other.start is None or self.end is None or
other.start <= self.end or
other.start in self.end or self.end in other.start))
-
@coerced
def union(self, other):
if not self.overlaps(other):
if (self.end is not None and other.start is not None and
- self.end.is_predecessor(other.start)):
+ self.end.is_predecessor(other.start)):
return VersionRange(self.start, other.end)
if (other.end is not None and self.start is not None and
- other.end.is_predecessor(self.start)):
+ other.end.is_predecessor(self.start)):
return VersionRange(other.start, self.end)
return VersionList([self, other])
@@ -442,13 +428,12 @@ class VersionRange(object):
else:
end = self.end
# TODO: See note in intersection() about < and in discrepancy.
- if not other.end in self.end:
+ if other.end not in self.end:
if end in other.end or other.end > self.end:
end = other.end
return VersionRange(start, end)
-
@coerced
def intersection(self, other):
if self.overlaps(other):
@@ -470,7 +455,7 @@ class VersionRange(object):
# 1.6 < 1.6.5 = True (lexicographic)
# Should 1.6 NOT be less than 1.6.5? Hm.
# Here we test (not end in other.end) first to avoid paradox.
- if other.end is not None and not end in other.end:
+ if other.end is not None and end not in other.end:
if other.end < end or other.end in end:
end = other.end
@@ -479,15 +464,12 @@ class VersionRange(object):
else:
return VersionList()
-
def __hash__(self):
return hash((self.start, self.end))
-
def __repr__(self):
return self.__str__()
-
def __str__(self):
out = ""
if self.start:
@@ -501,6 +483,7 @@ class VersionRange(object):
@total_ordering
class VersionList(object):
"""Sorted, non-redundant list of Versions and VersionRanges."""
+
def __init__(self, vlist=None):
self.versions = []
if vlist is not None:
@@ -515,7 +498,6 @@ class VersionList(object):
for v in vlist:
self.add(ver(v))
-
def add(self, version):
if type(version) in (Version, VersionRange):
# This normalizes single-value version ranges.
@@ -524,9 +506,9 @@ class VersionList(object):
i = bisect_left(self, version)
- while i-1 >= 0 and version.overlaps(self[i-1]):
- version = version.union(self[i-1])
- del self.versions[i-1]
+ while i - 1 >= 0 and version.overlaps(self[i - 1]):
+ version = version.union(self[i - 1])
+ del self.versions[i - 1]
i -= 1
while i < len(self) and version.overlaps(self[i]):
@@ -542,7 +524,6 @@ class VersionList(object):
else:
raise TypeError("Can't add %s to VersionList" % type(version))
-
@property
def concrete(self):
if len(self) == 1:
@@ -550,11 +531,9 @@ class VersionList(object):
else:
return None
-
def copy(self):
return VersionList(self)
-
def lowest(self):
"""Get the lowest version in the list."""
if not self:
@@ -562,7 +541,6 @@ class VersionList(object):
else:
return self[0].lowest()
-
def highest(self):
"""Get the highest version in the list."""
if not self:
@@ -570,7 +548,6 @@ class VersionList(object):
else:
return self[-1].highest()
-
@coerced
def overlaps(self, other):
if not other or not self:
@@ -586,14 +563,12 @@ class VersionList(object):
o += 1
return False
-
def to_dict(self):
"""Generate human-readable dict for YAML."""
if self.concrete:
- return { 'version' : str(self[0]) }
+ return {'version': str(self[0])}
else:
- return { 'versions' : [str(v) for v in self] }
-
+ return {'versions': [str(v) for v in self]}
@staticmethod
def from_dict(dictionary):
@@ -605,7 +580,6 @@ class VersionList(object):
else:
raise ValueError("Dict must have 'version' or 'versions' in it.")
-
@coerced
def satisfies(self, other, strict=False):
"""A VersionList satisfies another if some version in the list
@@ -633,20 +607,17 @@ class VersionList(object):
o += 1
return False
-
@coerced
def update(self, other):
for v in other.versions:
self.add(v)
-
@coerced
def union(self, other):
result = self.copy()
result.update(other)
return result
-
@coerced
def intersection(self, other):
# TODO: make this faster. This is O(n^2).
@@ -656,7 +627,6 @@ class VersionList(object):
result.add(s.intersection(o))
return result
-
@coerced
def intersect(self, other):
"""Intersect this spec's list with other.
@@ -678,50 +648,40 @@ class VersionList(object):
if i == 0:
if version not in self[0]:
return False
- elif all(version not in v for v in self[i-1:]):
+ elif all(version not in v for v in self[i - 1:]):
return False
return True
-
def __getitem__(self, index):
return self.versions[index]
-
def __iter__(self):
return iter(self.versions)
-
def __reversed__(self):
return reversed(self.versions)
-
def __len__(self):
return len(self.versions)
-
@coerced
def __eq__(self, other):
return other is not None and self.versions == other.versions
-
def __ne__(self, other):
return not (self == other)
-
@coerced
def __lt__(self, other):
return other is not None and self.versions < other.versions
-
def __hash__(self):
return hash(tuple(self.versions))
-
def __str__(self):
return ",".join(str(v) for v in self.versions)
-
def __repr__(self):
return str(self.versions)
@@ -730,7 +690,7 @@ def _string_to_version(string):
"""Converts a string to a Version, VersionList, or VersionRange.
This is private. Client code should use ver().
"""
- string = string.replace(' ','')
+ string = string.replace(' ', '')
if ',' in string:
return VersionList(string.split(','))
@@ -738,7 +698,7 @@ def _string_to_version(string):
elif ':' in string:
s, e = string.split(':')
start = Version(s) if s else None
- end = Version(e) if e else None
+ end = Version(e) if e else None
return VersionRange(start, end)
else:
diff --git a/lib/spack/spack/yaml_version_check.py b/lib/spack/spack/yaml_version_check.py
new file mode 100644
index 0000000000..c2d084d6c3
--- /dev/null
+++ b/lib/spack/spack/yaml_version_check.py
@@ -0,0 +1,55 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+"""Yaml Version Check is a module for ensuring that config file
+formats are compatible with the current version of Spack."""
+import os.path
+import os
+import llnl.util.tty as tty
+import spack.util.spack_yaml as syaml
+import spack.config
+
+
+def check_yaml_versions():
+ check_compiler_yaml_version()
+
+def check_compiler_yaml_version():
+ config_scopes = spack.config.config_scopes
+ for scope in config_scopes.values():
+ file_name = os.path.join(scope.path, 'compilers.yaml')
+ data = None
+ if os.path.isfile(file_name):
+ with open(file_name) as f:
+ data = syaml.load(f)
+
+ if data:
+ compilers = data['compilers']
+ if len(compilers) > 0:
+ 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 '
+ 'a compilers config file '
+ % (file_name, new_file))
+ os.rename(file_name, new_file)
diff --git a/var/spack/mock_configs/site_spackconfig/compilers.yaml b/var/spack/mock_configs/site_spackconfig/compilers.yaml
new file mode 100644
index 0000000000..5f8b38007b
--- /dev/null
+++ b/var/spack/mock_configs/site_spackconfig/compilers.yaml
@@ -0,0 +1,40 @@
+compilers:
+ all:
+ clang@3.3:
+ cc: /path/to/clang
+ cxx: /path/to/clang++
+ f77: None
+ fc: None
+ modules: None
+ strategy: PATH
+ gcc@4.5.0:
+ cc: /path/to/gcc
+ cxx: /path/to/g++
+ f77: /path/to/gfortran
+ fc: /path/to/gfortran
+ modules: None
+ strategy: PATH
+ gcc@5.2.0:
+ cc: cc
+ cxx: CC
+ f77: ftn
+ fc: ftn
+ modules:
+ - PrgEnv-gnu
+ - gcc/5.2.0
+ strategy: MODULES
+ intel@15.0.1:
+ cc: cc
+ ccx: CC
+ f77: ftn
+ fc: ftn
+ modules:
+ - PrgEnv-intel
+ - intel/15.0.1
+ strategy: MODULES
+ intel@15.1.2:
+ cc: /path/to/icc
+ cxx: /path/to/ic++
+ f77: /path/to/ifort
+ fc: /path/to/ifort
+ strategy: PATH \ No newline at end of file
diff --git a/var/spack/packages/adios/package.py b/var/spack/packages/adios/package.py
new file mode 100644
index 0000000000..260dcbe851
--- /dev/null
+++ b/var/spack/packages/adios/package.py
@@ -0,0 +1,38 @@
+import os
+
+from spack import *
+class Adios(Package):
+ """The Adaptable IO System (ADIOS) provides a simple,
+ flexible way for scientists to describe the
+ data in their code that may need to be written,
+ read, or processed outside of the running simulation
+ """
+
+ homepage = "http://www.olcf.ornl.gov/center-projects/adios/"
+ url = "http://users.nccs.gov/~pnorbert/adios-1.9.0.tar.gz"
+
+ version('1.9.0', 'dbf5cb10e32add2f04c9b4052b7ffa76')
+
+ # Lots of setting up here for this package
+ # module swap PrgEnv-intel PrgEnv-$COMP
+ # module load cray-netcdf/4.3.3.1
+ # module load cray-hdf5/1.8.14
+ # module load python/2.7.10
+ depends_on('hdf5')
+ depends_on('mxml')
+
+ def install(self, spec, prefix):
+ configure_args = ["--prefix=%s" % prefix,
+ "--with-mxml=%s" % spec['mxml'].prefix,
+ "--with-hdf5=%s" % spec['hdf5'].prefix,
+ "--with-netcdf=%s" % os.environ["NETCDF_DIR"],
+ "--with-infiniband=no",
+ "MPICC=cc","MPICXX=CC","MPIFC=ftn",
+ "CPPFLAGS=-DMPICH_IGNORE_CXX_SEEK"]
+
+ if spec.satisfies('%gcc'):
+ configure_args.extend(["CC=gcc", "CXX=g++", "FC=gfortran"])
+
+ configure(*configure_args)
+ make()
+ make("install")
diff --git a/var/spack/packages/mxml/package.py b/var/spack/packages/mxml/package.py
new file mode 100644
index 0000000000..f79251d312
--- /dev/null
+++ b/var/spack/packages/mxml/package.py
@@ -0,0 +1,26 @@
+import os
+from spack import *
+
+class Mxml(Package):
+ """Mini-XML is a small XML library that you can use to read and write XML
+ and XML-like data files in your application without requiring large
+ non-standard libraries
+ """
+
+ homepage = "http://www.msweet.org"
+ url = "http://www.msweet.org/files/project3/mxml-2.9.tar.gz"
+
+ version('2.9', 'e21cad0f7aacd18f942aa0568a8dee19')
+ version('2.8', 'd85ee6d30de053581242c4a86e79a5d2')
+ version('2.7', '76f2ae49bf0f5745d5cb5d9507774dc9')
+ version('2.6', '68977789ae64985dddbd1a1a1652642e')
+ version('2.5', 'f706377fba630b39fa02fd63642b17e5')
+
+ # module swap PrgEnv-intel PrgEnv-$COMP (Can use whatever compiler you want to use)
+ # Case statement to change CC and CXX flags
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix, "--disable-shared", 'CFLAGS=-static')
+ make()
+ make("install")
+
diff --git a/var/spack/repos/builtin.mock/packages/externalmodule/package.py b/var/spack/repos/builtin.mock/packages/externalmodule/package.py
new file mode 100644
index 0000000000..f7b0da3fd9
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/externalmodule/package.py
@@ -0,0 +1,37 @@
+
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+class Externalmodule(Package):
+ homepage = "http://somewhere.com"
+ url = "http://somewhere.com/module-1.0.tar.gz"
+
+ version('1.0', '1234567890abcdef1234567890abcdef')
+
+ depends_on('externalprereq')
+
+ def install(self, spec, prefix):
+ pass
diff --git a/var/spack/repos/builtin.mock/packages/multimethod/package.py b/var/spack/repos/builtin.mock/packages/multimethod/package.py
index def73ad82e..649afa5945 100644
--- a/var/spack/repos/builtin.mock/packages/multimethod/package.py
+++ b/var/spack/repos/builtin.mock/packages/multimethod/package.py
@@ -22,8 +22,11 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
+import imp
+from llnl.util.filesystem import join_path
+from spack.util.naming import mod_to_class
from spack import *
-
+import spack.architecture
class Multimethod(Package):
"""This package is designed for use with Spack's multimethod test.
@@ -101,25 +104,26 @@ class Multimethod(Package):
#
- # Make sure we can switch methods on different architectures
+ # Make sure we can switch methods on different target
#
- @when('arch=x86_64')
- def different_by_architecture(self):
- return 'x86_64'
-
- @when('arch=ppc64')
- def different_by_architecture(self):
- return 'ppc64'
-
- @when('arch=ppc32')
- def different_by_architecture(self):
- return 'ppc32'
-
- @when('arch=arm64')
- def different_by_architecture(self):
- return 'arm64'
-
-
+# for platform_name in ['cray_xc', 'darwin', 'linux']:
+# file_path = join_path(spack.platform_path, platform_name)
+# platform_mod = imp.load_source('spack.platforms', file_path + '.py')
+# cls = getattr(platform_mod, mod_to_class(platform_name))
+
+# platform = cls()
+ platform = spack.architecture.sys_type()
+ targets = platform.targets.values()
+ if len(targets) > 1:
+ targets = targets[:-1]
+
+ for target in targets:
+ @when('target='+target.name)
+ def different_by_target(self):
+ if isinstance(self.spec.architecture.target,basestring):
+ return self.spec.architecture.target
+ else:
+ return self.spec.architecture.target.name
#
# Make sure we can switch methods on different dependencies
#
diff --git a/var/spack/repos/builtin/packages/bertini/package.py b/var/spack/repos/builtin/packages/bertini/package.py
new file mode 100644
index 0000000000..8d7da705e4
--- /dev/null
+++ b/var/spack/repos/builtin/packages/bertini/package.py
@@ -0,0 +1,50 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class Bertini(Package):
+ """Bertini is a general-purpose solver, written in C, that was created
+ for research about polynomial continuation. It solves for the numerical
+ solution of systems of polynomial equations using homotopy continuation."""
+
+ homepage = "https://bertini.nd.edu/"
+ url = "https://bertini.nd.edu/BertiniSource_v1.5.tar.gz"
+
+ version('1.5', 'e3f6cc6e7f9a0cf1d73185e8671af707')
+
+ variant('mpi', default=True, description='Compile in parallel')
+
+ depends_on('flex')
+ depends_on('bison')
+ depends_on('gmp')
+ depends_on('mpfr')
+ depends_on('mpi', when='+mpi')
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix)
+
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/binutils/package.py b/var/spack/repos/builtin/packages/binutils/package.py
index 9e4cc98ae6..5f305abb02 100644
--- a/var/spack/repos/builtin/packages/binutils/package.py
+++ b/var/spack/repos/builtin/packages/binutils/package.py
@@ -30,8 +30,9 @@ class Binutils(Package):
url="https://ftp.gnu.org/gnu/binutils/binutils-2.25.tar.bz2"
+ # 2.26 is incompatible with py-pillow build for some reason.
version('2.26', '64146a0faa3b411ba774f47d41de239f')
- version('2.25', 'd9f3303f802a5b6b0bb73a335ab89d66')
+ version('2.25', 'd9f3303f802a5b6b0bb73a335ab89d66', preferred=True)
version('2.24', 'e0f71a7b2ddab0f8612336ac81d9636b')
version('2.23.2', '4f8fa651e35ef262edc01d60fb45702e')
version('2.20.1', '2b9dc8f2b7dbd5ec5992c6e29de0b764')
diff --git a/var/spack/repos/builtin/packages/boost/package.py b/var/spack/repos/builtin/packages/boost/package.py
index 2f2965eb12..cde76c590a 100644
--- a/var/spack/repos/builtin/packages/boost/package.py
+++ b/var/spack/repos/builtin/packages/boost/package.py
@@ -27,7 +27,7 @@ import spack
import sys
import os
-import sys
+
class Boost(Package):
"""Boost provides free peer-reviewed portable C++ source
@@ -75,23 +75,23 @@ class Boost(Package):
version('1.34.0', 'ed5b9291ffad776f8757a916e1726ad0')
default_install_libs = set(['atomic',
- 'chrono',
- 'date_time',
- 'filesystem',
- 'graph',
- 'iostreams',
- 'locale',
- 'log',
- 'math',
- 'program_options',
- 'random',
- 'regex',
- 'serialization',
- 'signals',
- 'system',
- 'test',
- 'thread',
- 'wave'])
+ 'chrono',
+ 'date_time',
+ 'filesystem',
+ 'graph',
+ 'iostreams',
+ 'locale',
+ 'log',
+ 'math',
+ 'program_options',
+ 'random',
+ 'regex',
+ 'serialization',
+ 'signals',
+ 'system',
+ 'test',
+ 'thread',
+ 'wave'])
# mpi/python are not installed by default because they pull in many
# dependencies and/or because there is a great deal of customization
@@ -109,6 +109,7 @@ class Boost(Package):
variant('multithreaded', default=True, description="Build multi-threaded versions of libraries")
variant('singlethreaded', default=True, description="Build single-threaded versions of libraries")
variant('icu_support', default=False, description="Include ICU support (for regex/locale libraries)")
+ variant('graph', default=False, description="Build the Boost Graph library")
depends_on('icu', when='+icu_support')
depends_on('python', when='+python')
@@ -120,15 +121,18 @@ class Boost(Package):
patch('boost_11856.patch', when='@1.60.0%gcc@4.4.7')
def url_for_version(self, version):
- """Handle Boost's weird URLs, which write the version two different ways."""
+ """
+ Handle Boost's weird URLs,
+ which write the version two different ways.
+ """
parts = [str(p) for p in Version(version)]
dots = ".".join(parts)
underscores = "_".join(parts)
- return "http://downloads.sourceforge.net/project/boost/boost/%s/boost_%s.tar.bz2" % (
- dots, underscores)
+ return "http://downloads.sourceforge.net/project/boost" \
+ "/boost/%s/boost_%s.tar.bz2" % (dots, underscores)
def determine_toolset(self, spec):
- if spec.satisfies("arch=darwin-x86_64"):
+ if spec.satisfies("platform=darwin"):
return 'darwin'
toolsets = {'g++': 'gcc',
@@ -149,20 +153,20 @@ class Boost(Package):
if '+python' in spec:
options.append('--with-python=%s' %
- join_path(spec['python'].prefix.bin, 'python'))
+ join_path(spec['python'].prefix.bin, 'python'))
with open('user-config.jam', 'w') as f:
compiler_wrapper = join_path(spack.build_env_path, 'c++')
f.write("using {0} : : {1} ;\n".format(boostToolsetId,
- compiler_wrapper))
+ compiler_wrapper))
if '+mpi' in spec:
f.write('using mpi : %s ;\n' %
- join_path(spec['mpi'].prefix.bin, 'mpicxx'))
+ join_path(spec['mpi'].prefix.bin, 'mpicxx'))
if '+python' in spec:
f.write('using python : %s : %s ;\n' %
- (spec['python'].version,
- join_path(spec['python'].prefix.bin, 'python')))
+ (spec['python'].version,
+ join_path(spec['python'].prefix.bin, 'python')))
def determine_b2_options(self, spec, options):
if '+debug' in spec:
@@ -178,8 +182,7 @@ class Boost(Package):
'-s', 'BZIP2_INCLUDE=%s' % spec['bzip2'].prefix.include,
'-s', 'BZIP2_LIBPATH=%s' % spec['bzip2'].prefix.lib,
'-s', 'ZLIB_INCLUDE=%s' % spec['zlib'].prefix.include,
- '-s', 'ZLIB_LIBPATH=%s' % spec['zlib'].prefix.lib,
- ])
+ '-s', 'ZLIB_LIBPATH=%s' % spec['zlib'].prefix.lib])
linkTypes = ['static']
if '+shared' in spec:
@@ -191,7 +194,8 @@ class Boost(Package):
if '+singlethreaded' in spec:
threadingOpts.append('single')
if not threadingOpts:
- raise RuntimeError("At least one of {singlethreaded, multithreaded} must be enabled")
+ raise RuntimeError("""At least one of {singlethreaded,
+ multithreaded} must be enabled""")
options.extend([
'toolset=%s' % self.determine_toolset(spec),
@@ -202,9 +206,9 @@ class Boost(Package):
def install(self, spec, prefix):
# On Darwin, Boost expects the Darwin libtool. However, one of the
- # dependencies may have pulled in Spack's GNU libtool, and these two are
- # not compatible. We thus create a symlink to Darwin's libtool and add
- # it at the beginning of PATH.
+ # dependencies may have pulled in Spack's GNU libtool, and these two
+ # are not compatible. We thus create a symlink to Darwin's libtool
+ # and add it at the beginning of PATH.
if sys.platform == 'darwin':
newdir = os.path.abspath('darwin-libtool')
mkdirp(newdir)
@@ -217,7 +221,8 @@ class Boost(Package):
withLibs.append(lib)
if not withLibs:
# if no libraries are specified for compilation, then you dont have
- # to configure/build anything, just copy over to the prefix directory.
+ # to configure/build anything, just copy over to the prefix
+ # directory.
src = join_path(self.stage.source_path, 'boost')
mkdirp(join_path(prefix, 'include'))
dst = join_path(prefix, 'include', 'boost')
@@ -235,6 +240,9 @@ class Boost(Package):
withLibs.remove('chrono')
if not spec.satisfies('@1.43.0:'):
withLibs.remove('random')
+ if '+graph' in spec and '+mpi' in spec:
+ withLibs.remove('graph')
+ withLibs.append('graph_parallel')
# to make Boost find the user-config.jam
env['BOOST_BUILD_PATH'] = './'
@@ -259,6 +267,7 @@ class Boost(Package):
for threadingOpt in threadingOpts:
b2('install', 'threading=%s' % threadingOpt, *b2_options)
- # The shared libraries are not installed correctly on Darwin; correct this
+ # The shared libraries are not installed correctly
+ # on Darwin; correct this
if (sys.platform == 'darwin') and ('+shared' in spec):
fix_darwin_install_name(prefix.lib)
diff --git a/var/spack/repos/builtin/packages/c-blosc/package.py b/var/spack/repos/builtin/packages/c-blosc/package.py
new file mode 100644
index 0000000000..dee332be14
--- /dev/null
+++ b/var/spack/repos/builtin/packages/c-blosc/package.py
@@ -0,0 +1,51 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import sys
+
+from spack import *
+
+class CBlosc(Package):
+ """Blosc, an extremely fast, multi-threaded, meta-compressor library"""
+ homepage = "http://www.blosc.org"
+ url = "https://github.com/Blosc/c-blosc/archive/v1.9.2.tar.gz"
+
+ version('1.9.2', 'dd2d83069d74b36b8093f1c6b49defc5')
+ version('1.9.1', '7d708d3daadfacf984a87b71b1734ce2')
+ version('1.9.0', 'e4c1dc8e2c468e5cfa2bf05eeee5357a')
+ version('1.8.1', 'd73d5be01359cf271e9386c90dcf5b05')
+ version('1.8.0', '5b92ecb287695ba20cc33d30bf221c4f')
+
+ depends_on("cmake")
+ depends_on("snappy")
+ depends_on("zlib")
+
+ def install(self, spec, prefix):
+ cmake('.', *std_cmake_args)
+
+ make()
+ make("install")
+ if sys.platform == 'darwin':
+ fix_darwin_install_name(prefix.lib)
diff --git a/var/spack/repos/builtin/packages/caliper/package.py b/var/spack/repos/builtin/packages/caliper/package.py
index 4b8fe0d8af..a424c73859 100644
--- a/var/spack/repos/builtin/packages/caliper/package.py
+++ b/var/spack/repos/builtin/packages/caliper/package.py
@@ -34,7 +34,7 @@ class Caliper(Package):
homepage = "https://github.com/LLNL/Caliper"
url = ""
- version('master', git='ssh://git@github.com:LLNL/Caliper.git')
+ version('master', git='https://github.com/LLNL/Caliper.git')
variant('mpi', default=False, description='Enable MPI function wrappers.')
diff --git a/var/spack/repos/builtin/packages/daal/package.py b/var/spack/repos/builtin/packages/daal/package.py
new file mode 100644
index 0000000000..e13dd80e19
--- /dev/null
+++ b/var/spack/repos/builtin/packages/daal/package.py
@@ -0,0 +1,28 @@
+from spack import *
+import os
+
+from spack.pkg.builtin.intel import IntelInstaller
+
+
+class Daal(IntelInstaller):
+ """Intel Data Analytics Acceleration Library.
+
+ Note: You will have to add the download file to a
+ mirror so that Spack can find it. For instructions on how to set up a
+ mirror, see http://software.llnl.gov/spack/mirrors.html"""
+
+ homepage = "https://software.intel.com/en-us/daal"
+
+ version('2016.2.181', 'aad2aa70e5599ebfe6f85b29d8719d46',
+ url="file://%s/l_daal_2016.2.181.tgz" % os.getcwd())
+ version('2016.3.210', 'ad747c0dd97dace4cad03cf2266cad28',
+ url="file://%s/l_daal_2016.3.210.tgz" % os.getcwd())
+
+ def install(self, spec, prefix):
+
+ self.intel_prefix = os.path.join(prefix, "pkg")
+ IntelInstaller.install(self, spec, prefix)
+
+ daal_dir = os.path.join(self.intel_prefix, "daal")
+ for f in os.listdir(daal_dir):
+ os.symlink(os.path.join(daal_dir, f), os.path.join(self.prefix, f))
diff --git a/var/spack/repos/builtin/packages/espresso/package.py b/var/spack/repos/builtin/packages/espresso/package.py
index ef6a3ccc7b..447964f286 100644
--- a/var/spack/repos/builtin/packages/espresso/package.py
+++ b/var/spack/repos/builtin/packages/espresso/package.py
@@ -26,20 +26,28 @@ from spack import *
import os
+
class Espresso(Package):
"""
- QE is an integrated suite of Open-Source computer codes for electronic-structure calculations and materials
- modeling at the nanoscale. It is based on density-functional theory, plane waves, and pseudopotentials.
+ QE is an integrated suite of Open-Source computer codes for
+ electronic-structure calculations and materials modeling at
+ the nanoscale. It is based on density-functional theory, plane
+ waves, and pseudopotentials.
"""
homepage = 'http://quantum-espresso.org'
url = 'http://www.qe-forge.org/gf/download/frsrelease/204/912/espresso-5.3.0.tar.gz'
+ version(
+ '5.4.0',
+ '8bb78181b39bd084ae5cb7a512c1cfe7',
+ url='http://www.qe-forge.org/gf/download/frsrelease/211/968/espresso-5.4.0.tar.gz'
+ )
version('5.3.0', '6848fcfaeb118587d6be36bd10b7f2c3')
- variant('mpi', default=True, description='Build Quantum-ESPRESSO with mpi support')
+ variant('mpi', default=True, description='Builds with mpi support')
variant('openmp', default=False, description='Enables openMP support')
variant('scalapack', default=True, description='Enables scalapack support')
- variant('elpa', default=True, description='Use elpa as an eigenvalue solver')
+ variant('elpa', default=True, description='Uses elpa as an eigenvalue solver')
depends_on('blas')
depends_on('lapack')
@@ -47,7 +55,12 @@ class Espresso(Package):
depends_on('mpi', when='+mpi')
depends_on('fftw~mpi', when='~mpi')
depends_on('fftw+mpi', when='+mpi')
- depends_on('scalapack', when='+scalapack+mpi') # TODO : + mpi needed to avoid false dependencies installation
+ # TODO : + mpi needed to avoid false dependencies installation
+ depends_on('scalapack', when='+scalapack+mpi')
+
+ # Spurious problems running in parallel the Makefile
+ # generated by qe configure
+ parallel = False
def check_variants(self, spec):
error = 'you cannot ask for \'+{variant}\' when \'+mpi\' is not active'
@@ -87,10 +100,9 @@ class Espresso(Package):
configure(*options)
make('all')
- if spec.architecture.startswith('darwin'):
+ if spec.satisfies('platform=darwin'):
mkdirp(prefix.bin)
for filename in glob("bin/*.x"):
install(filename, prefix.bin)
else:
make('install')
-
diff --git a/var/spack/repos/builtin/packages/hdf5-blosc/package.py b/var/spack/repos/builtin/packages/hdf5-blosc/package.py
new file mode 100644
index 0000000000..50f380083c
--- /dev/null
+++ b/var/spack/repos/builtin/packages/hdf5-blosc/package.py
@@ -0,0 +1,206 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import os
+import shutil
+import sys
+
+from spack import *
+
+def _install_shlib(name, src, dst):
+ """Install a shared library from directory src to directory dst"""
+ if sys.platform == "darwin":
+ shlib0 = name + ".0.dylib"
+ shlib = name + ".dylib"
+ shutil.copyfile(join_path(src, shlib0), join_path(dst, shlib0))
+ os.symlink(shlib0, join_path(dst, shlib))
+ else:
+ shlib000 = name + ".so.0.0.0"
+ shlib0 = name + ".so.0"
+ shlib = name + ".dylib"
+ shutil.copyfile(join_path(src, shlib000), join_path(dst, shlib000))
+ os.symlink(shlib000, join_path(dst, shlib0))
+ os.symlink(shlib0, join_path(dst, shlib))
+
+class Hdf5Blosc(Package):
+ """Blosc filter for HDF5"""
+ homepage = "https://github.com/Blosc/hdf5-blosc"
+ url = "https://github.com/Blosc/hdf5-blosc/archive/master.zip"
+
+ version('master', '02c04acbf4bec66ec8a35bf157d1c9de')
+
+ depends_on("c-blosc")
+ depends_on("hdf5")
+ depends_on("libtool")
+
+ parallel = False
+
+ def install(self, spec, prefix):
+ # The included cmake recipe doesn"t work for Darwin
+ # cmake(".", *std_cmake_args)
+ #
+ # make()
+ # make("install")
+ # if sys.platform == "darwin":
+ # fix_darwin_install_name(prefix.lib)
+
+ libtool = Executable(join_path(spec["libtool"].prefix.bin, "libtool"))
+ if "+mpi" in spec["hdf5"]:
+ cc = "mpicc"
+ else:
+ cc = "cc"
+ shlibext = "so" if sys.platform!="darwin" else "dylib"
+ mkdirp(prefix.include)
+ mkdirp(prefix.lib)
+
+ # Build and install filter
+ with working_dir("src"):
+ libtool("--mode=compile", "--tag=CC",
+ "cc", "-g", "-O",
+ "-c", "blosc_filter.c")
+ libtool("--mode=link", "--tag=CC",
+ "cc", "-g", "-O",
+ "-rpath", prefix.lib,
+ "-o", "libblosc_filter.la",
+ "blosc_filter.lo",
+ "-L%s" % spec["c-blosc"].prefix.lib, "-lblosc",
+ "-L%s" % spec["hdf5"].prefix.lib, "-lhdf5")
+ _install_shlib("libblosc_filter", ".libs", prefix.lib)
+
+ # Build and install plugin
+ # The plugin requires at least HDF5 1.8.11:
+ if spec["hdf5"].satisfies("@1.8.11:"):
+ libtool("--mode=compile", "--tag=CC",
+ "cc", "-g", "-O",
+ "-c", "blosc_plugin.c")
+ libtool("--mode=link", "--tag=CC",
+ "cc", "-g", "-O",
+ "-rpath", prefix.lib,
+ "-o", "libblosc_plugin.la",
+ "blosc_plugin.lo",
+ "-L%s" % prefix.lib, "-lblosc_filter",
+ "-L%s" % spec["c-blosc"].prefix.lib, "-lblosc",
+ "-L%s" % spec["hdf5"].prefix.lib, "-lhdf5")
+ _install_shlib("libblosc_plugin", ".libs", prefix.lib)
+
+ self.check_install(spec)
+
+ def check_install(self, spec):
+ "Build and run a small program to test the installed HDF5 Blosc plugin"
+ print "Checking HDF5-Blosc plugin..."
+ checkdir = "spack-check"
+ with working_dir(checkdir, create=True):
+ source = r"""\
+#include <hdf5.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define FILTER_BLOSC 32001 /* Blosc filter ID registered with the HDF group */
+
+int main(int argc, char **argv) {
+ herr_t herr;
+ hid_t file = H5Fcreate("file.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ assert(file >= 0);
+ hsize_t dims[3] = {10, 10, 10};
+ hid_t space = H5Screate_simple(3, dims, NULL);
+ assert(space >= 0);
+ hid_t create_proplist = H5Pcreate(H5P_DATASET_CREATE);
+ assert(create_proplist >= 0);
+ herr = H5Pset_chunk(create_proplist, 3, dims);
+ assert(herr >= 0);
+ herr = H5Pset_filter(create_proplist, FILTER_BLOSC, H5Z_FLAG_OPTIONAL, 0,
+ NULL);
+ assert(herr >= 0);
+ htri_t all_filters_avail = H5Pall_filters_avail(create_proplist);
+ assert(all_filters_avail > 0);
+ hid_t dataset = H5Dcreate(file, "dataset", H5T_NATIVE_DOUBLE, space,
+ H5P_DEFAULT, create_proplist, H5P_DEFAULT);
+ assert(dataset >= 0);
+ double data[10][10][10];
+ for (int k=0; k<10; ++k) {
+ for (int j=0; j<10; ++j) {
+ for (int i=0; i<10; ++i) {
+ data[k][j][i] = 1.0 / (1.0 + i + j + k);
+ }
+ }
+ }
+ herr = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, space, space, H5P_DEFAULT,
+ &data[0][0][0]);
+ assert(herr >= 0);
+ herr = H5Pclose(create_proplist);
+ assert(herr >= 0);
+ herr = H5Dclose(dataset);
+ assert(herr >= 0);
+ herr = H5Sclose(space);
+ assert(herr >= 0);
+ herr = H5Fclose(file);
+ assert(herr >= 0);
+ printf("Done.\n");
+ return 0;
+}
+"""
+ expected = """\
+Done.
+"""
+ with open("check.c", "w") as f:
+ f.write(source)
+ if "+mpi" in spec["hdf5"]:
+ cc = which("mpicc")
+ else:
+ cc = which("cc")
+ # TODO: Automate these path and library settings
+ cc("-c", "-I%s" % spec["hdf5"].prefix.include, "check.c")
+ cc("-o", "check", "check.o",
+ "-L%s" % spec["hdf5"].prefix.lib, "-lhdf5")
+ try:
+ check = Executable("./check")
+ output = check(return_output=True)
+ except:
+ output = ""
+ success = output == expected
+ if not success:
+ print "Produced output does not match expected output."
+ print "Expected output:"
+ print "-"*80
+ print expected
+ print "-"*80
+ print "Produced output:"
+ print "-"*80
+ print output
+ print "-"*80
+ print "Environment:"
+ env = which("env")
+ env()
+ raise RuntimeError("HDF5 Blosc plugin check failed")
+ shutil.rmtree(checkdir)
+
+ def setup_environment(self, spack_env, run_env):
+ spack_env.append_path("HDF5_PLUGIN_PATH", self.spec.prefix.lib)
+ run_env.append_path("HDF5_PLUGIN_PATH", self.spec.prefix.lib)
+
+ def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
+ spack_env.append_path("HDF5_PLUGIN_PATH", self.spec.prefix.lib)
+ run_env.append_path("HDF5_PLUGIN_PATH", self.spec.prefix.lib)
diff --git a/var/spack/repos/builtin/packages/hpl/package.py b/var/spack/repos/builtin/packages/hpl/package.py
new file mode 100644
index 0000000000..efd5c8bb1d
--- /dev/null
+++ b/var/spack/repos/builtin/packages/hpl/package.py
@@ -0,0 +1,119 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+import os
+import platform
+
+
+class Hpl(Package):
+ """HPL is a software package that solves a (random) dense linear system
+ in double precision (64 bits) arithmetic on distributed-memory computers.
+ It can thus be regarded as a portable as well as freely available
+ implementation of the High Performance Computing Linpack Benchmark."""
+
+ homepage = "http://www.netlib.org/benchmark/hpl/"
+ url = "http://www.netlib.org/benchmark/hpl/hpl-2.2.tar.gz"
+
+ version('2.2', '0eb19e787c3dc8f4058db22c9e0c5320')
+
+ variant('openmp', default=False, description='Enable OpenMP support')
+
+ depends_on('mpi@1.1:')
+ depends_on('blas')
+
+ parallel = False
+
+ def configure(self, spec, arch):
+ # List of configuration options
+ # Order is important
+ config = []
+
+ # OpenMP support
+ if '+openmp' in spec:
+ config.append(
+ 'OMP_DEFS = {0}'.format(self.compiler.openmp_flag)
+ )
+
+ config.extend([
+ # Shell
+ 'SHELL = /bin/sh',
+ 'CD = cd',
+ 'CP = cp',
+ 'LN_S = ln -fs',
+ 'MKDIR = mkdir -p',
+ 'RM = /bin/rm -f',
+ 'TOUCH = touch',
+ # Platform identifier
+ 'ARCH = {0}'.format(arch),
+ # HPL Directory Structure / HPL library
+ 'TOPdir = {0}'.format(os.getcwd()),
+ 'INCdir = $(TOPdir)/include',
+ 'BINdir = $(TOPdir)/bin/$(ARCH)',
+ 'LIBdir = $(TOPdir)/lib/$(ARCH)',
+ 'HPLlib = $(LIBdir)/libhpl.a',
+ # Message Passing library (MPI)
+ 'MPinc = -I{0}'.format(spec['mpi'].prefix.include),
+ 'MPlib = -L{0}'.format(spec['mpi'].prefix.lib),
+ # Linear Algebra library (BLAS or VSIPL)
+ 'LAinc = {0}'.format(spec['blas'].prefix.include),
+ 'LAlib = {0}'.format(spec['blas'].blas_shared_lib),
+ # F77 / C interface
+ 'F2CDEFS = -DAdd_ -DF77_INTEGER=int -DStringSunStyle',
+ # HPL includes / libraries / specifics
+ 'HPL_INCLUDES = -I$(INCdir) -I$(INCdir)/$(ARCH) ' +
+ '-I$(LAinc) -I$(MPinc)',
+ 'HPL_LIBS = $(HPLlib) $(LAlib) $(MPlib)',
+ 'HPL_OPTS = -DHPL_DETAILED_TIMING -DHPL_PROGRESS_REPORT',
+ 'HPL_DEFS = $(F2CDEFS) $(HPL_OPTS) $(HPL_INCLUDES)',
+ # Compilers / linkers - Optimization flags
+ 'CC = {0}'.format(spec['mpi'].mpicc),
+ 'CCNOOPT = $(HPL_DEFS)',
+ 'CCFLAGS = $(HPL_DEFS) -O3',
+ 'LINKER = $(CC)',
+ 'LINKFLAGS = $(CCFLAGS) $(OMP_DEFS)',
+ 'ARCHIVER = ar',
+ 'ARFLAGS = r',
+ 'RANLIB = echo'
+ ])
+
+ # Write configuration options to include file
+ with open('Make.{0}'.format(arch), 'w') as makefile:
+ for var in config:
+ makefile.write('{0}\n'.format(var))
+
+ def install(self, spec, prefix):
+ # Arch used for file naming purposes only
+ arch = '{0}-{1}'.format(platform.system(), platform.processor())
+
+ # Generate Makefile include
+ self.configure(spec, arch)
+
+ make('arch={0}'.format(arch))
+
+ # Manual installation
+ install_tree(join_path('bin', arch), prefix.bin)
+ install_tree(join_path('lib', arch), prefix.lib)
+ install_tree(join_path('include', arch), prefix.include)
+ install_tree('man', prefix.man)
diff --git a/var/spack/repos/builtin/packages/intel-parallel-studio/package.py b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py
new file mode 100644
index 0000000000..493ca16417
--- /dev/null
+++ b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py
@@ -0,0 +1,144 @@
+from spack import *
+import os
+import re
+
+from spack.pkg.builtin.intel import IntelInstaller, filter_pick, \
+ get_all_components
+
+
+class IntelParallelStudio(IntelInstaller):
+ """Intel Parallel Studio.
+
+ Note: You will have to add the download file to a
+ mirror so that Spack can find it. For instructions on how to set up a
+ mirror, see http://software.llnl.gov/spack/mirrors.html"""
+
+ homepage = "https://software.intel.com/en-us/intel-parallel-studio-xe"
+
+ # TODO: can also try the online installer (will download files on demand)
+ version('composer.2016.2', '1133fb831312eb519f7da897fec223fa',
+ url="file://%s/parallel_studio_xe_2016_composer_edition_update2.tgz" # NOQA: ignore=E501
+ % os.getcwd())
+ version('professional.2016.2', '70be832f2d34c9bf596a5e99d5f2d832',
+ url="file://%s/parallel_studio_xe_2016_update2.tgz" % os.getcwd()) # NOQA: ignore=E501
+ version('cluster.2016.2', '70be832f2d34c9bf596a5e99d5f2d832',
+ url="file://%s/parallel_studio_xe_2016_update2.tgz" % os.getcwd()) # NOQA: ignore=E501
+ version('composer.2016.3', '3208eeabee951fc27579177b593cefe9',
+ url="file://%s/parallel_studio_xe_2016_composer_edition_update3.tgz" # NOQA: ignore=E501
+ % os.getcwd())
+ version('professional.2016.3', 'eda19bb0d0d19709197ede58f13443f3',
+ url="file://%s/parallel_studio_xe_2016_update3.tgz" % os.getcwd()) # NOQA: ignore=E501
+ version('cluster.2016.3', 'eda19bb0d0d19709197ede58f13443f3',
+ url="file://%s/parallel_studio_xe_2016_update3.tgz" % os.getcwd()) # NOQA: ignore=E501
+
+ variant('rpath', default=True, description="Add rpath to .cfg files")
+ variant('newdtags', default=False,
+ description="Allow use of --enable-new-dtags in MPI wrappers")
+ variant('all', default=False,
+ description="Install all files with the requested edition")
+ variant('mpi', default=True,
+ description="Install the Intel MPI library and ITAC tool")
+ variant('mkl', default=True, description="Install the Intel MKL library")
+ variant('daal',
+ default=True, description="Install the Intel DAAL libraries")
+ variant('ipp', default=True, description="Install the Intel IPP libraries")
+ variant('tools', default=True, description="""Install the Intel Advisor,\
+VTune Amplifier, and Inspector tools""")
+
+ provides('mpi', when='@cluster:+mpi')
+ provides('mkl', when='+mkl')
+ provides('daal', when='+daal')
+ provides('ipp', when='+ipp')
+
+ def install(self, spec, prefix):
+
+ base_components = "ALL" # when in doubt, install everything
+ mpi_components = ""
+ mkl_components = ""
+ daal_components = ""
+ ipp_components = ""
+
+ if spec.satisfies('+all'):
+ base_components = "ALL"
+ else:
+ all_components = get_all_components()
+ regex = '(comp|openmp|intel-tbb|icc|ifort|psxe|icsxe-pset)'
+ base_components = \
+ filter_pick(all_components, re.compile(regex).search)
+ regex = '(icsxe|imb|mpi|itac|intel-tc|clck)'
+ mpi_components = \
+ filter_pick(all_components, re.compile(regex).search)
+ mkl_components = \
+ filter_pick(all_components, re.compile('(mkl)').search)
+ daal_components = \
+ filter_pick(all_components, re.compile('(daal)').search)
+ ipp_components = \
+ filter_pick(all_components, re.compile('(ipp)').search)
+ regex = '(gdb|vtune|inspector|advisor)'
+ tool_components = \
+ filter_pick(all_components, re.compile(regex).search)
+
+ components = base_components
+ if not spec.satisfies('+all'):
+ if spec.satisfies('+mpi') and 'cluster' in str(spec.version):
+ components += mpi_components
+ if spec.satisfies('+mkl'):
+ components += mkl_components
+ if spec.satisfies('+daal'):
+ components += daal_components
+ if spec.satisfies('+ipp'):
+ components += ipp_components
+ if spec.satisfies('+tools') and (spec.satisfies('@cluster') or
+ spec.satisfies('@professional')):
+ components += tool_components
+
+ self.intel_components = ';'.join(components)
+ IntelInstaller.install(self, spec, prefix)
+
+ absbindir = os.path.dirname(os.path.realpath(os.path.join(
+ self.prefix.bin, "icc")))
+ abslibdir = os.path.dirname(os.path.realpath(os.path.join
+ (self.prefix.lib, "intel64", "libimf.a")))
+
+ os.symlink(self.global_license_file, os.path.join(absbindir,
+ "license.lic"))
+ if spec.satisfies('+tools') and (spec.satisfies('@cluster') or
+ spec.satisfies('@professional')):
+ os.mkdir(os.path.join(self.prefix, "inspector_xe/licenses"))
+ os.symlink(self.global_license_file, os.path.join(
+ self.prefix, "inspector_xe/licenses", "license.lic"))
+ os.mkdir(os.path.join(self.prefix, "advisor_xe/licenses"))
+ os.symlink(self.global_license_file, os.path.join(
+ self.prefix, "advisor_xe/licenses", "license.lic"))
+ os.mkdir(os.path.join(self.prefix, "vtune_amplifier_xe/licenses"))
+ os.symlink(self.global_license_file, os.path.join(
+ self.prefix, "vtune_amplifier_xe/licenses", "license.lic"))
+
+ if (spec.satisfies('+all') or spec.satisfies('+mpi')) and \
+ spec.satisfies('@cluster'):
+ os.symlink(self.global_license_file, os.path.join(
+ self.prefix, "itac_latest", "license.lic"))
+ if spec.satisfies('~newdtags'):
+ wrappers = ["mpif77", "mpif77", "mpif90", "mpif90",
+ "mpigcc", "mpigcc", "mpigxx", "mpigxx",
+ "mpiicc", "mpiicc", "mpiicpc", "mpiicpc",
+ "mpiifort", "mpiifort"]
+ wrapper_paths = []
+ for root, dirs, files in os.walk(spec.prefix):
+ for name in files:
+ if name in wrappers:
+ wrapper_paths.append(os.path.join(spec.prefix,
+ root, name))
+ for wrapper in wrapper_paths:
+ filter_file(r'-Xlinker --enable-new-dtags', r' ',
+ wrapper)
+
+ if spec.satisfies('+rpath'):
+ for compiler_command in ["icc", "icpc", "ifort"]:
+ cfgfilename = os.path.join(absbindir, "%s.cfg" %
+ compiler_command)
+ with open(cfgfilename, "w") as f:
+ f.write('-Xlinker -rpath -Xlinker %s\n' % abslibdir)
+
+ os.symlink(os.path.join(self.prefix.man, "common", "man1"),
+ os.path.join(self.prefix.man, "man1"))
diff --git a/var/spack/repos/builtin/packages/intel/package.py b/var/spack/repos/builtin/packages/intel/package.py
new file mode 100644
index 0000000000..ec3192380a
--- /dev/null
+++ b/var/spack/repos/builtin/packages/intel/package.py
@@ -0,0 +1,125 @@
+from spack import *
+import os
+import re
+
+
+def filter_pick(input_list, regex_filter):
+ """Returns the items in input_list that are found in the regex_filter"""
+ return [l for l in input_list for m in (regex_filter(l),) if m]
+
+
+def unfilter_pick(input_list, regex_filter):
+ """Returns the items in input_list that are not found in the
+ regex_filter"""
+ return [l for l in input_list for m in (regex_filter(l),) if not m]
+
+
+def get_all_components():
+ """Returns a list of all the components associated with the downloaded
+ Intel package"""
+ all_components = []
+ with open("pset/mediaconfig.xml", "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ if line.find('<Abbr>') != -1:
+ component = line[line.find('<Abbr>') + 6:line.find('</Abbr>')]
+ all_components.append(component)
+ return all_components
+
+
+class IntelInstaller(Package):
+ """Base package containing common methods for installing Intel software"""
+
+ homepage = "https://software.intel.com/en-us"
+ intel_components = "ALL"
+ license_required = True
+ license_comment = '#'
+ license_files = ['Licenses/license.lic']
+ license_vars = ['INTEL_LICENSE_FILE']
+ license_url = \
+ 'https://software.intel.com/en-us/articles/intel-license-manager-faq'
+
+ @property
+ def global_license_file(self):
+ """Returns the path where a global license file should be stored."""
+ if not self.license_files:
+ return
+ return join_path(self.global_license_dir, "intel",
+ os.path.basename(self.license_files[0]))
+
+ def install(self, spec, prefix):
+
+ # Remove the installation DB, otherwise it will try to install into
+ # location of other Intel builds
+ if os.path.exists(os.path.join(os.environ["HOME"], "intel",
+ "intel_sdp_products.db")):
+ os.remove(os.path.join(os.environ["HOME"], "intel",
+ "intel_sdp_products.db"))
+
+ if not hasattr(self, "intel_prefix"):
+ self.intel_prefix = self.prefix
+
+ silent_config_filename = 'silent.cfg'
+ with open(silent_config_filename, 'w') as f:
+ f.write("""
+ACCEPT_EULA=accept
+PSET_MODE=install
+CONTINUE_WITH_INSTALLDIR_OVERWRITE=yes
+PSET_INSTALL_DIR=%s
+ACTIVATION_LICENSE_FILE=%s
+ACTIVATION_TYPE=license_file
+PHONEHOME_SEND_USAGE_DATA=no
+CONTINUE_WITH_OPTIONAL_ERROR=yes
+COMPONENTS=%s
+""" % (self.intel_prefix, self.global_license_file, self.intel_components))
+
+ install_script = which("install.sh")
+ install_script('--silent', silent_config_filename)
+
+
+class Intel(IntelInstaller):
+ """Intel Compilers.
+
+ Note: You will have to add the download file to a
+ mirror so that Spack can find it. For instructions on how to set up a
+ mirror, see http://software.llnl.gov/spack/mirrors.html"""
+
+ homepage = "https://software.intel.com/en-us/intel-parallel-studio-xe"
+
+ # TODO: can also try the online installer (will download files on demand)
+ version('16.0.2', '1133fb831312eb519f7da897fec223fa',
+ url="file://%s/parallel_studio_xe_2016_composer_edition_update2.tgz" # NOQA: ignore=E501
+ % os.getcwd())
+ version('16.0.3', '3208eeabee951fc27579177b593cefe9',
+ url="file://%s/parallel_studio_xe_2016_composer_edition_update3.tgz" # NOQA: ignore=E501
+ % os.getcwd())
+
+ variant('rpath', default=True, description="Add rpath to .cfg files")
+
+ def install(self, spec, prefix):
+ components = []
+ all_components = get_all_components()
+ regex = '(comp|openmp|intel-tbb|icc|ifort|psxe|icsxe-pset)'
+ components = filter_pick(all_components, re.compile(regex).search)
+
+ self.intel_components = ';'.join(components)
+ IntelInstaller.install(self, spec, prefix)
+
+ absbindir = os.path.split(os.path.realpath(os.path.join(
+ self.prefix.bin, "icc")))[0]
+ abslibdir = os.path.split(os.path.realpath(os.path.join(
+ self.prefix.lib, "intel64", "libimf.a")))[0]
+
+ # symlink or copy?
+ os.symlink(self.global_license_file, os.path.join(absbindir,
+ "license.lic"))
+
+ if spec.satisfies('+rpath'):
+ for compiler_command in ["icc", "icpc", "ifort"]:
+ cfgfilename = os.path.join(absbindir, "%s.cfg" %
+ compiler_command)
+ with open(cfgfilename, "w") as f:
+ f.write('-Xlinker -rpath -Xlinker %s\n' % abslibdir)
+
+ os.symlink(os.path.join(self.prefix.man, "common", "man1"),
+ os.path.join(self.prefix.man, "man1"))
diff --git a/var/spack/repos/builtin/packages/ipp/package.py b/var/spack/repos/builtin/packages/ipp/package.py
new file mode 100644
index 0000000000..2bd931d5bd
--- /dev/null
+++ b/var/spack/repos/builtin/packages/ipp/package.py
@@ -0,0 +1,26 @@
+from spack import *
+import os
+
+from spack.pkg.builtin.intel import IntelInstaller
+
+
+class Ipp(IntelInstaller):
+ """Intel Integrated Performance Primitives.
+
+ Note: You will have to add the download file to a
+ mirror so that Spack can find it. For instructions on how to set up a
+ mirror, see http://software.llnl.gov/spack/mirrors.html"""
+
+ homepage = "https://software.intel.com/en-us/intel-ipp"
+
+ version('9.0.3.210', '0e1520dd3de7f811a6ef6ebc7aa429a3',
+ url="file://%s/l_ipp_9.0.3.210.tgz" % os.getcwd())
+
+ def install(self, spec, prefix):
+
+ self.intel_prefix = os.path.join(prefix, "pkg")
+ IntelInstaller.install(self, spec, prefix)
+
+ ipp_dir = os.path.join(self.intel_prefix, "ipp")
+ for f in os.listdir(ipp_dir):
+ os.symlink(os.path.join(ipp_dir, f), os.path.join(self.prefix, f))
diff --git a/var/spack/repos/builtin/packages/libpciaccess/package.py b/var/spack/repos/builtin/packages/libpciaccess/package.py
index 42e8711a7d..91cef95cec 100644
--- a/var/spack/repos/builtin/packages/libpciaccess/package.py
+++ b/var/spack/repos/builtin/packages/libpciaccess/package.py
@@ -37,7 +37,7 @@ class Libpciaccess(Package):
def install(self, spec, prefix):
# libpciaccess does not support OS X
- if spec.satisfies('arch=darwin-x86_64'):
+ if spec.satisfies('platform=darwin'):
# create a dummy directory
mkdir(prefix.lib)
return
diff --git a/var/spack/repos/builtin/packages/libpthread-stubs/package.py b/var/spack/repos/builtin/packages/libpthread-stubs/package.py
new file mode 100644
index 0000000000..4bcca43c24
--- /dev/null
+++ b/var/spack/repos/builtin/packages/libpthread-stubs/package.py
@@ -0,0 +1,39 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+class LibpthreadStubs(Package):
+ """The libpthread-stubs package provides weak aliases for pthread
+ functions not provided in libc or otherwise available by
+ default. """
+ homepage = "http://xcb.freedesktop.org/"
+ url = "http://xcb.freedesktop.org/dist/libpthread-stubs-0.1.tar.bz2"
+
+ version('0.3', 'e8fa31b42e13f87e8f5a7a2b731db7ee')
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix)
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/libxau/package.py b/var/spack/repos/builtin/packages/libxau/package.py
new file mode 100644
index 0000000000..55816ecdbd
--- /dev/null
+++ b/var/spack/repos/builtin/packages/libxau/package.py
@@ -0,0 +1,44 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+class Libxau(Package):
+ """The libXau package contains a library implementing the X11
+ Authorization Protocol. This is useful for restricting client
+ access to the display."""
+ homepage = "http://xcb.freedesktop.org/"
+ url = "http://ftp.x.org/pub/individual/lib/libXau-1.0.8.tar.bz2"
+
+ version('1.0.8', '685f8abbffa6d145c0f930f00703b21b')
+
+ depends_on('xproto')
+
+ def install(self, spec, prefix):
+ # FIXME: Modify the configure line to suit your build system here.
+ configure('--prefix=%s' % prefix)
+
+ # FIXME: Add logic to build and install here
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/libxcb/package.py b/var/spack/repos/builtin/packages/libxcb/package.py
index 0f39bb0f1d..746d4567e2 100644
--- a/var/spack/repos/builtin/packages/libxcb/package.py
+++ b/var/spack/repos/builtin/packages/libxcb/package.py
@@ -35,18 +35,19 @@ class Libxcb(Package):
version('1.11', '1698dd837d7e6e94d029dbe8b3a82deb')
version('1.11.1', '118623c15a96b08622603a71d8789bf3')
+
depends_on("python")
depends_on("xcb-proto")
depends_on("pkg-config")
-
- # depends_on('pthread') # Ubuntu: apt-get install libpthread-stubs0-dev
- # depends_on('xau') # Ubuntu: apt-get install libxau-dev
+ depends_on("libpthread-stubs")
+ depends_on('libxau')
def patch(self):
filter_file('typedef struct xcb_auth_info_t {', 'typedef struct {', 'src/xcb.h')
def install(self, spec, prefix):
+ env['PKG_CONFIG_PATH'] = env['PKG_CONFIG_PATH'] + ':/usr/lib64/pkgconfig'
configure("--prefix=%s" % prefix)
make()
diff --git a/var/spack/repos/builtin/packages/llvm/package.py b/var/spack/repos/builtin/packages/llvm/package.py
index c32f66590a..7a6ea7401c 100644
--- a/var/spack/repos/builtin/packages/llvm/package.py
+++ b/var/spack/repos/builtin/packages/llvm/package.py
@@ -267,16 +267,16 @@ class Llvm(Package):
if '+all_targets' not in spec: # all is default on cmake
targets = ['CppBackend', 'NVPTX', 'AMDGPU']
- if 'x86' in spec.architecture.lower():
+ if 'x86' in spec.architecture.target.lower():
targets.append('X86')
- elif 'arm' in spec.architecture.lower():
+ elif 'arm' in spec.architecture.target.lower():
targets.append('ARM')
- elif 'aarch64' in spec.architecture.lower():
+ elif 'aarch64' in spec.architecture.target.lower():
targets.append('AArch64')
- elif 'sparc' in spec.architecture.lower():
+ elif 'sparc' in spec.architecture.target.lower():
targets.append('sparc')
- elif ('ppc' in spec.architecture.lower() or
- 'power' in spec.architecture.lower()):
+ elif ('ppc' in spec.architecture.target.lower() or
+ 'power' in spec.architecture.target.lower()):
targets.append('PowerPC')
cmake_args.append('-DLLVM_TARGETS_TO_BUILD:Bool=' + ';'.join(targets))
diff --git a/var/spack/repos/builtin/packages/lmod/package.py b/var/spack/repos/builtin/packages/lmod/package.py
index 0a8b9b4577..7d75866d52 100644
--- a/var/spack/repos/builtin/packages/lmod/package.py
+++ b/var/spack/repos/builtin/packages/lmod/package.py
@@ -23,7 +23,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *
-import os
+
class Lmod(Package):
"""
@@ -34,17 +34,25 @@ class Lmod(Package):
variable. Modulefiles for Library packages provide environment variables
that specify where the library and header files can be found.
"""
- homepage = "https://www.tacc.utexas.edu/research-development/tacc-projects/lmod"
- url = "http://sourceforge.net/projects/lmod/files/Lmod-6.0.1.tar.bz2/download"
+ homepage = 'https://www.tacc.utexas.edu/research-development/tacc-projects/lmod' # NOQA: ignore=E501
+ url = 'https://github.com/TACC/Lmod/archive/6.4.1.tar.gz'
+ version('6.4.1', '7978ba777c8aa41a4d8c05fec5f780f4')
+ version('6.3.7', '0fa4d5a24c41cae03776f781aa2dedc1')
version('6.0.1', '91abf52fe5033bd419ffe2842ebe7af9')
- depends_on("lua@5.2:")
+ depends_on('lua@5.2:')
+ depends_on('lua-luaposix')
+ depends_on('lua-luafilesystem')
+
+ parallel = False
+
+ def setup_environment(self, spack_env, run_env):
+ stage_lua_path = join_path(
+ self.stage.path, 'Lmod-{version}', 'src', '?.lua')
+ spack_env.append_path('LUA_PATH', stage_lua_path.format(
+ version=self.version), separator=';')
def install(self, spec, prefix):
- # Add our lua to PATH
- os.environ['PATH'] = spec['lua'].prefix.bin + ';' + os.environ['PATH']
-
configure('--prefix=%s' % prefix)
- make()
- make("install")
+ make('install')
diff --git a/var/spack/repos/builtin/packages/lua-luafilesystem/package.py b/var/spack/repos/builtin/packages/lua-luafilesystem/package.py
new file mode 100644
index 0000000000..a61b9dd675
--- /dev/null
+++ b/var/spack/repos/builtin/packages/lua-luafilesystem/package.py
@@ -0,0 +1,51 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class LuaLuafilesystem(Package):
+ """
+ LuaFileSystem is a Lua library developed to complement the set of
+ functions related to file systems offered by the standard Lua distribution.
+
+ LuaFileSystem offers a portable way to access the underlying directory
+ structure and file attributes.
+
+ LuaFileSystem is free software and uses the same license as Lua 5.1
+ """
+ homepage = 'http://keplerproject.github.io/luafilesystem'
+ url = 'https://github.com/keplerproject/luafilesystem/archive/v_1_6_3.tar.gz'
+
+ version('1_6_3', 'd0552c7e5a082f5bb2865af63fb9dc95')
+
+ extends('lua')
+
+ def install(self, spec, prefix):
+ rockspec_fmt = join_path(self.stage.path,
+ 'luafilesystem-v_{version.underscored}',
+ 'rockspecs',
+ 'luafilesystem-{version.dotted}-1.rockspec')
+ luarocks('--tree=' + prefix, 'install',
+ rockspec_fmt.format(version=self.spec.version))
diff --git a/var/spack/repos/builtin/packages/lua/package.py b/var/spack/repos/builtin/packages/lua/package.py
index 170f90516a..761932361b 100644
--- a/var/spack/repos/builtin/packages/lua/package.py
+++ b/var/spack/repos/builtin/packages/lua/package.py
@@ -57,7 +57,7 @@ class Lua(Package):
placement='luarocks')
def install(self, spec, prefix):
- if spec.satisfies("arch=darwin-i686") or spec.satisfies("arch=darwin-x86_64"):
+ if spec.satisfies("platform=darwin"):
target = 'macosx'
else:
target = 'linux'
@@ -105,6 +105,9 @@ class Lua(Package):
spack_env.set('LUA_PATH', ';'.join(lua_patterns), separator=';')
spack_env.set('LUA_CPATH', ';'.join(lua_cpatterns), separator=';')
+ # Add LUA to PATH for dependent packages
+ spack_env.prepend_path('PATH', self.prefix.bin)
+
# For run time environment set only the path for extension_spec and
# prepend it to LUAPATH
if extension_spec.package.extends(self.spec):
@@ -153,5 +156,5 @@ class Lua(Package):
"""
# Lua extension builds can have lua and luarocks executable functions
module.lua = Executable(join_path(self.spec.prefix.bin, 'lua'))
- module.luarocks = Executable(join_path(self.spec.prefix.bin,
- 'luarocks'))
+ module.luarocks = Executable(
+ join_path(self.spec.prefix.bin, 'luarocks'))
diff --git a/var/spack/repos/builtin/packages/mkl/package.py b/var/spack/repos/builtin/packages/mkl/package.py
new file mode 100644
index 0000000000..454e78d29c
--- /dev/null
+++ b/var/spack/repos/builtin/packages/mkl/package.py
@@ -0,0 +1,28 @@
+from spack import *
+import os
+
+from spack.pkg.builtin.intel import IntelInstaller
+
+
+class Mkl(IntelInstaller):
+ """Intel Math Kernel Library.
+
+ Note: You will have to add the download file to a
+ mirror so that Spack can find it. For instructions on how to set up a
+ mirror, see http://software.llnl.gov/spack/mirrors.html"""
+
+ homepage = "https://software.intel.com/en-us/intel-mkl"
+
+ version('11.3.2.181', '536dbd82896d6facc16de8f961d17d65',
+ url="file://%s/l_mkl_11.3.2.181.tgz" % os.getcwd())
+ version('11.3.3.210', 'f72546df27f5ebb0941b5d21fd804e34',
+ url="file://%s/l_mkl_11.3.3.210.tgz" % os.getcwd())
+
+ def install(self, spec, prefix):
+
+ self.intel_prefix = os.path.join(prefix, "pkg")
+ IntelInstaller.install(self, spec, prefix)
+
+ mkl_dir = os.path.join(self.intel_prefix, "mkl")
+ for f in os.listdir(mkl_dir):
+ os.symlink(os.path.join(mkl_dir, f), os.path.join(self.prefix, f))
diff --git a/var/spack/repos/builtin/packages/openmpi/package.py b/var/spack/repos/builtin/packages/openmpi/package.py
index 4e465e1784..0638628a6c 100644
--- a/var/spack/repos/builtin/packages/openmpi/package.py
+++ b/var/spack/repos/builtin/packages/openmpi/package.py
@@ -142,7 +142,7 @@ class Openmpi(Package):
])
if '+verbs' in spec:
path = _verbs_dir()
- if path is not None:
+ if path is not None and path not in ('/usr', '/usr/local'):
config_args.append('--with-%s=%s' % (self.verbs, path))
else:
config_args.append('--with-%s' % self.verbs)
diff --git a/var/spack/repos/builtin/packages/openssl/package.py b/var/spack/repos/builtin/packages/openssl/package.py
index 34ab0703ad..377bffe723 100644
--- a/var/spack/repos/builtin/packages/openssl/package.py
+++ b/var/spack/repos/builtin/packages/openssl/package.py
@@ -100,7 +100,7 @@ class Openssl(Package):
# in the environment, then this will override what is set in the
# Makefile, leading to build errors.
env.pop('APPS', None)
- if spec.satisfies("arch=darwin-x86_64") or spec.satisfies("arch=ppc64"):
+ if spec.satisfies("target=x86_64") or spec.satisfies("target=ppc64"):
# This needs to be done for all 64-bit architectures (except Linux,
# where it happens automatically?)
env['KERNEL_BITS'] = '64'
diff --git a/var/spack/repos/builtin/packages/pcre/intel.patch b/var/spack/repos/builtin/packages/pcre/intel.patch
new file mode 100644
index 0000000000..f160f55e1b
--- /dev/null
+++ b/var/spack/repos/builtin/packages/pcre/intel.patch
@@ -0,0 +1,12 @@
+diff -up pcre-8.38/pcrecpp.cc.intel pcre-8.38/pcrecpp.cc
+--- pcre-8.38/pcrecpp.cc.intel 2014-09-15 07:48:59.000000000 -0600
++++ pcre-8.38/pcrecpp.cc 2016-06-08 16:16:56.702721214 -0600
+@@ -66,7 +66,7 @@ Arg RE::no_arg((void*)NULL);
+ // inclusive test if we ever needed it. (Note that not only the
+ // __attribute__ syntax, but also __USER_LABEL_PREFIX__, are
+ // gnu-specific.)
+-#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__)
++#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) && !defined(__INTEL_COMPILER)
+ # define ULP_AS_STRING(x) ULP_AS_STRING_INTERNAL(x)
+ # define ULP_AS_STRING_INTERNAL(x) #x
+ # define USER_LABEL_PREFIX_STR ULP_AS_STRING(__USER_LABEL_PREFIX__)
diff --git a/var/spack/repos/builtin/packages/pcre/package.py b/var/spack/repos/builtin/packages/pcre/package.py
index 7a9f3b911d..8e0f83110e 100644
--- a/var/spack/repos/builtin/packages/pcre/package.py
+++ b/var/spack/repos/builtin/packages/pcre/package.py
@@ -24,6 +24,7 @@
##############################################################################
from spack import *
+
class Pcre(Package):
"""The PCRE package contains Perl Compatible Regular Expression
libraries. These are useful for implementing regular expression
@@ -34,6 +35,8 @@ class Pcre(Package):
version('8.36', 'b767bc9af0c20bc9c1fe403b0d41ad97')
version('8.38', '00aabbfe56d5a48b270f999b508c5ad2')
+ patch("intel.patch")
+
def install(self, spec, prefix):
configure("--prefix=%s" % prefix)
make()
diff --git a/var/spack/repos/builtin/packages/py-astropy/package.py b/var/spack/repos/builtin/packages/py-astropy/package.py
index 86875bbcae..a9962777dc 100644
--- a/var/spack/repos/builtin/packages/py-astropy/package.py
+++ b/var/spack/repos/builtin/packages/py-astropy/package.py
@@ -24,29 +24,38 @@
##############################################################################
from spack import *
+
class PyAstropy(Package):
- """
- The Astropy Project is a community effort to develop a single core
+ """The Astropy Project is a community effort to develop a single core
package for Astronomy in Python and foster interoperability between
- Python astronomy packages.
- """
+ Python astronomy packages."""
+
homepage = 'http://www.astropy.org/'
+ url = 'https://pypi.python.org/packages/source/a/astropy/astropy-1.1.2.tar.gz'
+ version('1.1.2', 'cbe32023b5b1177d1e2498a0d00cda51')
version('1.1.post1', 'b52919f657a37d45cc45f5cb0f58c44d')
- def url_for_version(self, version):
- return 'https://pypi.python.org/packages/source/a/astropy/astropy-{0}.tar.gz'.format(version)
-
+ # Required dependencies
extends('python')
+ depends_on('py-numpy')
- depends_on('cfitsio')
- depends_on('expat')
+ # Optional dependencies
depends_on('py-h5py')
- depends_on('py-numpy')
+ depends_on('py-beautifulsoup4')
+ depends_on('py-pyyaml')
depends_on('py-scipy')
+ depends_on('libxml2')
+ depends_on('py-matplotlib')
+ depends_on('py-pytz')
+ depends_on('py-scikit-image')
+ depends_on('py-pandas')
+
+ # System dependencies
+ depends_on('cfitsio')
+ depends_on('expat')
def install(self, spec, prefix):
python('setup.py', 'build', '--use-system-cfitsio',
- '--use-system-expat')
- python('setup.py', 'install', '--prefix=' + prefix)
-
+ '--use-system-expat')
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/py-beautifulsoup4/package.py b/var/spack/repos/builtin/packages/py-beautifulsoup4/package.py
new file mode 100644
index 0000000000..64368fe70d
--- /dev/null
+++ b/var/spack/repos/builtin/packages/py-beautifulsoup4/package.py
@@ -0,0 +1,41 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class PyBeautifulsoup4(Package):
+ """Beautiful Soup is a Python library for pulling data out of HTML and
+ XML files. It works with your favorite parser to provide idiomatic ways
+ of navigating, searching, and modifying the parse tree."""
+
+ homepage = "https://www.crummy.com/software/BeautifulSoup"
+ url = "https://pypi.python.org/packages/source/b/beautifulsoup4/beautifulsoup4-4.4.1.tar.gz"
+
+ version('4.4.1', '8fbd9a7cac0704645fa20d1419036815')
+
+ extends('python')
+
+ def install(self, spec, prefix):
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/py-emcee/package.py b/var/spack/repos/builtin/packages/py-emcee/package.py
new file mode 100644
index 0000000000..d57ef4bd76
--- /dev/null
+++ b/var/spack/repos/builtin/packages/py-emcee/package.py
@@ -0,0 +1,41 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class PyEmcee(Package):
+ """emcee is an MIT licensed pure-Python implementation of Goodman & Weare's
+ Affine Invariant Markov chain Monte Carlo (MCMC) Ensemble sampler."""
+
+ homepage = "http://dan.iel.fm/emcee/current/"
+ url = "https://pypi.python.org/packages/source/e/emcee/emcee-2.1.0.tar.gz"
+
+ version('2.1.0', 'c6b6fad05c824d40671d4a4fc58dfff7')
+
+ extends('python')
+ depends_on('py-numpy')
+
+ def install(self, spec, prefix):
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/py-h5py/package.py b/var/spack/repos/builtin/packages/py-h5py/package.py
index de72bac44e..0180b658f5 100644
--- a/var/spack/repos/builtin/packages/py-h5py/package.py
+++ b/var/spack/repos/builtin/packages/py-h5py/package.py
@@ -23,21 +23,42 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *
-import re
+
class PyH5py(Package):
- """The h5py package provides both a high- and low-level interface to the HDF5 library from Python."""
+ """The h5py package provides both a high- and low-level interface to the
+ HDF5 library from Python."""
+
homepage = "https://pypi.python.org/pypi/h5py"
url = "https://pypi.python.org/packages/source/h/h5py/h5py-2.4.0.tar.gz"
- version('2.4.0', '80c9a94ae31f84885cc2ebe1323d6758')
+ version('2.6.0', 'ec476211bd1de3f5ac150544189b0bf4')
version('2.5.0', '6e4301b5ad5da0d51b0a1e5ac19e3b74')
+ version('2.4.0', '80c9a94ae31f84885cc2ebe1323d6758')
+
+ variant('mpi', default=False, description='Build with MPI support')
- extends('python', ignore=lambda f: re.match(r'bin/cy*', f))
- depends_on('hdf5')
- depends_on('py-numpy')
- depends_on('py-cython')
+ extends('python')
+
+ # Build dependencies
+ depends_on('py-cython@0.19:')
+ depends_on('pkg-config')
+ depends_on('hdf5@1.8.4:+mpi', when='+mpi')
+ depends_on('hdf5@1.8.4:~mpi', when='~mpi')
+ depends_on('mpi', when='+mpi')
+
+ # Build and runtime dependencies
+ depends_on('py-numpy@1.6.1:')
+
+ # Runtime dependencies
+ depends_on('py-six')
def install(self, spec, prefix):
- python('setup.py', 'configure', '--hdf5=%s' % spec['hdf5'].prefix)
- python('setup.py', 'install', '--prefix=%s' % prefix)
+ python('setup.py', 'configure',
+ '--hdf5={0}'.format(spec['hdf5'].prefix))
+
+ if '+mpi' in spec:
+ env['CC'] = spec['mpi'].mpicc
+ python('setup.py', 'configure', '--mpi')
+
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/py-iminuit/package.py b/var/spack/repos/builtin/packages/py-iminuit/package.py
new file mode 100644
index 0000000000..47751a702d
--- /dev/null
+++ b/var/spack/repos/builtin/packages/py-iminuit/package.py
@@ -0,0 +1,46 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class PyIminuit(Package):
+ """Interactive IPython-Friendly Minimizer based on SEAL Minuit2."""
+
+ homepage = "https://pypi.python.org/pypi/iminuit"
+ url = "https://pypi.python.org/packages/source/i/iminuit/iminuit-1.2.tar.gz"
+
+ version('1.2', '4701ec472cae42015e26251703e6e984')
+
+ # Required dependencies
+ extends('python')
+ depends_on('py-setuptools')
+
+ # Optional dependencies
+ depends_on('py-numpy')
+ depends_on('py-matplotlib')
+ depends_on('py-cython')
+
+ def install(self, spec, prefix):
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/py-nestle/package.py b/var/spack/repos/builtin/packages/py-nestle/package.py
new file mode 100644
index 0000000000..16506e3eca
--- /dev/null
+++ b/var/spack/repos/builtin/packages/py-nestle/package.py
@@ -0,0 +1,44 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class PyNestle(Package):
+ """Nested sampling algorithms for evaluating Bayesian evidence."""
+
+ homepage = "http://kbarbary.github.io/nestle/"
+ url = "https://pypi.python.org/packages/source/n/nestle/nestle-0.1.1.tar.gz"
+
+ version('0.1.1', '4875c0f9a0a8e263c1d7f5fa6ce604c5')
+
+ # Required dependencies
+ extends('python')
+ depends_on('py-numpy')
+
+ # Optional dependencies
+ depends_on('py-scipy')
+
+ def install(self, spec, prefix):
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/py-sncosmo/package.py b/var/spack/repos/builtin/packages/py-sncosmo/package.py
new file mode 100644
index 0000000000..82ae2a2e69
--- /dev/null
+++ b/var/spack/repos/builtin/packages/py-sncosmo/package.py
@@ -0,0 +1,51 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class PySncosmo(Package):
+ """SNCosmo is a Python library for high-level supernova cosmology
+ analysis."""
+
+ homepage = "http://sncosmo.readthedocs.io/"
+ url = "https://pypi.python.org/packages/source/s/sncosmo/sncosmo-1.2.0.tar.gz"
+
+ version('1.2.0', '028e6d1dc84ab1c17d2f3b6378b2cb1e')
+
+ # Required dependencies
+ # py-sncosmo binaries are duplicates of those from py-astropy
+ extends('python', ignore=r'bin/.*')
+ depends_on('py-numpy')
+ depends_on('py-scipy')
+ depends_on('py-astropy')
+
+ # Recommended dependencies
+ depends_on('py-matplotlib')
+ depends_on('py-iminuit')
+ depends_on('py-emcee')
+ depends_on('py-nestle')
+
+ def install(self, spec, prefix):
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/py-wcsaxes/package.py b/var/spack/repos/builtin/packages/py-wcsaxes/package.py
new file mode 100644
index 0000000000..b0adbe3658
--- /dev/null
+++ b/var/spack/repos/builtin/packages/py-wcsaxes/package.py
@@ -0,0 +1,43 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class PyWcsaxes(Package):
+ """WCSAxes is a framework for making plots of Astronomical data
+ in Matplotlib."""
+
+ homepage = "http://wcsaxes.readthedocs.io/en/latest/index.html"
+ url = "https://github.com/astrofrog/wcsaxes/archive/v0.8.tar.gz"
+
+ version('0.8', 'de1c60fdae4c330bf5ddb9f1ab5ab920')
+
+ extends('python', ignore=r'bin/pbr')
+ depends_on('py-numpy')
+ depends_on('py-matplotlib')
+ depends_on('py-astropy')
+
+ def install(self, spec, prefix):
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py
index 86c12498e1..b6a62bf742 100644
--- a/var/spack/repos/builtin/packages/python/package.py
+++ b/var/spack/repos/builtin/packages/python/package.py
@@ -22,9 +22,6 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import functools
-import glob
-import inspect
import os
import re
from contextlib import closing
@@ -37,11 +34,10 @@ from spack.util.environment import *
class Python(Package):
"""The Python programming language."""
+
homepage = "http://www.python.org"
url = "http://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz"
- extendable = True
-
version('3.5.1', 'be78e48cdfc1a7ad90efff146dce6cfe')
version('3.5.0', 'a56c0c0b45d75a0ec9c6dee933c41c36')
version('2.7.11', '6b6076ec9e93f05dd63e47eb9c15728b', preferred=True)
@@ -49,6 +45,8 @@ class Python(Package):
version('2.7.9', '5eebcaa0030dc4061156d3429657fb83')
version('2.7.8', 'd4bca0159acb0b44a781292b5231936f')
+ extendable = True
+
depends_on("openssl")
depends_on("bzip2")
depends_on("readline")
@@ -64,39 +62,63 @@ class Python(Package):
# Rest of install is pretty standard except setup.py needs to
# be able to read the CPPFLAGS and LDFLAGS as it scans for the
# library and headers to build
- configure_args= [
- "--prefix=%s" % prefix,
- "--with-threads",
- "--enable-shared",
- "CPPFLAGS=-I%s/include -I%s/include -I%s/include -I%s/include -I%s/include -I%s/include" % (
- spec['openssl'].prefix, spec['bzip2'].prefix,
- spec['readline'].prefix, spec['ncurses'].prefix,
- spec['sqlite'].prefix, spec['zlib'].prefix),
- "LDFLAGS=-L%s/lib -L%s/lib -L%s/lib -L%s/lib -L%s/lib -L%s/lib" % (
- spec['openssl'].prefix, spec['bzip2'].prefix,
- spec['readline'].prefix, spec['ncurses'].prefix,
- spec['sqlite'].prefix, spec['zlib'].prefix)
- ]
+ cppflags = ' -I'.join([
+ spec['openssl'].prefix.include, spec['bzip2'].prefix.include,
+ spec['readline'].prefix.include, spec['ncurses'].prefix.include,
+ spec['sqlite'].prefix.include, spec['zlib'].prefix.include
+ ])
+
+ ldflags = ' -L'.join([
+ spec['openssl'].prefix.lib, spec['bzip2'].prefix.lib,
+ spec['readline'].prefix.lib, spec['ncurses'].prefix.lib,
+ spec['sqlite'].prefix.lib, spec['zlib'].prefix.lib
+ ])
+
+ config_args = [
+ "--prefix={0}".format(prefix),
+ "--with-threads",
+ "--enable-shared",
+ "CPPFLAGS=-I{0}".format(cppflags),
+ "LDFLAGS=-L{0}".format(ldflags)
+ ]
+
if spec.satisfies('@3:'):
- configure_args.append('--without-ensurepip')
- configure(*configure_args)
+ config_args.append('--without-ensurepip')
+
+ configure(*config_args)
+
make()
make("install")
- # Modify compiler paths in configuration files. This is necessary for
- # building site packages outside of spack
- filter_file(r'([/s]=?)([\S=]*)/lib/spack/env(/[^\s/]*)?/(\S*)(\s)',
- (r'\4\5'),
- join_path(prefix.lib, 'python%d.%d' % self.version[:2], '_sysconfigdata.py'))
+ self.filter_compilers(spec, prefix)
+
+ def filter_compilers(self, spec, prefix):
+ """Run after install to tell the configuration files and Makefiles
+ to use the compilers that Spack built the package with.
+
+ If this isn't done, they'll have CC and CXX set to Spack's generic
+ cc and c++. We want them to be bound to whatever compiler
+ they were built with."""
+
+ kwargs = {'ignore_absent': True, 'backup': False, 'string': True}
- python3_version = ''
+ dirname = join_path(prefix.lib,
+ 'python{0}'.format(self.version.up_to(2)))
+
+ config = 'config'
if spec.satisfies('@3:'):
- python3_version = '-%d.%dm' % self.version[:2]
- makefile_filepath = join_path(prefix.lib, 'python%d.%d' % self.version[:2], 'config%s' % python3_version, 'Makefile')
- filter_file(r'([/s]=?)([\S=]*)/lib/spack/env(/[^\s/]*)?/(\S*)(\s)',
- (r'\4\5'),
- makefile_filepath)
+ config = 'config-{0}m'.format(self.version.up_to(2))
+
+ files = [
+ '_sysconfigdata.py',
+ join_path(config, 'Makefile')
+ ]
+ for filename in files:
+ filter_file(env['CC'], self.compiler.cc,
+ join_path(dirname, filename), **kwargs)
+ filter_file(env['CXX'], self.compiler.cxx,
+ join_path(dirname, filename), **kwargs)
# ========================================================================
# Set up environment to make install easy for python extensions.
@@ -104,57 +126,59 @@ class Python(Package):
@property
def python_lib_dir(self):
- return os.path.join('lib', 'python%d.%d' % self.version[:2])
-
+ return join_path('lib', 'python{0}'.format(self.version.up_to(2)))
@property
def python_include_dir(self):
- return os.path.join('include', 'python%d.%d' % self.version[:2])
-
+ return join_path('include', 'python{0}'.format(self.version.up_to(2)))
@property
def site_packages_dir(self):
- return os.path.join(self.python_lib_dir, 'site-packages')
-
+ return join_path(self.python_lib_dir, 'site-packages')
def setup_dependent_environment(self, spack_env, run_env, extension_spec):
- # TODO: do this only for actual extensions.
+ """Set PYTHONPATH to include site-packages dir for the
+ extension and any other python extensions it depends on."""
- # Set PYTHONPATH to include site-packages dir for the
- # extension and any other python extensions it depends on.
python_paths = []
for d in extension_spec.traverse():
if d.package.extends(self.spec):
- python_paths.append(os.path.join(d.prefix, self.site_packages_dir))
+ python_paths.append(join_path(d.prefix,
+ self.site_packages_dir))
pythonpath = ':'.join(python_paths)
spack_env.set('PYTHONPATH', pythonpath)
- # For run time environment set only the path for extension_spec and prepend it to PYTHONPATH
+ # For run time environment set only the path for
+ # extension_spec and prepend it to PYTHONPATH
if extension_spec.package.extends(self.spec):
- run_env.prepend_path('PYTHONPATH', os.path.join(extension_spec.prefix, self.site_packages_dir))
-
+ run_env.prepend_path('PYTHONPATH', join_path(
+ extension_spec.prefix, self.site_packages_dir))
def setup_dependent_package(self, module, ext_spec):
- """
- Called before python modules' install() methods.
+ """Called before python modules' install() methods.
In most cases, extensions will only need to have one line::
- python('setup.py', 'install', '--prefix=%s' % prefix)
- """
+ python('setup.py', 'install', '--prefix={0}'.format(prefix))"""
+
# Python extension builds can have a global python executable function
- if self.version >= Version("3.0.0") and self.version < Version("4.0.0"):
- module.python = Executable(join_path(self.spec.prefix.bin, 'python3'))
+ if Version("3.0.0") <= self.version < Version("4.0.0"):
+ module.python = Executable(join_path(self.spec.prefix.bin,
+ 'python3'))
else:
- module.python = Executable(join_path(self.spec.prefix.bin, 'python'))
+ module.python = Executable(join_path(self.spec.prefix.bin,
+ 'python'))
# Add variables for lib/pythonX.Y and lib/pythonX.Y/site-packages dirs.
- module.python_lib_dir = os.path.join(ext_spec.prefix, self.python_lib_dir)
- module.python_include_dir = os.path.join(ext_spec.prefix, self.python_include_dir)
- module.site_packages_dir = os.path.join(ext_spec.prefix, self.site_packages_dir)
-
- # Make the site packages directory for extensions, if it does not exist already.
+ module.python_lib_dir = join_path(ext_spec.prefix,
+ self.python_lib_dir)
+ module.python_include_dir = join_path(ext_spec.prefix,
+ self.python_include_dir)
+ module.site_packages_dir = join_path(ext_spec.prefix,
+ self.site_packages_dir)
+
+ # Make the site packages directory for extensions
if ext_spec.package.is_extension:
mkdirp(module.site_packages_dir)
@@ -167,25 +191,28 @@ class Python(Package):
ignore_arg = args.get('ignore', lambda f: False)
# Always ignore easy-install.pth, as it needs to be merged.
- patterns = [r'easy-install\.pth$']
+ patterns = [r'site-packages/easy-install\.pth$']
# Ignore pieces of setuptools installed by other packages.
+ # Must include directory name or it will remove all site*.py files.
if ext_pkg.name != 'py-setuptools':
- patterns.append(r'/site[^/]*\.pyc?$')
- patterns.append(r'setuptools\.pth')
- patterns.append(r'bin/easy_install[^/]*$')
- patterns.append(r'setuptools.*egg$')
+ patterns.extend([
+ r'bin/easy_install[^/]*$',
+ r'site-packages/setuptools[^/]*\.egg$',
+ r'site-packages/setuptools\.pth$',
+ r'site-packages/site[^/]*\.pyc?$',
+ r'site-packages/__pycache__/site[^/]*\.pyc?$'
+ ])
if ext_pkg.name != 'py-numpy':
patterns.append(r'bin/f2py$')
return match_predicate(ignore_arg, patterns)
-
def write_easy_install_pth(self, exts):
paths = []
for ext in sorted(exts.values()):
- ext_site_packages = os.path.join(ext.prefix, self.site_packages_dir)
- easy_pth = "%s/easy-install.pth" % ext_site_packages
+ ext_site_packages = join_path(ext.prefix, self.site_packages_dir)
+ easy_pth = join_path(ext_site_packages, "easy-install.pth")
if not os.path.isfile(easy_pth):
continue
@@ -195,15 +222,18 @@ class Python(Package):
line = line.rstrip()
# Skip lines matching these criteria
- if not line: continue
- if re.search(r'^(import|#)', line): continue
- if (ext.name != 'py-setuptools' and
- re.search(r'setuptools.*egg$', line)): continue
+ if not line:
+ continue
+ if re.search(r'^(import|#)', line):
+ continue
+ if ((ext.name != 'py-setuptools' and
+ re.search(r'setuptools.*egg$', line))):
+ continue
paths.append(line)
- site_packages = os.path.join(self.prefix, self.site_packages_dir)
- main_pth = "%s/easy-install.pth" % site_packages
+ site_packages = join_path(self.prefix, self.site_packages_dir)
+ main_pth = join_path(site_packages, "easy-install.pth")
if not paths:
if os.path.isfile(main_pth):
@@ -211,15 +241,22 @@ class Python(Package):
else:
with closing(open(main_pth, 'w')) as f:
- f.write("import sys; sys.__plen = len(sys.path)\n")
+ f.write("""
+import sys
+sys.__plen = len(sys.path)
+""")
for path in paths:
- f.write("%s\n" % path)
- f.write("import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; "
- "p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)\n")
-
+ f.write("{0}\n".format(path))
+ f.write("""
+new = sys.path[sys.__plen:]
+del sys.path[sys.__plen:]
+p = getattr(sys, '__egginsert', 0)
+sys.path[p:p] = new
+sys.__egginsert = p + len(new)
+""")
def activate(self, ext_pkg, **args):
- ignore=self.python_ignore(ext_pkg, args)
+ ignore = self.python_ignore(ext_pkg, args)
args.update(ignore=ignore)
super(Python, self).activate(ext_pkg, **args)
@@ -228,12 +265,12 @@ class Python(Package):
exts[ext_pkg.name] = ext_pkg.spec
self.write_easy_install_pth(exts)
-
def deactivate(self, ext_pkg, **args):
args.update(ignore=self.python_ignore(ext_pkg, args))
super(Python, self).deactivate(ext_pkg, **args)
exts = spack.install_layout.extension_map(self.spec)
- if ext_pkg.name in exts: # Make deactivate idempotent.
+ # Make deactivate idempotent
+ if ext_pkg.name in exts:
del exts[ext_pkg.name]
self.write_easy_install_pth(exts)
diff --git a/var/spack/repos/builtin/packages/serf/package.py b/var/spack/repos/builtin/packages/serf/package.py
index 3b1d08889c..817db68241 100644
--- a/var/spack/repos/builtin/packages/serf/package.py
+++ b/var/spack/repos/builtin/packages/serf/package.py
@@ -24,8 +24,10 @@
##############################################################################
from spack import *
+
class Serf(Package):
- """Apache Serf - a high performance C-based HTTP client library built upon the Apache Portable Runtime (APR) library"""
+ """Apache Serf - a high performance C-based HTTP client library
+ built upon the Apache Portable Runtime (APR) library"""
homepage = 'https://serf.apache.org/'
url = 'https://archive.apache.org/dist/serf/serf-1.3.8.tar.bz2'
@@ -36,6 +38,7 @@ class Serf(Package):
depends_on('scons')
depends_on('expat')
depends_on('openssl')
+ depends_on('zlib')
def install(self, spec, prefix):
scons = which("scons")
@@ -44,8 +47,10 @@ class Serf(Package):
options.append('APR=%s' % spec['apr'].prefix)
options.append('APU=%s' % spec['apr-util'].prefix)
options.append('OPENSSL=%s' % spec['openssl'].prefix)
- options.append('LINKFLAGS=-L%s/lib' % spec['expat'].prefix)
- options.append('CPPFLAGS=-I%s/include' % spec['expat'].prefix)
+ options.append('LINKFLAGS=-L%s/lib -L%s/lib' %
+ (spec['expat'].prefix, spec['zlib'].prefix))
+ options.append('CPPFLAGS=-I%s/include -I%s/include' %
+ (spec['expat'].prefix, spec['zlib'].prefix))
scons(*options)
scons('install')
diff --git a/var/spack/repos/builtin/packages/trilinos/package.py b/var/spack/repos/builtin/packages/trilinos/package.py
index 1eaec86405..6913d79dcc 100644
--- a/var/spack/repos/builtin/packages/trilinos/package.py
+++ b/var/spack/repos/builtin/packages/trilinos/package.py
@@ -23,18 +23,23 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *
-import os, sys, glob
+import os
+import sys
-# Trilinos is complicated to build, as an inspiration a couple of links to other repositories which build it:
+# Trilinos is complicated to build, as an inspiration a couple of links to
+# other repositories which build it:
# https://github.com/hpcugent/easybuild-easyblocks/blob/master/easybuild/easyblocks/t/trilinos.py#L111
# https://github.com/koecher/candi/blob/master/deal.II-toolchain/packages/trilinos.package
# https://gitlab.com/configurations/cluster-config/blob/master/trilinos.sh
-# https://github.com/Homebrew/homebrew-science/blob/master/trilinos.rb
-# and some relevant documentation/examples:
+# https://github.com/Homebrew/homebrew-science/blob/master/trilinos.rb and some
+# relevant documentation/examples:
# https://github.com/trilinos/Trilinos/issues/175
+
+
class Trilinos(Package):
- """The Trilinos Project is an effort to develop algorithms and enabling technologies within an object-oriented
- software framework for the solution of large-scale, complex multi-physics engineering and scientific problems.
+ """The Trilinos Project is an effort to develop algorithms and enabling
+ technologies within an object-oriented software framework for the solution
+ of large-scale, complex multi-physics engineering and scientific problems.
A unique design feature of Trilinos is its focus on packages.
"""
homepage = "https://trilinos.org/"
@@ -54,49 +59,51 @@ class Trilinos(Package):
variant('hypre', default=True, description='Compile with Hypre preconditioner')
variant('hdf5', default=True, description='Compile with HDF5')
variant('suite-sparse', default=True, description='Compile with SuiteSparse solvers')
- # not everyone has py-numpy activated, keep it disabled by default to avoid configure errors
+ # not everyone has py-numpy activated, keep it disabled by default to avoid
+ # configure errors
variant('python', default=False, description='Build python wrappers')
variant('shared', default=True, description='Enables the build of shared libraries')
variant('debug', default=False, description='Builds a debug version of the libraries')
+ variant('boost', default=True, description='Compile with Boost')
# Everything should be compiled with -fpic
depends_on('blas')
depends_on('lapack')
- depends_on('boost')
+ depends_on('boost', when='+boost')
depends_on('matio')
depends_on('glm')
depends_on('swig')
- depends_on('metis@5:',when='+metis')
- depends_on('suite-sparse',when='+suite-sparse')
+ depends_on('metis@5:', when='+metis')
+ depends_on('suite-sparse', when='+suite-sparse')
# MPI related dependencies
depends_on('mpi')
depends_on('netcdf+mpi')
- depends_on('parmetis',when='+metis')
- # Trilinos' Tribits config system is limited which makes it
- # very tricky to link Amesos with static MUMPS, see
+ depends_on('parmetis', when='+metis')
+ # Trilinos' Tribits config system is limited which makes it very tricky to
+ # link Amesos with static MUMPS, see
# https://trilinos.org/docs/dev/packages/amesos2/doc/html/classAmesos2_1_1MUMPS.html
- # One could work it out by getting linking flags from mpif90 --showme:link (or alike)
- # and adding results to -DTrilinos_EXTRA_LINK_FLAGS
- # together with Blas and Lapack and ScaLAPACK and Blacs and -lgfortran and
- # it may work at the end. But let's avoid all this by simply using shared libs
- depends_on('mumps@5.0:+mpi+shared',when='+mumps')
- depends_on('scalapack',when='+mumps')
- depends_on('superlu-dist',when='+superlu-dist')
- depends_on('hypre~internal-superlu',when='+hypre')
- depends_on('hdf5+mpi',when='+hdf5')
-
- depends_on('python',when='+python')
+ # One could work it out by getting linking flags from mpif90 --showme:link
+ # (or alike) and adding results to -DTrilinos_EXTRA_LINK_FLAGS together
+ # with Blas and Lapack and ScaLAPACK and Blacs and -lgfortran and it may
+ # work at the end. But let's avoid all this by simply using shared libs
+ depends_on('mumps@5.0:+mpi+shared', when='+mumps')
+ depends_on('scalapack', when='+mumps')
+ depends_on('superlu-dist', when='+superlu-dist')
+ depends_on('hypre~internal-superlu', when='+hypre')
+ depends_on('hdf5+mpi', when='+hdf5')
+ depends_on('python', when='+python')
patch('umfpack_from_suitesparse.patch')
# check that the combination of variants makes sense
def variants_check(self):
if '+superlu-dist' in self.spec and self.spec.satisfies('@:11.4.3'):
- # For Trilinos v11 we need to force SuperLUDist=OFF,
- # since only the deprecated SuperLUDist v3.3 together with an Amesos patch
- # is working.
- raise RuntimeError('The superlu-dist variant can only be used with Trilinos @12.0.1:')
+ # For Trilinos v11 we need to force SuperLUDist=OFF, since only the
+ # deprecated SuperLUDist v3.3 together with an Amesos patch is
+ # working.
+ raise RuntimeError('The superlu-dist variant can only be used' +
+ ' with Trilinos @12.0.1:')
def install(self, spec, prefix):
self.variants_check()
@@ -106,54 +113,75 @@ class Trilinos(Package):
options.extend(std_cmake_args)
mpi_bin = spec['mpi'].prefix.bin
- options.extend(['-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON',
- '-DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES:BOOL=ON',
- '-DTrilinos_VERBOSE_CONFIGURE:BOOL=OFF',
- '-DTrilinos_ENABLE_TESTS:BOOL=OFF',
- '-DTrilinos_ENABLE_EXAMPLES:BOOL=OFF',
- '-DCMAKE_BUILD_TYPE:STRING=%s' % ('DEBUG' if '+debug' in spec else 'RELEASE'),
- '-DBUILD_SHARED_LIBS:BOOL=%s' % ('ON' if '+shared' in spec else 'OFF'),
- '-DTPL_ENABLE_MPI:BOOL=ON',
- '-DMPI_BASE_DIR:PATH=%s' % spec['mpi'].prefix,
- '-DTPL_ENABLE_BLAS=ON',
- '-DBLAS_LIBRARY_NAMES=blas', # FIXME: don't hardcode names
- '-DBLAS_LIBRARY_DIRS=%s' % spec['blas'].prefix.lib,
- '-DTPL_ENABLE_LAPACK=ON',
- '-DLAPACK_LIBRARY_NAMES=lapack',
- '-DLAPACK_LIBRARY_DIRS=%s' % spec['lapack'].prefix,
- '-DTPL_ENABLE_Boost:BOOL=ON',
- '-DBoost_INCLUDE_DIRS:PATH=%s' % spec['boost'].prefix.include,
- '-DBoost_LIBRARY_DIRS:PATH=%s' % spec['boost'].prefix.lib,
- '-DTrilinos_ENABLE_EXPLICIT_INSTANTIATION:BOOL=ON',
- '-DTrilinos_ENABLE_CXX11:BOOL=ON',
- '-DTPL_ENABLE_Netcdf:BOOL=ON',
- '-DTPL_ENABLE_HYPRE:BOOL=%s' % ('ON' if '+hypre' in spec else 'OFF'),
- '-DTPL_ENABLE_HDF5:BOOL=%s' % ('ON' if '+hdf5' in spec else 'OFF'),
- ])
+ options.extend([
+ '-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON',
+ '-DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES:BOOL=ON',
+ '-DTrilinos_VERBOSE_CONFIGURE:BOOL=OFF',
+ '-DTrilinos_ENABLE_TESTS:BOOL=OFF',
+ '-DTrilinos_ENABLE_EXAMPLES:BOOL=OFF',
+ '-DCMAKE_BUILD_TYPE:STRING=%s' % (
+ 'DEBUG' if '+debug' in spec else 'RELEASE'),
+ '-DBUILD_SHARED_LIBS:BOOL=%s' % (
+ 'ON' if '+shared' in spec else 'OFF'),
+ '-DTPL_ENABLE_MPI:BOOL=ON',
+ '-DMPI_BASE_DIR:PATH=%s' % spec['mpi'].prefix,
+ '-DTPL_ENABLE_BLAS=ON',
+ '-DBLAS_LIBRARY_NAMES=blas', # FIXME: don't hardcode names
+ '-DBLAS_LIBRARY_DIRS=%s' % spec['blas'].prefix.lib,
+ '-DTPL_ENABLE_LAPACK=ON',
+ '-DLAPACK_LIBRARY_NAMES=lapack',
+ '-DLAPACK_LIBRARY_DIRS=%s' % spec['lapack'].prefix,
+ '-DTrilinos_ENABLE_EXPLICIT_INSTANTIATION:BOOL=ON',
+ '-DTrilinos_ENABLE_CXX11:BOOL=ON',
+ '-DTPL_ENABLE_Netcdf:BOOL=ON',
+ '-DTPL_ENABLE_HYPRE:BOOL=%s' % (
+ 'ON' if '+hypre' in spec else 'OFF'),
+ '-DTPL_ENABLE_HDF5:BOOL=%s' % (
+ 'ON' if '+hdf5' in spec else 'OFF'),
+ ])
+
+ if '+boost' in spec:
+ options.extend([
+ '-DTPL_ENABLE_Boost:BOOL=ON',
+ '-DBoost_INCLUDE_DIRS:PATH=%s' % spec['boost'].prefix.include,
+ '-DBoost_LIBRARY_DIRS:PATH=%s' % spec['boost'].prefix.lib
+ ])
+ else:
+ options.extend(['-DTPL_ENABLE_Boost:BOOL=OFF'])
# Fortran lib
- libgfortran = os.path.dirname (os.popen('%s --print-file-name libgfortran.a' % join_path(mpi_bin,'mpif90') ).read())
+ libgfortran = os.path.dirname(os.popen(
+ '%s --print-file-name libgfortran.a' %
+ join_path(mpi_bin, 'mpif90')).read())
options.extend([
- '-DTrilinos_EXTRA_LINK_FLAGS:STRING=-L%s/ -lgfortran' % libgfortran,
+ '-DTrilinos_EXTRA_LINK_FLAGS:STRING=-L%s/ -lgfortran' % (
+ libgfortran),
'-DTrilinos_ENABLE_Fortran=ON'
])
# for build-debug only:
- #options.extend([
- # '-DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE'
- #])
+ # options.extend([
+ # '-DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE'
+ # ])
# suite-sparse related
if '+suite-sparse' in spec:
options.extend([
- '-DTPL_ENABLE_Cholmod:BOOL=OFF', # FIXME: Trilinos seems to be looking for static libs only, patch CMake TPL file?
- #'-DTPL_ENABLE_Cholmod:BOOL=ON',
- #'-DCholmod_LIBRARY_DIRS:PATH=%s' % spec['suite-sparse'].prefix.lib,
- #'-DCholmod_INCLUDE_DIRS:PATH=%s' % spec['suite-sparse'].prefix.include,
+ # FIXME: Trilinos seems to be looking for static libs only,
+ # patch CMake TPL file?
+ '-DTPL_ENABLE_Cholmod:BOOL=OFF',
+ # '-DTPL_ENABLE_Cholmod:BOOL=ON',
+ # '-DCholmod_LIBRARY_DIRS:PATH=%s' % (
+ # spec['suite-sparse'].prefix.lib,
+ # '-DCholmod_INCLUDE_DIRS:PATH=%s' % (
+ # spec['suite-sparse'].prefix.include,
'-DTPL_ENABLE_UMFPACK:BOOL=ON',
- '-DUMFPACK_LIBRARY_DIRS:PATH=%s' % spec['suite-sparse'].prefix.lib,
- '-DUMFPACK_INCLUDE_DIRS:PATH=%s' % spec['suite-sparse'].prefix.include,
- '-DUMFPACK_LIBRARY_NAMES=umfpack;amd;colamd;cholmod;suitesparseconfig'
+ '-DUMFPACK_LIBRARY_DIRS:PATH=%s' % (
+ spec['suite-sparse'].prefix.lib),
+ '-DUMFPACK_INCLUDE_DIRS:PATH=%s' % (
+ spec['suite-sparse'].prefix.include),
+ '-DUMFPACK_LIBRARY_NAMES=umfpack;amd;colamd;cholmod;' +
+ 'suitesparseconfig'
])
else:
options.extend([
@@ -169,9 +197,11 @@ class Trilinos(Package):
'-DMETIS_LIBRARY_NAMES=metis',
'-DTPL_METIS_INCLUDE_DIRS=%s' % spec['metis'].prefix.include,
'-DTPL_ENABLE_ParMETIS:BOOL=ON',
- '-DParMETIS_LIBRARY_DIRS=%s;%s' % (spec['parmetis'].prefix.lib,spec['metis'].prefix.lib),
+ '-DParMETIS_LIBRARY_DIRS=%s;%s' % (
+ spec['parmetis'].prefix.lib, spec['metis'].prefix.lib),
'-DParMETIS_LIBRARY_NAMES=parmetis;metis',
- '-DTPL_ParMETIS_INCLUDE_DIRS=%s' % spec['parmetis'].prefix.include
+ '-DTPL_ParMETIS_INCLUDE_DIRS=%s' % (
+ spec['parmetis'].prefix.include)
])
else:
options.extend([
@@ -184,11 +214,14 @@ class Trilinos(Package):
options.extend([
'-DTPL_ENABLE_MUMPS:BOOL=ON',
'-DMUMPS_LIBRARY_DIRS=%s' % spec['mumps'].prefix.lib,
- '-DMUMPS_LIBRARY_NAMES=dmumps;mumps_common;pord', # order is important!
+ # order is important!
+ '-DMUMPS_LIBRARY_NAMES=dmumps;mumps_common;pord',
'-DTPL_ENABLE_SCALAPACK:BOOL=ON',
- '-DSCALAPACK_LIBRARY_NAMES=scalapack' # FIXME: for MKL it's mkl_scalapack_lp64;mkl_blacs_mpich_lp64
+ # FIXME: for MKL it's mkl_scalapack_lp64;mkl_blacs_mpich_lp64
+ '-DSCALAPACK_LIBRARY_NAMES=scalapack'
])
- # see https://github.com/trilinos/Trilinos/blob/master/packages/amesos/README-MUMPS
+ # see
+ # https://github.com/trilinos/Trilinos/blob/master/packages/amesos/README-MUMPS
cxx_flags.extend([
'-DMUMPS_5_0'
])
@@ -201,16 +234,20 @@ class Trilinos(Package):
# superlu-dist:
if '+superlu-dist' in spec:
# Amesos, conflicting types of double and complex SLU_D
- # see https://trilinos.org/pipermail/trilinos-users/2015-March/004731.html
- # and https://trilinos.org/pipermail/trilinos-users/2015-March/004802.html
+ # see
+ # https://trilinos.org/pipermail/trilinos-users/2015-March/004731.html
+ # and
+ # https://trilinos.org/pipermail/trilinos-users/2015-March/004802.html
options.extend([
'-DTeuchos_ENABLE_COMPLEX:BOOL=OFF',
'-DKokkosTSQR_ENABLE_Complex:BOOL=OFF'
])
options.extend([
'-DTPL_ENABLE_SuperLUDist:BOOL=ON',
- '-DSuperLUDist_LIBRARY_DIRS=%s' % spec['superlu-dist'].prefix.lib,
- '-DSuperLUDist_INCLUDE_DIRS=%s' % spec['superlu-dist'].prefix.include
+ '-DSuperLUDist_LIBRARY_DIRS=%s' %
+ spec['superlu-dist'].prefix.lib,
+ '-DSuperLUDist_INCLUDE_DIRS=%s' %
+ spec['superlu-dist'].prefix.include
])
if spec.satisfies('^superlu-dist@4.0:'):
options.extend([
@@ -221,7 +258,6 @@ class Trilinos(Package):
'-DTPL_ENABLE_SuperLUDist:BOOL=OFF',
])
-
# python
if '+python' in spec:
options.extend([
@@ -248,23 +284,26 @@ class Trilinos(Package):
'-DTrilinos_ENABLE_FEI=OFF'
])
-
with working_dir('spack-build', create=True):
cmake('..', *options)
make()
make('install')
- # When trilinos is built with Python, libpytrilinos is included through
- # cmake configure files. Namely, Trilinos_LIBRARIES in TrilinosConfig.cmake
- # contains pytrilinos. This leads to a run-time error:
- # Symbol not found: _PyBool_Type
- # and prevents Trilinos to be used in any C++ code, which links executable
- # against the libraries listed in Trilinos_LIBRARIES.
- # See https://github.com/Homebrew/homebrew-science/issues/2148#issuecomment-103614509
+ # When trilinos is built with Python, libpytrilinos is included
+ # through cmake configure files. Namely, Trilinos_LIBRARIES in
+ # TrilinosConfig.cmake contains pytrilinos. This leads to a
+ # run-time error: Symbol not found: _PyBool_Type and prevents
+ # Trilinos to be used in any C++ code, which links executable
+ # against the libraries listed in Trilinos_LIBRARIES. See
+ # https://github.com/Homebrew/homebrew-science/issues/2148#issuecomment-103614509
# A workaround it to remove PyTrilinos from the COMPONENTS_LIST :
if '+python' in self.spec:
- filter_file(r'(SET\(COMPONENTS_LIST.*)(PyTrilinos;)(.*)', (r'\1\3'), '%s/cmake/Trilinos/TrilinosConfig.cmake' % prefix.lib)
+ filter_file(r'(SET\(COMPONENTS_LIST.*)(PyTrilinos;)(.*)',
+ (r'\1\3'),
+ '%s/cmake/Trilinos/TrilinosConfig.cmake' %
+ prefix.lib)
- # The shared libraries are not installed correctly on Darwin; correct this
+ # The shared libraries are not installed correctly on Darwin;
+ # correct this
if (sys.platform == 'darwin') and ('+shared' in spec):
fix_darwin_install_name(prefix.lib)
diff --git a/var/spack/repos/builtin/packages/xorg-util-macros/package.py b/var/spack/repos/builtin/packages/xorg-util-macros/package.py
new file mode 100644
index 0000000000..963d93442f
--- /dev/null
+++ b/var/spack/repos/builtin/packages/xorg-util-macros/package.py
@@ -0,0 +1,38 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+class XorgUtilMacros(Package):
+ """The util-macros package contains the m4 macros used by all of the Xorg packages."""
+
+ homepage = "http://www.example.com"
+ url = "http://ftp.x.org/pub/individual/util/util-macros-1.19.0.tar.bz2"
+
+ version('1.19.0', '1cf984125e75f8204938d998a8b6c1e1')
+
+ def install(self, spec, prefix):
+ configure("--prefix=%s" % prefix)
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/xproto/package.py b/var/spack/repos/builtin/packages/xproto/package.py
new file mode 100644
index 0000000000..7be6defb83
--- /dev/null
+++ b/var/spack/repos/builtin/packages/xproto/package.py
@@ -0,0 +1,41 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+class Xproto(Package):
+ """The Xorg protocol headers provide the header files required to
+ build the system, and to allow other applications to build against
+ the installed X Window system."""
+ homepage = "http://www.x.org/"
+ url = "https://www.x.org/archive//individual/proto/xproto-7.0.29.tar.gz"
+
+ version('7.0.29', '16a78dd2c5ad73011105c96235f6a0af')
+
+ depends_on("xorg-util-macros")
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix)
+ make()
+ make("install")