summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/sbang84
-rw-r--r--lib/spack/docs/developer_guide.rst15
-rw-r--r--lib/spack/docs/features.rst2
-rw-r--r--lib/spack/docs/packaging_guide.rst26
-rwxr-xr-xlib/spack/env/cc48
l---------lib/spack/env/pgi/case-insensitive/pgCC1
l---------lib/spack/env/pgi/pgc++ (renamed from lib/spack/env/pgi/pgf77)0
l---------lib/spack/env/pgi/pgfortran (renamed from lib/spack/env/pgi/pgf90)0
-rw-r--r--lib/spack/llnl/util/filesystem.py16
-rw-r--r--lib/spack/spack/cmd/checksum.py6
-rw-r--r--lib/spack/spack/cmd/clean.py2
-rw-r--r--lib/spack/spack/cmd/compiler.py6
-rw-r--r--lib/spack/spack/cmd/create.py10
-rw-r--r--lib/spack/spack/cmd/mirror.py4
-rw-r--r--lib/spack/spack/cmd/module.py6
-rw-r--r--lib/spack/spack/cmd/repo.py12
-rw-r--r--lib/spack/spack/compiler.py4
-rw-r--r--lib/spack/spack/compilers/pgi.py18
-rw-r--r--lib/spack/spack/config.py6
-rw-r--r--lib/spack/spack/database.py2
-rw-r--r--lib/spack/spack/directives.py4
-rw-r--r--lib/spack/spack/directory_layout.py4
-rw-r--r--lib/spack/spack/fetch_strategy.py16
-rw-r--r--lib/spack/spack/hooks/sbang.py77
-rw-r--r--lib/spack/spack/mirror.py4
-rw-r--r--lib/spack/spack/multimethod.py36
-rw-r--r--lib/spack/spack/package.py164
-rw-r--r--lib/spack/spack/repository.py6
-rw-r--r--lib/spack/spack/stage.py120
-rw-r--r--lib/spack/spack/test/cc.py10
-rw-r--r--var/spack/repos/builtin/packages/blitz/package.py15
-rw-r--r--var/spack/repos/builtin/packages/jdk/package.py4
-rw-r--r--var/spack/repos/builtin/packages/libevent/package.py9
-rw-r--r--var/spack/repos/builtin/packages/libsigsegv/package.py15
-rw-r--r--var/spack/repos/builtin/packages/llvm/package.py19
-rw-r--r--var/spack/repos/builtin/packages/m4/package.py12
-rw-r--r--var/spack/repos/builtin/packages/mpc/package.py6
-rw-r--r--var/spack/repos/builtin/packages/netcdf-cxx4/package.py15
-rw-r--r--var/spack/repos/builtin/packages/netcdf-fortran/package.py16
-rw-r--r--var/spack/repos/builtin/packages/netcdf/package.py14
-rw-r--r--var/spack/repos/builtin/packages/openssl/package.py1
-rw-r--r--var/spack/repos/builtin/packages/proj/package.py20
-rw-r--r--var/spack/repos/builtin/packages/udunits2/package.py16
-rw-r--r--var/spack/repos/builtin/packages/zfp/package.py26
44 files changed, 651 insertions, 246 deletions
diff --git a/bin/sbang b/bin/sbang
new file mode 100755
index 0000000000..ebfbe2e7a1
--- /dev/null
+++ b/bin/sbang
@@ -0,0 +1,84 @@
+#!/bin/bash
+#
+# `sbang`: Run scripts with long shebang lines.
+#
+# Many operating systems limit the length of shebang lines, making it
+# hard to use interpreters that are deep in the directory hierarchy.
+# `sbang` can run such scripts, either as a shebang interpreter, or
+# directly on the command line.
+#
+# Usage
+# -----------------------------
+# Suppose you have a script, long-shebang.sh, like this:
+#
+# 1 #!/very/long/path/to/some/interpreter
+# 2
+# 3 echo "success!"
+#
+# Invoking this script will result in an error on some OS's. On
+# Linux, you get this:
+#
+# $ ./long-shebang.sh
+# -bash: ./long: /very/long/path/to/some/interp: bad interpreter:
+# No such file or directory
+#
+# On Mac OS X, the system simply assumes the interpreter is the shell
+# and tries to run with it, which is likely not what you want.
+#
+#
+# `sbang` on the command line
+# -----------------------------
+# You can use `sbang` in two ways. The first is to use it directly,
+# from the command line, like this:
+#
+# $ sbang ./long-shebang.sh
+# success!
+#
+#
+# `sbang` as the interpreter
+# -----------------------------
+# You can also use `sbang` *as* the interpreter for your script. Put
+# `#!/bin/bash /path/to/sbang` on line 1, and move the original
+# shebang to line 2 of the script:
+#
+# 1 #!/bin/bash /path/to/sbang
+# 2 #!/long/path/to/real/interpreter with arguments
+# 3
+# 4 echo "success!"
+#
+# $ ./long-shebang.sh
+# success!
+#
+# On Linux, you could shorten line 1 to `#!/path/to/sbang`, but other
+# operating systems like Mac OS X require the interpreter to be a
+# binary, so it's best to use `sbang` as a `bash` argument.
+# Obviously, for this to work, `sbang` needs to have a short enough
+# path that *it* will run without hitting OS limits.
+#
+#
+# How it works
+# -----------------------------
+# `sbang` is a very simple bash script. It looks at the first two
+# lines of a script argument and runs the last line starting with
+# `#!`, with the script as an argument. It also forwards arguments.
+#
+
+# First argument is the script we want to actually run.
+script="$1"
+
+# Search the first two lines of script for interpreters.
+lines=0
+while read line && ((lines < 2)) ; do
+ if [[ "$line" = '#!'* ]]; then
+ interpreter="${line#\#!}"
+ fi
+ lines=$((lines+1))
+done < "$script"
+
+# Invoke any interpreter found, or raise an error if none was found.
+if [ -n "$interpreter" ]; then
+ exec $interpreter "$@"
+else
+ echo "error: sbang found no interpreter in $script"
+ exit 1
+fi
diff --git a/lib/spack/docs/developer_guide.rst b/lib/spack/docs/developer_guide.rst
index db47de80f5..0b618aa683 100644
--- a/lib/spack/docs/developer_guide.rst
+++ b/lib/spack/docs/developer_guide.rst
@@ -73,19 +73,32 @@ with a high level view of Spack's directory structure::
spack/ <- installation root
bin/
spack <- main spack executable
+
+ etc/
+ spack/ <- Spack config files.
+ Can be overridden by files in ~/.spack.
+
var/
spack/ <- build & stage directories
+ repos/ <- contains package repositories
+ builtin/ <- pkg repository that comes with Spack
+ repo.yaml <- descriptor for the builtin repository
+ packages/ <- directories under here contain packages
+
opt/
spack/ <- packages are installed here
+
lib/
spack/
docs/ <- source for this documentation
env/ <- compiler wrappers for build environment
+ external/ <- external libs included in Spack distro
+ llnl/ <- some general-use libraries
+
spack/ <- spack module; contains Python code
cmd/ <- each file in here is a spack subcommand
compilers/ <- compiler description files
- packages/ <- each file in here is a spack package
test/ <- unit test modules
util/ <- common code
diff --git a/lib/spack/docs/features.rst b/lib/spack/docs/features.rst
index fcb810086d..0998ba8da4 100644
--- a/lib/spack/docs/features.rst
+++ b/lib/spack/docs/features.rst
@@ -103,7 +103,7 @@ creates a simple python file:
It doesn't take much python coding to get from there to a working
package:
-.. literalinclude:: ../../../var/spack/packages/libelf/package.py
+.. literalinclude:: ../../../var/spack/repos/builtin/packages/libelf/package.py
:lines: 25-
Spack also provides wrapper functions around common commands like
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst
index 59ba63fa35..07a17ebd0a 100644
--- a/lib/spack/docs/packaging_guide.rst
+++ b/lib/spack/docs/packaging_guide.rst
@@ -84,7 +84,7 @@ always choose to download just one tarball initially, and run
If it fails entirely, you can get minimal boilerplate by using
:ref:`spack-edit-f`, or you can manually create a directory and
- ``package.py`` file for the package in ``var/spack/packages``.
+ ``package.py`` file for the package in ``var/spack/repos/builtin/packages``.
.. note::
@@ -203,7 +203,7 @@ edit`` command:
So, if you used ``spack create`` to create a package, then saved and
closed the resulting file, you can get back to it with ``spack edit``.
The ``cmake`` package actually lives in
-``$SPACK_ROOT/var/spack/packages/cmake/package.py``, but this provides
+``$SPACK_ROOT/var/spack/repos/builtin/packages/cmake/package.py``, but this provides
a much simpler shortcut and saves you the trouble of typing the full
path.
@@ -269,18 +269,18 @@ live in Spack's directory structure. In general, `spack-create`_ and
`spack-edit`_ handle creating package files for you, so you can skip
most of the details here.
-``var/spack/packages``
+``var/spack/repos/builtin/packages``
~~~~~~~~~~~~~~~~~~~~~~~
A Spack installation directory is structured like a standard UNIX
install prefix (``bin``, ``lib``, ``include``, ``var``, ``opt``,
etc.). Most of the code for Spack lives in ``$SPACK_ROOT/lib/spack``.
-Packages themselves live in ``$SPACK_ROOT/var/spack/packages``.
+Packages themselves live in ``$SPACK_ROOT/var/spack/repos/builtin/packages``.
If you ``cd`` to that directory, you will see directories for each
package:
-.. command-output:: cd $SPACK_ROOT/var/spack/packages; ls -CF
+.. command-output:: cd $SPACK_ROOT/var/spack/repos/builtin/packages; ls -CF
:shell:
:ellipsis: 10
@@ -288,7 +288,7 @@ Each directory contains a file called ``package.py``, which is where
all the python code for the package goes. For example, the ``libelf``
package lives in::
- $SPACK_ROOT/var/spack/packages/libelf/package.py
+ $SPACK_ROOT/var/spack/repos/builtin/packages/libelf/package.py
Alongside the ``package.py`` file, a package may contain extra
directories or files (like patches) that it needs to build.
@@ -301,7 +301,7 @@ Packages are named after the directory containing ``package.py``. So,
``libelf``'s ``package.py`` lives in a directory called ``libelf``.
The ``package.py`` file defines a class called ``Libelf``, which
extends Spack's ``Package`` class. for example, here is
-``$SPACK_ROOT/var/spack/packages/libelf/package.py``:
+``$SPACK_ROOT/var/spack/repos/builtin/packages/libelf/package.py``:
.. code-block:: python
:linenos:
@@ -328,7 +328,7 @@ these:
$ spack install libelf@0.8.13
Spack sees the package name in the spec and looks for
-``libelf/package.py`` in ``var/spack/packages``. Likewise, if you say
+``libelf/package.py`` in ``var/spack/repos/builtin/packages``. Likewise, if you say
``spack install py-numpy``, then Spack looks for
``py-numpy/package.py``.
@@ -703,7 +703,7 @@ supply is a filename, then the patch needs to live within the spack
source tree. For example, the patch above lives in a directory
structure like this::
- $SPACK_ROOT/var/spack/packages/
+ $SPACK_ROOT/var/spack/repos/builtin/packages/
mvapich2/
package.py
ad_lustre_rwcontig_open_source.patch
@@ -1533,7 +1533,7 @@ The last element of a package is its ``install()`` method. This is
where the real work of installation happens, and it's the main part of
the package you'll need to customize for each piece of software.
-.. literalinclude:: ../../../var/spack/packages/libelf/package.py
+.. literalinclude:: ../../../var/spack/repos/builtin/packages/libelf/package.py
:start-after: 0.8.12
:linenos:
@@ -1711,15 +1711,15 @@ Compile-time library search paths
* ``-L$dep_prefix/lib``
* ``-L$dep_prefix/lib64``
Runtime library search paths (RPATHs)
- * ``-Wl,-rpath=$dep_prefix/lib``
- * ``-Wl,-rpath=$dep_prefix/lib64``
+ * ``-Wl,-rpath,$dep_prefix/lib``
+ * ``-Wl,-rpath,$dep_prefix/lib64``
Include search paths
* ``-I$dep_prefix/include``
An example of this would be the ``libdwarf`` build, which has one
dependency: ``libelf``. Every call to ``cc`` in the ``libdwarf``
build will have ``-I$LIBELF_PREFIX/include``,
-``-L$LIBELF_PREFIX/lib``, and ``-Wl,-rpath=$LIBELF_PREFIX/lib``
+``-L$LIBELF_PREFIX/lib``, and ``-Wl,-rpath,$LIBELF_PREFIX/lib``
inserted on the command line. This is done transparently to the
project's build system, which will just think it's using a system
where ``libelf`` is readily available. Because of this, you **do
diff --git a/lib/spack/env/cc b/lib/spack/env/cc
index a323c48124..a19346ce97 100755
--- a/lib/spack/env/cc
+++ b/lib/spack/env/cc
@@ -90,15 +90,15 @@ case "$command" in
command="$SPACK_CC"
language="C"
;;
- c++|CC|g++|clang++|icpc|pgCC|xlc++)
+ c++|CC|g++|clang++|icpc|pgc++|xlc++)
command="$SPACK_CXX"
language="C++"
;;
- f90|fc|f95|gfortran|ifort|pgf90|xlf90|nagfor)
+ f90|fc|f95|gfortran|ifort|pgfortran|xlf90|nagfor)
command="$SPACK_FC"
language="Fortran 90"
;;
- f77|gfortran|ifort|pgf77|xlf|nagfor)
+ f77|gfortran|ifort|pgfortran|xlf|nagfor)
command="$SPACK_F77"
language="Fortran 77"
;;
@@ -175,32 +175,44 @@ while [ -n "$1" ]; do
;;
-Wl,*)
arg="${1#-Wl,}"
- if [ -z "$arg" ]; then shift; arg="$1"; fi
- if [[ "$arg" = -rpath=* ]]; then
- rpaths+=("${arg#-rpath=}")
- elif [[ "$arg" = -rpath ]]; then
+ # TODO: Handle multiple -Wl, continuations of -Wl,-rpath
+ if [[ $arg == -rpath=* ]]; then
+ arg="${arg#-rpath=}"
+ for rpath in ${arg//,/ }; do
+ rpaths+=("$rpath")
+ done
+ elif [[ $arg == -rpath,* ]]; then
+ arg="${arg#-rpath,}"
+ for rpath in ${arg//,/ }; do
+ rpaths+=("$rpath")
+ done
+ elif [[ $arg == -rpath ]]; then
shift; arg="$1"
- if [[ "$arg" != -Wl,* ]]; then
+ if [[ $arg != '-Wl,'* ]]; then
die "-Wl,-rpath was not followed by -Wl,*"
fi
- rpaths+=("${arg#-Wl,}")
+ arg="${arg#-Wl,}"
+ for rpath in ${arg//,/ }; do
+ rpaths+=("$rpath")
+ done
else
other_args+=("-Wl,$arg")
fi
;;
- -Xlinker,*)
- arg="${1#-Xlinker,}"
- if [ -z "$arg" ]; then shift; arg="$1"; fi
- if [[ "$arg" = -rpath=* ]]; then
+ -Xlinker)
+ shift; arg="$1";
+ if [[ $arg = -rpath=* ]]; then
rpaths+=("${arg#-rpath=}")
- elif [[ "$arg" = -rpath ]]; then
+ elif [[ $arg = -rpath ]]; then
shift; arg="$1"
- if [[ "$arg" != -Xlinker,* ]]; then
- die "-Xlinker,-rpath was not followed by -Xlinker,*"
+ if [[ $arg != -Xlinker ]]; then
+ die "-Xlinker -rpath was not followed by -Xlinker <arg>"
fi
- rpaths+=("${arg#-Xlinker,}")
+ shift; arg="$1"
+ rpaths+=("$arg")
else
- other_args+=("-Xlinker,$arg")
+ other_args+=("-Xlinker")
+ other_args+=("$arg")
fi
;;
*)
diff --git a/lib/spack/env/pgi/case-insensitive/pgCC b/lib/spack/env/pgi/case-insensitive/pgCC
deleted file mode 120000
index e2deb67f3b..0000000000
--- a/lib/spack/env/pgi/case-insensitive/pgCC
+++ /dev/null
@@ -1 +0,0 @@
-../../cc \ No newline at end of file
diff --git a/lib/spack/env/pgi/pgf77 b/lib/spack/env/pgi/pgc++
index 82c2b8e90a..82c2b8e90a 120000
--- a/lib/spack/env/pgi/pgf77
+++ b/lib/spack/env/pgi/pgc++
diff --git a/lib/spack/env/pgi/pgf90 b/lib/spack/env/pgi/pgfortran
index 82c2b8e90a..82c2b8e90a 120000
--- a/lib/spack/env/pgi/pgf90
+++ b/lib/spack/env/pgi/pgfortran
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index 366237ef8f..9ba662d0e3 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -25,7 +25,8 @@
__all__ = ['set_install_permissions', 'install', 'install_tree', 'traverse_tree',
'expand_user', 'working_dir', 'touch', 'touchp', 'mkdirp',
'force_remove', 'join_path', 'ancestor', 'can_access', 'filter_file',
- 'FileFilter', 'change_sed_delimiter', 'is_exe', 'force_symlink', 'remove_dead_links', 'remove_linked_tree']
+ 'FileFilter', 'change_sed_delimiter', 'is_exe', 'force_symlink',
+ 'remove_dead_links', 'remove_linked_tree', 'copy_mode', 'unset_executable_mode']
import os
import sys
@@ -158,6 +159,14 @@ def copy_mode(src, dest):
os.chmod(dest, dest_mode)
+def unset_executable_mode(path):
+ mode = os.stat(path).st_mode
+ mode &= ~stat.S_IXUSR
+ mode &= ~stat.S_IXGRP
+ mode &= ~stat.S_IXOTH
+ os.chmod(path, mode)
+
+
def install(src, dest):
"""Manually install a file to a particular location."""
tty.debug("Installing %s to %s" % (src, dest))
@@ -362,8 +371,9 @@ def remove_dead_links(root):
def remove_linked_tree(path):
"""
- Removes a directory and its contents. If the directory is a symlink, follows the link and removes the real
- directory before removing the link.
+ Removes a directory and its contents. If the directory is a
+ symlink, follows the link and removes the real directory before
+ removing the link.
Args:
path: directory to be removed
diff --git a/lib/spack/spack/cmd/checksum.py b/lib/spack/spack/cmd/checksum.py
index c451993233..966ff9a5e9 100644
--- a/lib/spack/spack/cmd/checksum.py
+++ b/lib/spack/spack/cmd/checksum.py
@@ -100,11 +100,11 @@ def checksum(parser, args):
else:
versions = pkg.fetch_remote_versions()
if not versions:
- tty.die("Could not fetch any versions for %s." % pkg.name)
+ tty.die("Could not fetch any versions for %s" % pkg.name)
sorted_versions = sorted(versions, reverse=True)
- tty.msg("Found %s versions of %s." % (len(versions), pkg.name),
+ tty.msg("Found %s versions of %s" % (len(versions), pkg.name),
*spack.cmd.elide_list(
["%-10s%s" % (v, versions[v]) for v in sorted_versions]))
print
@@ -121,7 +121,7 @@ def checksum(parser, args):
keep_stage=args.keep_stage)
if not version_hashes:
- tty.die("Could not fetch any versions for %s." % pkg.name)
+ tty.die("Could not fetch any versions for %s" % pkg.name)
version_lines = [" version('%s', '%s')" % (v, h) for v, h in version_hashes]
tty.msg("Checksummed new versions of %s:" % pkg.name, *version_lines)
diff --git a/lib/spack/spack/cmd/clean.py b/lib/spack/spack/cmd/clean.py
index 0c8bd1d528..6e7179122c 100644
--- a/lib/spack/spack/cmd/clean.py
+++ b/lib/spack/spack/cmd/clean.py
@@ -43,4 +43,4 @@ def clean(parser, args):
specs = spack.cmd.parse_specs(args.packages, concretize=True)
for spec in specs:
package = spack.repo.get(spec)
- package.stage.destroy()
+ package.do_clean()
diff --git a/lib/spack/spack/cmd/compiler.py b/lib/spack/spack/cmd/compiler.py
index 75b51f6b49..3e58e82184 100644
--- a/lib/spack/spack/cmd/compiler.py
+++ b/lib/spack/spack/cmd/compiler.py
@@ -96,7 +96,7 @@ def compiler_remove(args):
compilers = spack.compilers.compilers_for_spec(cspec, scope=args.scope)
if not compilers:
- tty.die("No compilers match spec %s." % cspec)
+ tty.die("No compilers match spec %s" % cspec)
elif not args.all and len(compilers) > 1:
tty.error("Multiple compilers match spec %s. Choose one:" % cspec)
colify(reversed(sorted([c.spec for c in compilers])), indent=4)
@@ -105,7 +105,7 @@ def compiler_remove(args):
for compiler in compilers:
spack.compilers.remove_compiler_from_config(compiler.spec, scope=args.scope)
- tty.msg("Removed compiler %s." % compiler.spec)
+ tty.msg("Removed compiler %s" % compiler.spec)
def compiler_info(args):
@@ -114,7 +114,7 @@ def compiler_info(args):
compilers = spack.compilers.compilers_for_spec(cspec, scope=args.scope)
if not compilers:
- tty.error("No compilers match spec %s." % cspec)
+ tty.error("No compilers match spec %s" % cspec)
else:
for c in compilers:
print str(c.spec) + ":"
diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py
index 6809209046..4564143f83 100644
--- a/lib/spack/spack/cmd/create.py
+++ b/lib/spack/spack/cmd/create.py
@@ -156,7 +156,7 @@ def guess_name_and_version(url, args):
# Try to deduce name and version of the new package from the URL
version = spack.url.parse_version(url)
if not version:
- tty.die("Couldn't guess a version string from %s." % url)
+ tty.die("Couldn't guess a version string from %s" % url)
# Try to guess a name. If it doesn't work, allow the user to override.
if args.alternate_name:
@@ -189,7 +189,7 @@ def find_repository(spec, args):
try:
repo = Repo(repo_path)
if spec.namespace and spec.namespace != repo.namespace:
- tty.die("Can't create package with namespace %s in repo with namespace %s."
+ tty.die("Can't create package with namespace %s in repo with namespace %s"
% (spec.namespace, repo.namespace))
except RepoError as e:
tty.die(str(e))
@@ -252,7 +252,7 @@ def create(parser, args):
name = spec.name # factors out namespace, if any
repo = find_repository(spec, args)
- tty.msg("This looks like a URL for %s version %s." % (name, version))
+ tty.msg("This looks like a URL for %s version %s" % (name, version))
tty.msg("Creating template for package %s" % name)
# Fetch tarballs (prompting user if necessary)
@@ -266,7 +266,7 @@ def create(parser, args):
keep_stage=args.keep_stage)
if not ver_hash_tuples:
- tty.die("Could not fetch any tarballs for %s." % name)
+ tty.die("Could not fetch any tarballs for %s" % name)
# Prepend 'py-' to python package names, by convention.
if guesser.build_system == 'python':
@@ -291,4 +291,4 @@ def create(parser, args):
# If everything checks out, go ahead and edit.
spack.editor(pkg_path)
- tty.msg("Created package %s." % pkg_path)
+ tty.msg("Created package %s" % pkg_path)
diff --git a/lib/spack/spack/cmd/mirror.py b/lib/spack/spack/cmd/mirror.py
index 8e9438c1a3..fcd15a6a90 100644
--- a/lib/spack/spack/cmd/mirror.py
+++ b/lib/spack/spack/cmd/mirror.py
@@ -126,7 +126,7 @@ def mirror_remove(args):
old_value = mirrors.pop(name)
spack.config.update_config('mirrors', mirrors, scope=args.scope)
- tty.msg("Removed mirror %s with url %s." % (name, old_value))
+ tty.msg("Removed mirror %s with url %s" % (name, old_value))
def mirror_list(args):
@@ -203,7 +203,7 @@ def mirror_create(args):
verb = "updated" if existed else "created"
tty.msg(
- "Successfully %s mirror in %s." % (verb, directory),
+ "Successfully %s mirror in %s" % (verb, directory),
"Archive stats:",
" %-4d already present" % p,
" %-4d added" % m,
diff --git a/lib/spack/spack/cmd/module.py b/lib/spack/spack/cmd/module.py
index a5a9570eb5..1d6867c1d9 100644
--- a/lib/spack/spack/cmd/module.py
+++ b/lib/spack/spack/cmd/module.py
@@ -58,7 +58,7 @@ def module_find(mtype, spec_array):
should type to use that package's module.
"""
if mtype not in module_types:
- tty.die("Invalid module type: '%s'. Options are %s." % (mtype, comma_or(module_types)))
+ tty.die("Invalid module type: '%s'. Options are %s" % (mtype, comma_or(module_types)))
specs = spack.cmd.parse_specs(spec_array)
if len(specs) > 1:
@@ -78,7 +78,7 @@ def module_find(mtype, spec_array):
mt = module_types[mtype]
mod = mt(specs[0])
if not os.path.isfile(mod.file_name):
- tty.die("No %s module is installed for %s." % (mtype, spec))
+ tty.die("No %s module is installed for %s" % (mtype, spec))
print mod.use_name
@@ -94,7 +94,7 @@ def module_refresh():
shutil.rmtree(cls.path, ignore_errors=False)
mkdirp(cls.path)
for spec in specs:
- tty.debug(" Writing file for %s." % spec)
+ tty.debug(" Writing file for %s" % spec)
cls(spec).write()
diff --git a/lib/spack/spack/cmd/repo.py b/lib/spack/spack/cmd/repo.py
index c2e352786d..87c782000f 100644
--- a/lib/spack/spack/cmd/repo.py
+++ b/lib/spack/spack/cmd/repo.py
@@ -89,11 +89,11 @@ def repo_add(args):
# check if the path exists
if not os.path.exists(canon_path):
- tty.die("No such file or directory: '%s'." % path)
+ tty.die("No such file or directory: %s" % path)
# Make sure the path is a directory.
if not os.path.isdir(canon_path):
- tty.die("Not a Spack repository: '%s'." % path)
+ tty.die("Not a Spack repository: %s" % path)
# Make sure it's actually a spack repository by constructing it.
repo = Repo(canon_path)
@@ -103,7 +103,7 @@ def repo_add(args):
if not repos: repos = []
if repo.root in repos or path in repos:
- tty.die("Repository is already registered with Spack: '%s'" % path)
+ tty.die("Repository is already registered with Spack: %s" % path)
repos.insert(0, canon_path)
spack.config.update_config('repos', repos, args.scope)
@@ -122,7 +122,7 @@ def repo_remove(args):
if canon_path == repo_canon_path:
repos.remove(repo_path)
spack.config.update_config('repos', repos, args.scope)
- tty.msg("Removed repository '%s'." % repo_path)
+ tty.msg("Removed repository %s" % repo_path)
return
# If it is a namespace, remove corresponding repo
@@ -132,13 +132,13 @@ def repo_remove(args):
if repo.namespace == path_or_namespace:
repos.remove(path)
spack.config.update_config('repos', repos, args.scope)
- tty.msg("Removed repository '%s' with namespace %s."
+ tty.msg("Removed repository %s with namespace '%s'."
% (repo.root, repo.namespace))
return
except RepoError as e:
continue
- tty.die("No repository with path or namespace: '%s'"
+ tty.die("No repository with path or namespace: %s"
% path_or_namespace)
diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index 12c02e0ea2..d38c0b00b1 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -256,12 +256,12 @@ class Compiler(object):
def __repr__(self):
- """Return a string represntation of the compiler toolchain."""
+ """Return a string representation of the compiler toolchain."""
return self.__str__()
def __str__(self):
- """Return a string represntation of the compiler toolchain."""
+ """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))))
diff --git a/lib/spack/spack/compilers/pgi.py b/lib/spack/spack/compilers/pgi.py
index 9ac74cfbdb..c6a1078bd9 100644
--- a/lib/spack/spack/compilers/pgi.py
+++ b/lib/spack/spack/compilers/pgi.py
@@ -29,28 +29,28 @@ class Pgi(Compiler):
cc_names = ['pgcc']
# Subclasses use possible names of C++ compiler
- cxx_names = ['pgCC']
+ cxx_names = ['pgc++', 'pgCC']
# Subclasses use possible names of Fortran 77 compiler
- f77_names = ['pgf77']
+ f77_names = ['pgfortran', 'pgf77']
# Subclasses use possible names of Fortran 90 compiler
- fc_names = ['pgf95', 'pgf90']
+ fc_names = ['pgfortran', 'pgf95', 'pgf90']
# Named wrapper links within spack.build_env_path
link_paths = { 'cc' : 'pgi/pgcc',
- 'cxx' : 'pgi/case-insensitive/pgCC',
- 'f77' : 'pgi/pgf77',
- 'fc' : 'pgi/pgf90' }
+ 'cxx' : 'pgi/pgc++',
+ 'f77' : 'pgi/pgfortran',
+ 'fc' : 'pgi/pgfortran' }
@classmethod
def default_version(cls, comp):
"""The '-V' option works for all the PGI compilers.
Output looks like this::
- pgf95 10.2-0 64-bit target on x86-64 Linux -tp nehalem-64
- Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
- Copyright 2000-2010, STMicroelectronics, Inc. All Rights Reserved.
+ pgcc 15.10-0 64-bit target on x86-64 Linux -tp sandybridge
+ The Portland Group - PGI Compilers and Tools
+ Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
"""
return get_compiler_version(
comp, '-V', r'pg[^ ]* ([^ ]+) \d\d\d?-bit target')
diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py
index 6fecde9980..576a5afa2e 100644
--- a/lib/spack/spack/config.py
+++ b/lib/spack/spack/config.py
@@ -205,7 +205,7 @@ config_scopes = OrderedDict()
def validate_section_name(section):
"""Raise a ValueError if the section is not a valid section."""
if section not in section_schemas:
- raise ValueError("Invalid config section: '%s'. Options are %s."
+ raise ValueError("Invalid config section: '%s'. Options are %s"
% (section, section_schemas))
@@ -335,7 +335,7 @@ def validate_scope(scope):
return config_scopes[scope]
else:
- raise ValueError("Invalid config scope: '%s'. Must be one of %s."
+ raise ValueError("Invalid config scope: '%s'. Must be one of %s"
% (scope, config_scopes.keys()))
@@ -350,7 +350,7 @@ def _read_config_file(filename, schema):
"Invlaid configuration. %s exists but is not a file." % filename)
elif not os.access(filename, os.R_OK):
- raise ConfigFileError("Config file is not readable: %s." % filename)
+ raise ConfigFileError("Config file is not readable: %s" % filename)
try:
tty.debug("Reading config file %s" % filename)
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index 9cbe7de44a..089d29325e 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -330,7 +330,7 @@ class Database(object):
found = rec.ref_count
if not expected == found:
raise AssertionError(
- "Invalid ref_count: %s: %d (expected %d), in DB %s."
+ "Invalid ref_count: %s: %d (expected %d), in DB %s"
% (key, found, expected, self._index_path))
diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index c8542f55f0..61cd303012 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -125,7 +125,7 @@ class directive(object):
dicts = (dicts,)
elif type(dicts) not in (list, tuple):
raise TypeError(
- "dicts arg must be list, tuple, or string. Found %s."
+ "dicts arg must be list, tuple, or string. Found %s"
% type(dicts))
self.dicts = dicts
@@ -317,5 +317,5 @@ class CircularReferenceError(DirectiveError):
def __init__(self, directive, package):
super(CircularReferenceError, self).__init__(
directive,
- "Package '%s' cannot pass itself to %s." % (package, directive))
+ "Package '%s' cannot pass itself to %s" % (package, directive))
self.package = package
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index 29d87b65b3..08c23627f4 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -335,7 +335,7 @@ class YamlDirectoryLayout(DirectoryLayout):
if not dag_hash in by_hash:
raise InvalidExtensionSpecError(
- "Spec %s not found in %s." % (dag_hash, prefix))
+ "Spec %s not found in %s" % (dag_hash, prefix))
ext_spec = by_hash[dag_hash]
if not prefix == ext_spec.prefix:
@@ -450,7 +450,7 @@ class ExtensionConflictError(DirectoryLayoutError):
"""Raised when an extension is added to a package that already has it."""
def __init__(self, spec, ext_spec, conflict):
super(ExtensionConflictError, self).__init__(
- "%s cannot be installed in %s because it conflicts with %s."% (
+ "%s cannot be installed in %s because it conflicts with %s"% (
ext_spec.short_spec, spec.short_spec, conflict.short_spec))
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index 83a2dbb59c..ec17cb97f1 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -153,7 +153,7 @@ class URLFetchStrategy(FetchStrategy):
self.stage.chdir()
if self.archive_file:
- tty.msg("Already downloaded %s." % self.archive_file)
+ tty.msg("Already downloaded %s" % self.archive_file)
return
tty.msg("Trying to fetch from %s" % self.url)
@@ -275,8 +275,8 @@ class URLFetchStrategy(FetchStrategy):
checker = crypto.Checker(self.digest)
if not checker.check(self.archive_file):
raise ChecksumError(
- "%s checksum failed for %s." % (checker.hash_name, self.archive_file),
- "Expected %s but got %s." % (self.digest, checker.sum))
+ "%s checksum failed for %s" % (checker.hash_name, self.archive_file),
+ "Expected %s but got %s" % (self.digest, checker.sum))
@_needs_stage
def reset(self):
@@ -312,7 +312,7 @@ class VCSFetchStrategy(FetchStrategy):
# Ensure that there's only one of the rev_types
if sum(k in kwargs for k in rev_types) > 1:
raise FetchStrategyError(
- "Supply only one of %s to fetch with %s." % (
+ "Supply only one of %s to fetch with %s" % (
comma_or(rev_types), name))
# Set attributes for each rev type.
@@ -321,7 +321,7 @@ class VCSFetchStrategy(FetchStrategy):
@_needs_stage
def check(self):
- tty.msg("No checksum needed when fetching with %s." % self.name)
+ tty.msg("No checksum needed when fetching with %s" % self.name)
@_needs_stage
def expand(self):
@@ -395,7 +395,7 @@ class GitFetchStrategy(VCSFetchStrategy):
self.stage.chdir()
if self.stage.source_path:
- tty.msg("Already fetched %s." % self.stage.source_path)
+ tty.msg("Already fetched %s" % self.stage.source_path)
return
args = []
@@ -505,7 +505,7 @@ class SvnFetchStrategy(VCSFetchStrategy):
self.stage.chdir()
if self.stage.source_path:
- tty.msg("Already fetched %s." % self.stage.source_path)
+ tty.msg("Already fetched %s" % self.stage.source_path)
return
tty.msg("Trying to check out svn repository: %s" % self.url)
@@ -584,7 +584,7 @@ class HgFetchStrategy(VCSFetchStrategy):
self.stage.chdir()
if self.stage.source_path:
- tty.msg("Already fetched %s." % self.stage.source_path)
+ tty.msg("Already fetched %s" % self.stage.source_path)
return
args = []
diff --git a/lib/spack/spack/hooks/sbang.py b/lib/spack/spack/hooks/sbang.py
new file mode 100644
index 0000000000..3390ecea29
--- /dev/null
+++ b/lib/spack/spack/hooks/sbang.py
@@ -0,0 +1,77 @@
+##############################################################################
+# Copyright (c) 2013-2015, 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://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 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 os
+
+from llnl.util.filesystem import *
+import llnl.util.tty as tty
+
+import spack
+import spack.modules
+
+# Character limit for shebang line. Using Linux's 127 characters
+# here, as it is the shortest I could find on a modern OS.
+shebang_limit = 127
+
+def shebang_too_long(path):
+ """Detects whether an file has a shebang line that is too long."""
+ with open(path, 'r') as script:
+ bytes = script.read(2)
+ if bytes != '#!':
+ return False
+
+ line = bytes + script.readline()
+ return len(line) > shebang_limit
+
+
+def filter_shebang(path):
+ """Adds a second shebang line, using sbang, at the beginning of a file."""
+ backup = path + ".shebang.bak"
+ os.rename(path, backup)
+
+ with open(backup, 'r') as bak_file:
+ original = bak_file.read()
+
+ with open(path, 'w') as new_file:
+ new_file.write('#!/bin/bash %s/bin/sbang\n' % spack.spack_root)
+ new_file.write(original)
+
+ copy_mode(backup, path)
+ unset_executable_mode(backup)
+
+ tty.warn("Patched overly long shebang in %s" % path)
+
+
+def post_install(pkg):
+ """This hook edits scripts so that they call /bin/bash
+ $spack_prefix/bin/sbang instead of something longer than the
+ shebang limit."""
+ if not os.path.isdir(pkg.prefix.bin):
+ return
+
+ for file in os.listdir(pkg.prefix.bin):
+ path = os.path.join(pkg.prefix.bin, file)
+ if shebang_too_long(path):
+ filter_shebang(path)
+
diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py
index 5ed7aff176..fdc4e7967f 100644
--- a/lib/spack/spack/mirror.py
+++ b/lib/spack/spack/mirror.py
@@ -73,7 +73,7 @@ def get_matching_versions(specs, **kwargs):
# Skip any package that has no known versions.
if not pkg.versions:
- tty.msg("No safe (checksummed) versions for package %s." % pkg.name)
+ tty.msg("No safe (checksummed) versions for package %s" % pkg.name)
continue
num_versions = kwargs.get('num_versions', 0)
@@ -214,7 +214,7 @@ def add_single_spec(spec, mirror_root, categories, **kwargs):
if spack.debug:
sys.excepthook(*sys.exc_info())
else:
- tty.warn("Error while fetching %s." % spec.format('$_$@'), e.message)
+ tty.warn("Error while fetching %s" % spec.format('$_$@'), e.message)
categories['error'].append(spec)
diff --git a/lib/spack/spack/multimethod.py b/lib/spack/spack/multimethod.py
index 51c6a8e89d..3cd17e796a 100644
--- a/lib/spack/spack/multimethod.py
+++ b/lib/spack/spack/multimethod.py
@@ -138,7 +138,7 @@ class when(object):
methods like install() that depend on the package's spec.
For example:
- .. code-block::
+ .. code-block:: python
class SomePackage(Package):
...
@@ -163,26 +163,28 @@ class when(object):
if you only have part of the install that is platform specific, you
could do this:
- class SomePackage(Package):
- ...
- # virtual dependence on MPI.
- # could resolve to mpich, mpich2, OpenMPI
- depends_on('mpi')
+ .. code-block:: python
- def setup(self):
- # do nothing in the default case
- pass
+ class SomePackage(Package):
+ ...
+ # virtual dependence on MPI.
+ # could resolve to mpich, mpich2, OpenMPI
+ depends_on('mpi')
- @when('^openmpi')
- def setup(self):
- # do something special when this is built with OpenMPI for
- # its MPI implementations.
+ def setup(self):
+ # do nothing in the default case
+ pass
+ @when('^openmpi')
+ def setup(self):
+ # do something special when this is built with OpenMPI for
+ # its MPI implementations.
- def install(self, prefix):
- # Do common install stuff
- self.setup()
- # Do more common install stuff
+
+ def install(self, prefix):
+ # Do common install stuff
+ self.setup()
+ # Do more common install stuff
There must be one (and only one) @when clause that matches the
package's spec. If there is more than one, or if none match,
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 106c546d5c..d4acbf5024 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -293,6 +293,7 @@ class Package(object):
.. code-block:: python
+ p.do_clean() # removes the stage directory entirely
p.do_restage() # removes the build directory and
# re-expands the archive.
@@ -455,7 +456,7 @@ class Package(object):
# Construct a composite stage on top of the composite FetchStrategy
composite_fetcher = self.fetcher
composite_stage = StageComposite()
- resources = self._get_resources()
+ resources = self._get_needed_resources()
for ii, fetcher in enumerate(composite_fetcher):
if ii == 0:
# Construct root stage first
@@ -466,6 +467,11 @@ class Package(object):
stage = self._make_resource_stage(composite_stage[0], fetcher, resource)
# Append the item to the composite
composite_stage.append(stage)
+
+ # Create stage on first access. Needed because fetch, stage,
+ # patch, and install can be called independently of each
+ # other, so `with self.stage:` in do_install isn't sufficient.
+ composite_stage.create()
return composite_stage
@property
@@ -484,12 +490,14 @@ class Package(object):
def _make_fetcher(self):
- # Construct a composite fetcher that always contains at least one element (the root package). In case there
- # are resources associated with the package, append their fetcher to the composite.
+ # Construct a composite fetcher that always contains at least
+ # one element (the root package). In case there are resources
+ # associated with the package, append their fetcher to the
+ # composite.
root_fetcher = fs.for_package_version(self, self.version)
fetcher = fs.FetchStrategyComposite() # Composite fetcher
fetcher.append(root_fetcher) # Root fetcher is always present
- resources = self._get_resources()
+ resources = self._get_needed_resources()
for resource in resources:
fetcher.append(resource.fetcher)
return fetcher
@@ -686,7 +694,7 @@ class Package(object):
if not ignore_checksum:
raise FetchError(
- "Will not fetch %s." % self.spec.format('$_$@'), checksum_msg)
+ "Will not fetch %s" % self.spec.format('$_$@'), checksum_msg)
self.stage.fetch(mirror_only)
@@ -706,6 +714,7 @@ class Package(object):
self.stage.expand_archive()
self.stage.chdir_to_source()
+
def do_patch(self):
"""Calls do_stage(), then applied patches to the expanded tarball if they
haven't been applied already."""
@@ -720,7 +729,7 @@ class Package(object):
# If there are no patches, note it.
if not self.patches and not has_patch_fun:
- tty.msg("No patches needed for %s." % self.name)
+ tty.msg("No patches needed for %s" % self.name)
return
# Construct paths to special files in the archive dir used to
@@ -743,7 +752,7 @@ class Package(object):
tty.msg("Already patched %s" % self.name)
return
elif os.path.isfile(no_patches_file):
- tty.msg("No patches needed for %s." % self.name)
+ tty.msg("No patches needed for %s" % self.name)
return
# Apply all the patches for specs that match this one
@@ -764,10 +773,10 @@ class Package(object):
if has_patch_fun:
try:
self.patch()
- tty.msg("Ran patch() for %s." % self.name)
+ tty.msg("Ran patch() for %s" % self.name)
patched = True
except:
- tty.msg("patch() function failed for %s." % self.name)
+ tty.msg("patch() function failed for %s" % self.name)
touch(bad_file)
raise
@@ -798,7 +807,7 @@ class Package(object):
mkdirp(self.prefix.man1)
- def _get_resources(self):
+ def _get_needed_resources(self):
resources = []
# Select the resources that are needed for this build
for when_spec, resource_list in self.resources.items():
@@ -816,7 +825,7 @@ class Package(object):
def do_install(self,
- keep_prefix=False, keep_stage=False, ignore_deps=False,
+ keep_prefix=False, keep_stage=None, ignore_deps=False,
skip_patch=False, verbose=False, make_jobs=None, fake=False):
"""Called by commands to install a package and its dependencies.
@@ -825,7 +834,8 @@ class Package(object):
Args:
keep_prefix -- Keep install prefix on failure. By default, destroys it.
- keep_stage -- Keep stage on successful build. By default, destroys it.
+ keep_stage -- Set to True or false to always keep or always delete stage.
+ By default, stage is destroyed only if there are no exceptions.
ignore_deps -- Do not install dependencies before installing this package.
fake -- Don't really build -- install fake stub files instead.
skip_patch -- Skip patch stage of build if True.
@@ -836,19 +846,32 @@ class Package(object):
raise ValueError("Can only install concrete packages.")
if os.path.exists(self.prefix):
- tty.msg("%s is already installed in %s." % (self.name, self.prefix))
+ tty.msg("%s is already installed in %s" % (self.name, self.prefix))
return
tty.msg("Installing %s" % self.name)
+ # First, install dependencies recursively.
if not ignore_deps:
self.do_install_dependencies(
keep_prefix=keep_prefix, keep_stage=keep_stage, ignore_deps=ignore_deps,
- fake=fake, skip_patch=skip_patch, verbose=verbose,
- make_jobs=make_jobs)
+ fake=fake, skip_patch=skip_patch, verbose=verbose, make_jobs=make_jobs)
- start_time = time.time()
- with self.stage:
+ def cleanup():
+ """Handles removing install prefix on error."""
+ if not keep_prefix:
+ self.remove_prefix()
+ else:
+ tty.warn("Keeping install prefix in place despite error.",
+ "Spack will think this package is installed. " +
+ "Manually remove this directory to fix:",
+ self.prefix, wrap=True)
+
+ # Then install the package itself.
+ def real_work():
+ """Forked for each build. Has its own process and python
+ module space set up by build_environment.fork()."""
+ start_time = time.time()
if not fake:
if not skip_patch:
self.do_patch()
@@ -860,28 +883,18 @@ class Package(object):
# package naming scheme it likes.
spack.install_layout.create_install_directory(self.spec)
- def cleanup():
- if not keep_prefix:
- # If anything goes wrong, remove the install prefix
- self.remove_prefix()
- else:
- tty.warn("Keeping install prefix in place despite error.",
- "Spack will think this package is installed." +
- "Manually remove this directory to fix:",
- self.prefix, wrap=True)
-
-
- def real_work():
- try:
- tty.msg("Building %s." % self.name)
+ try:
+ tty.msg("Building %s" % self.name)
+ self.stage.keep = keep_stage
+ with self.stage:
# Run the pre-install hook in the child process after
# the directory is created.
spack.hooks.pre_install(self)
- # Set up process's build environment before running install.
if fake:
self.do_fake_install()
+
else:
# Do the real install in the source directory.
self.stage.chdir_to_source()
@@ -889,62 +902,57 @@ class Package(object):
# Save the build environment in a file before building.
env_path = join_path(os.getcwd(), 'spack-build.env')
- # This redirects I/O to a build log (and optionally to the terminal)
+ # Redirect I/O to a build log (and optionally to the terminal)
log_path = join_path(os.getcwd(), 'spack-build.out')
log_file = open(log_path, 'w')
with log_output(log_file, verbose, sys.stdout.isatty(), True):
dump_environment(env_path)
self.install(self.spec, self.prefix)
- # Ensure that something was actually installed.
- self._sanity_check_install()
+ # Ensure that something was actually installed.
+ self._sanity_check_install()
- # Move build log into install directory on success
- if not fake:
+ # Copy provenance into the install directory on success
log_install_path = spack.install_layout.build_log_path(self.spec)
env_install_path = spack.install_layout.build_env_path(self.spec)
+ packages_dir = spack.install_layout.build_packages_path(self.spec)
+
install(log_path, log_install_path)
install(env_path, env_install_path)
+ dump_packages(self.spec, packages_dir)
- packages_dir = spack.install_layout.build_packages_path(self.spec)
- dump_packages(self.spec, packages_dir)
-
- # On successful install, remove the stage.
- if not keep_stage:
- self.stage.destroy()
-
- # Stop timer.
- self._total_time = time.time() - start_time
- build_time = self._total_time - self._fetch_time
+ # Stop timer.
+ self._total_time = time.time() - start_time
+ build_time = self._total_time - self._fetch_time
- tty.msg("Successfully installed %s." % self.name,
- "Fetch: %s. Build: %s. Total: %s."
- % (_hms(self._fetch_time), _hms(build_time), _hms(self._total_time)))
- print_pkg(self.prefix)
+ tty.msg("Successfully installed %s" % self.name,
+ "Fetch: %s. Build: %s. Total: %s."
+ % (_hms(self._fetch_time), _hms(build_time), _hms(self._total_time)))
+ print_pkg(self.prefix)
- except ProcessError as e:
- # Annotate with location of build log.
- e.build_log = log_path
- cleanup()
- raise e
+ except ProcessError as e:
+ # Annotate with location of build log.
+ e.build_log = log_path
+ cleanup()
+ raise e
- except:
- # other exceptions just clean up and raise.
- cleanup()
- raise
+ except:
+ # other exceptions just clean up and raise.
+ cleanup()
+ raise
- # Set parallelism before starting build.
- self.make_jobs = make_jobs
+ # Set parallelism before starting build.
+ self.make_jobs = make_jobs
- # Do the build.
- spack.build_environment.fork(self, real_work)
+ # Do the build.
+ spack.build_environment.fork(self, real_work)
- # note: PARENT of the build process adds the new package to
- # the database, so that we don't need to re-read from file.
- spack.installed_db.add(self.spec, self.prefix)
+ # note: PARENT of the build process adds the new package to
+ # the database, so that we don't need to re-read from file.
+ spack.installed_db.add(self.spec, self.prefix)
- # Once everything else is done, run post install hooks
- spack.hooks.post_install(self)
+ # Once everything else is done, run post install hooks
+ spack.hooks.post_install(self)
def _sanity_check_install(self):
@@ -1024,7 +1032,7 @@ class Package(object):
# Uninstalling in Spack only requires removing the prefix.
self.remove_prefix()
spack.installed_db.remove(self.spec)
- tty.msg("Successfully uninstalled %s." % self.spec.short_spec)
+ tty.msg("Successfully uninstalled %s" % self.spec.short_spec)
# Once everything else is done, run post install hooks
spack.hooks.post_uninstall(self)
@@ -1071,7 +1079,7 @@ class Package(object):
self.extendee_spec.package.activate(self, **self.extendee_args)
spack.install_layout.add_extension(self.extendee_spec, self.spec)
- tty.msg("Activated extension %s for %s."
+ tty.msg("Activated extension %s for %s"
% (self.spec.short_spec, self.extendee_spec.format("$_$@$+$%@")))
@@ -1123,7 +1131,7 @@ class Package(object):
if self.activated:
spack.install_layout.remove_extension(self.extendee_spec, self.spec)
- tty.msg("Deactivated extension %s for %s."
+ tty.msg("Deactivated extension %s for %s"
% (self.spec.short_spec, self.extendee_spec.format("$_$@$+$%@")))
@@ -1148,6 +1156,12 @@ class Package(object):
"""Reverts expanded/checked out source to a pristine state."""
self.stage.restage()
+
+ def do_clean(self):
+ """Removes the package's build stage and source tarball."""
+ self.stage.destroy()
+
+
def format_doc(self, **kwargs):
"""Wrap doc string at 72 characters and format nicely"""
indent = kwargs.get('indent', 0)
@@ -1202,8 +1216,8 @@ class Package(object):
@property
def rpath_args(self):
- """Get the rpath args as a string, with -Wl,-rpath= for each element."""
- return " ".join("-Wl,-rpath=%s" % p for p in self.rpath)
+ """Get the rpath args as a string, with -Wl,-rpath, for each element."""
+ return " ".join("-Wl,-rpath,%s" % p for p in self.rpath)
def validate_package_url(url_string):
@@ -1312,7 +1326,7 @@ class PackageVersionError(PackageError):
"""Raised when a version URL cannot automatically be determined."""
def __init__(self, version):
super(PackageVersionError, self).__init__(
- "Cannot determine a URL automatically for version %s." % version,
+ "Cannot determine a URL automatically for version %s" % version,
"Please provide a url for this version in the package.py file.")
diff --git a/lib/spack/spack/repository.py b/lib/spack/spack/repository.py
index 8d06fefe7f..3c3ba08bcc 100644
--- a/lib/spack/spack/repository.py
+++ b/lib/spack/spack/repository.py
@@ -156,7 +156,7 @@ class RepoPath(object):
if repo.namespace in self.by_namespace:
raise DuplicateRepoError(
- "Package repos '%s' and '%s' both provide namespace %s."
+ "Package repos '%s' and '%s' both provide namespace %s"
% (repo.root, self.by_namespace[repo.namespace].root, repo.namespace))
# Add repo to the pkg indexes
@@ -545,7 +545,7 @@ class Repo(object):
raise UnknownPackageError(spec.name)
if spec.namespace and spec.namespace != self.namespace:
- raise UnknownPackageError("Repository %s does not contain package %s."
+ raise UnknownPackageError("Repository %s does not contain package %s"
% (self.namespace, spec.fullname))
key = hash(spec)
@@ -825,7 +825,7 @@ class UnknownPackageError(PackageLoadError):
def __init__(self, name, repo=None):
msg = None
if repo:
- msg = "Package %s not found in repository %s." % (name, repo)
+ msg = "Package %s not found in repository %s" % (name, repo)
else:
msg = "Package %s not found." % name
super(UnknownPackageError, self).__init__(msg)
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index 985043c103..b117c76aa1 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -42,29 +42,53 @@ STAGE_PREFIX = 'spack-stage-'
class Stage(object):
- """
- A Stage object is a context manager that handles a directory where some source code is downloaded and built
- before being installed. It handles fetching the source code, either as an archive to be expanded or by checking
- it out of a repository. A stage's lifecycle looks like this:
+ """Manages a temporary stage directory for building.
+
+ A Stage object is a context manager that handles a directory where
+ some source code is downloaded and built before being installed.
+ It handles fetching the source code, either as an archive to be
+ expanded or by checking it out of a repository. A stage's
+ lifecycle looks like this:
+
+ ```
+ with Stage() as stage: # Context manager creates and destroys the stage directory
+ stage.fetch() # Fetch a source archive into the stage.
+ stage.expand_archive() # Expand the source archive.
+ <install> # Build and install the archive. (handled by user of Stage)
+ ```
+
+ When used as a context manager, the stage is automatically
+ destroyed if no exception is raised by the context. If an
+ excpetion is raised, the stage is left in the filesystem and NOT
+ destroyed, for potential reuse later.
+
+ You can also use the stage's create/destroy functions manually,
+ like this:
```
- with Stage() as stage: # Context manager creates and destroys the stage directory
- fetch() # Fetch a source archive into the stage.
- expand_archive() # Expand the source archive.
- <install> # Build and install the archive. This is handled by the Package class.
+ stage = Stage()
+ try:
+ stage.create() # Explicitly create the stage directory.
+ stage.fetch() # Fetch a source archive into the stage.
+ stage.expand_archive() # Expand the source archive.
+ <install> # Build and install the archive. (handled by user of Stage)
+ finally:
+ stage.destroy() # Explicitly destroy the stage directory.
```
- If spack.use_tmp_stage is True, spack will attempt to create stages in a tmp directory.
- Otherwise, stages are created directly in spack.stage_path.
+ If spack.use_tmp_stage is True, spack will attempt to create
+ stages in a tmp directory. Otherwise, stages are created directly
+ in spack.stage_path.
- There are two kinds of stages: named and unnamed. Named stages can persist between runs of spack, e.g. if you
- fetched a tarball but didn't finish building it, you won't have to fetch it again.
+ There are two kinds of stages: named and unnamed. Named stages
+ can persist between runs of spack, e.g. if you fetched a tarball
+ but didn't finish building it, you won't have to fetch it again.
- Unnamed stages are created using standard mkdtemp mechanisms or similar, and are intended to persist for
- only one run of spack.
+ Unnamed stages are created using standard mkdtemp mechanisms or
+ similar, and are intended to persist for only one run of spack.
"""
- def __init__(self, url_or_fetch_strategy, **kwargs):
+ def __init__(self, url_or_fetch_strategy, name=None, mirror_path=None, keep=None):
"""Create a stage object.
Parameters:
url_or_fetch_strategy
@@ -76,6 +100,18 @@ class Stage(object):
and will persist between runs (or if you construct another
stage object later). If name is not provided, then this
stage will be given a unique name automatically.
+
+ mirror_path
+ If provided, Stage will search Spack's mirrors for
+ this archive at the mirror_path, before using the
+ default fetch strategy.
+
+ keep
+ By default, when used as a context manager, the Stage
+ is cleaned up when everything goes well, and it is
+ kept intact when an exception is raised. You can
+ override this behavior by setting keep to True
+ (always keep) or False (always delete).
"""
# TODO: fetch/stage coupling needs to be reworked -- the logic
# TODO: here is convoluted and not modular enough.
@@ -91,15 +127,19 @@ class Stage(object):
# TODO : this uses a protected member of tempfile, but seemed the only way to get a temporary name
# TODO : besides, the temporary link name won't be the same as the temporary stage area in tmp_root
- self.name = kwargs.get('name') if 'name' in kwargs else STAGE_PREFIX + next(tempfile._get_candidate_names())
- self.mirror_path = kwargs.get('mirror_path')
+ self.name = name
+ if name is None:
+ self.name = STAGE_PREFIX + next(tempfile._get_candidate_names())
+ self.mirror_path = mirror_path
self.tmp_root = find_tmp_root()
# Try to construct here a temporary name for the stage directory
# If this is a named stage, then construct a named path.
self.path = join_path(spack.stage_path, self.name)
+
# Flag to decide whether to delete the stage folder on exit or not
- self.delete_on_exit = True
+ self.keep = keep
+
def __enter__(self):
"""
@@ -111,6 +151,7 @@ class Stage(object):
self.create()
return self
+
def __exit__(self, exc_type, exc_val, exc_tb):
"""
Exiting from a stage context will delete the stage directory unless:
@@ -125,11 +166,15 @@ class Stage(object):
Returns:
Boolean
"""
- self.delete_on_exit = False if exc_type is not None else self.delete_on_exit
+ if self.keep is None:
+ # Default: delete when there are no exceptions.
+ if exc_type is None: self.destroy()
- if self.delete_on_exit:
+ elif not self.keep:
+ # Overridden. Either always keep or always delete.
self.destroy()
+
def _need_to_create_path(self):
"""Makes sure nothing weird has happened since the last time we
looked at path. Returns True if path already exists and is ok.
@@ -201,7 +246,7 @@ class Stage(object):
if os.path.isdir(self.path):
os.chdir(self.path)
else:
- tty.die("Setup failed: no such directory: " + self.path)
+ raise ChdirError("Setup failed: no such directory: " + self.path)
def fetch(self, mirror_only=False):
"""Downloads an archive or checks out code from a repository."""
@@ -276,9 +321,9 @@ class Stage(object):
archive_dir = self.source_path
if not archive_dir:
self.fetcher.expand()
- tty.msg("Created stage in %s." % self.path)
+ tty.msg("Created stage in %s" % self.path)
else:
- tty.msg("Already staged %s in %s." % (self.name, self.path))
+ tty.msg("Already staged %s in %s" % (self.name, self.path))
def chdir_to_source(self):
"""Changes directory to the expanded archive directory.
@@ -302,11 +347,14 @@ class Stage(object):
"""
Creates the stage directory
- If self.tmp_root evaluates to False, the stage directory is created directly under spack.stage_path, otherwise
- this will attempt to create a stage in a temporary directory and link it into spack.stage_path.
+ If self.tmp_root evaluates to False, the stage directory is
+ created directly under spack.stage_path, otherwise this will
+ attempt to create a stage in a temporary directory and link it
+ into spack.stage_path.
- Spack will use the first writable location in spack.tmp_dirs to create a stage. If there is no valid location
- in tmp_dirs, fall back to making the stage inside spack.stage_path.
+ Spack will use the first writable location in spack.tmp_dirs
+ to create a stage. If there is no valid location in tmp_dirs,
+ fall back to making the stage inside spack.stage_path.
"""
# Create the top-level stage directory
mkdirp(spack.stage_path)
@@ -323,9 +371,7 @@ class Stage(object):
ensure_access(self.path)
def destroy(self):
- """
- Removes this stage directory
- """
+ """Removes this stage directory."""
remove_linked_tree(self.path)
# Make sure we don't end up in a removed directory
@@ -370,7 +416,7 @@ class ResourceStage(Stage):
shutil.move(source_path, destination_path)
-@pattern.composite(method_list=['fetch', 'check', 'expand_archive', 'restage', 'destroy'])
+@pattern.composite(method_list=['fetch', 'create', 'check', 'expand_archive', 'restage', 'destroy'])
class StageComposite:
"""
Composite for Stage type objects. The first item in this composite is considered to be the root package, and
@@ -410,7 +456,7 @@ class DIYStage(object):
if os.path.isdir(self.path):
os.chdir(self.path)
else:
- tty.die("Setup failed: no such directory: " + self.path)
+ raise ChdirError("Setup failed: no such directory: " + self.path)
def chdir_to_source(self):
self.chdir()
@@ -472,19 +518,15 @@ def find_tmp_root():
class StageError(spack.error.SpackError):
- def __init__(self, message, long_message=None):
- super(self, StageError).__init__(message, long_message)
+ """"Superclass for all errors encountered during staging."""
class RestageError(StageError):
- def __init__(self, message, long_msg=None):
- super(RestageError, self).__init__(message, long_msg)
+ """"Error encountered during restaging."""
class ChdirError(StageError):
- def __init__(self, message, long_msg=None):
- super(ChdirError, self).__init__(message, long_msg)
-
+ """Raised when Spack can't change directories."""
# Keep this in namespace for convenience
FailedDownloadError = fs.FailedDownloadError
diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py
index 905af28a06..f3f6d4a22e 100644
--- a/lib/spack/spack/test/cc.py
+++ b/lib/spack/spack/test/cc.py
@@ -39,11 +39,11 @@ test_command = [
'arg1',
'-Wl,--start-group',
'arg2',
- '-Wl,-rpath=/first/rpath', 'arg3', '-Wl,-rpath', '-Wl,/second/rpath',
+ '-Wl,-rpath,/first/rpath', 'arg3', '-Wl,-rpath', '-Wl,/second/rpath',
'-llib1', '-llib2',
'arg4',
'-Wl,--end-group',
- '-Xlinker,-rpath', '-Xlinker,/third/rpath', '-Xlinker,-rpath=/fourth/rpath',
+ '-Xlinker', '-rpath', '-Xlinker', '/third/rpath', '-Xlinker', '-rpath', '-Xlinker', '/fourth/rpath',
'-llib3', '-llib4',
'arg5', 'arg6']
@@ -95,13 +95,13 @@ class CompilerTest(unittest.TestCase):
def test_ccld_mode(self):
self.check_cc('dump-mode', [], "ccld")
self.check_cc('dump-mode', ['foo.c', '-o', 'foo'], "ccld")
- self.check_cc('dump-mode', ['foo.c', '-o', 'foo', '-Wl,-rpath=foo'], "ccld")
- self.check_cc('dump-mode', ['foo.o', 'bar.o', 'baz.o', '-o', 'foo', '-Wl,-rpath=foo'], "ccld")
+ self.check_cc('dump-mode', ['foo.c', '-o', 'foo', '-Wl,-rpath,foo'], "ccld")
+ self.check_cc('dump-mode', ['foo.o', 'bar.o', 'baz.o', '-o', 'foo', '-Wl,-rpath,foo'], "ccld")
def test_ld_mode(self):
self.check_ld('dump-mode', [], "ld")
- self.check_ld('dump-mode', ['foo.o', 'bar.o', 'baz.o', '-o', 'foo', '-Wl,-rpath=foo'], "ld")
+ self.check_ld('dump-mode', ['foo.o', 'bar.o', 'baz.o', '-o', 'foo', '-Wl,-rpath,foo'], "ld")
def test_includes(self):
diff --git a/var/spack/repos/builtin/packages/blitz/package.py b/var/spack/repos/builtin/packages/blitz/package.py
new file mode 100644
index 0000000000..9413b276fe
--- /dev/null
+++ b/var/spack/repos/builtin/packages/blitz/package.py
@@ -0,0 +1,15 @@
+from spack import *
+
+class Blitz(Package):
+ """N-dimensional arrays for C++"""
+ homepage = "http://github.com/blitzpp/blitz"
+ url = "https://github.com/blitzpp/blitz/tarball/1.0.0"
+
+ version('1.0.0', '9f040b9827fe22228a892603671a77af')
+
+ # No dependencies
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix)
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/jdk/package.py b/var/spack/repos/builtin/packages/jdk/package.py
index f8f5fc21bd..cbcc53ac0a 100644
--- a/var/spack/repos/builtin/packages/jdk/package.py
+++ b/var/spack/repos/builtin/packages/jdk/package.py
@@ -28,7 +28,7 @@ class Jdk(Package):
'-H', # specify required License Agreement cookie
'Cookie: oraclelicense=accept-securebackup-cookie']
- def do_fetch(self):
+ def do_fetch(self, mirror_only=False):
# Add our custom curl commandline options
tty.msg(
"[Jdk] Adding required commandline options to curl " +
@@ -39,7 +39,7 @@ class Jdk(Package):
spack.curl.add_default_arg(option)
# Now perform the actual fetch
- super(Jdk, self).do_fetch()
+ super(Jdk, self).do_fetch(mirror_only)
def install(self, spec, prefix):
diff --git a/var/spack/repos/builtin/packages/libevent/package.py b/var/spack/repos/builtin/packages/libevent/package.py
index 11b1083d67..714a155dc0 100644
--- a/var/spack/repos/builtin/packages/libevent/package.py
+++ b/var/spack/repos/builtin/packages/libevent/package.py
@@ -22,9 +22,16 @@ class Libevent(Package):
version('2.0.13', 'af786b4b3f790c9d3279792edf7867fc')
version('2.0.12', '42986228baf95e325778ed328a93e070')
+ variant('openssl', default=True, description="Build with encryption enabled at the libevent level.")
+ depends_on('openssl', when='+openssl')
def install(self, spec, prefix):
- configure("--prefix=%s" % prefix)
+ configure_args = []
+ if '+openssl' in spec:
+ configure_args.append('--enable-openssl')
+ else:
+ configure_args.append('--enable-openssl')
+ configure("--prefix=%s" % prefix, *configure_args)
make()
make("install")
diff --git a/var/spack/repos/builtin/packages/libsigsegv/package.py b/var/spack/repos/builtin/packages/libsigsegv/package.py
new file mode 100644
index 0000000000..4b486198ec
--- /dev/null
+++ b/var/spack/repos/builtin/packages/libsigsegv/package.py
@@ -0,0 +1,15 @@
+from spack import *
+
+class Libsigsegv(Package):
+ """GNU libsigsegv is a library for handling page faults in user mode."""
+ homepage = "https://www.gnu.org/software/libsigsegv/"
+ url = "ftp://ftp.gnu.org/gnu/libsigsegv/libsigsegv-2.10.tar.gz"
+
+ version('2.10', '7f96fb1f65b3b8cbc1582fb7be774f0f')
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix,
+ '--enable-shared')
+
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/llvm/package.py b/var/spack/repos/builtin/packages/llvm/package.py
index 934d994bd3..280e400f69 100644
--- a/var/spack/repos/builtin/packages/llvm/package.py
+++ b/var/spack/repos/builtin/packages/llvm/package.py
@@ -1,5 +1,5 @@
##############################################################################
-# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Copyright (c) 2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
@@ -34,7 +34,7 @@ class Llvm(Package):
it is the full name of the project.
"""
homepage = 'http://llvm.org/'
- url = 'http://llvm.org/releases/3.7.0/llvm-3.7.0.src.tar.xz'
+ url = 'http://llvm.org/releases/3.7.1/llvm-3.7.1.src.tar.xz'
version('3.0', 'a8e5f5f1c1adebae7b4a654c376a6005', url='http://llvm.org/releases/3.0/llvm-3.0.tar.gz') # currently required by mesa package
@@ -133,6 +133,21 @@ class Llvm(Package):
}
},
{
+ 'version' : '3.7.1',
+ 'md5':'bf8b3a2c79e61212c5409041dfdbd319',
+ 'resources' : {
+ 'compiler-rt' : '1c6975daf30bb3b0473b53c3a1a6ff01',
+ 'openmp' : 'b4ad08cda4e5c22e42b66062b140438e',
+ 'polly' : '3a2a7367002740881637f4d47bca4dc3',
+ 'libcxx' : 'f9c43fa552a10e14ff53b94d04bea140',
+ 'libcxxabi' : '52d925afac9f97e9dcac90745255c169',
+ 'clang' : '0acd026b5529164197563d135a8fd83e',
+ 'clang-tools-extra' : '5d49ff745037f061a7c86aeb6a24c3d2',
+ 'lldb' : 'a106d8a0d21fc84d76953822fbaf3398',
+ 'llvm-libunwind' : '814bd52c9247c5d04629658fbcb3ab8c',
+ }
+ },
+ {
'version' : '3.7.0',
'md5':'b98b9495e5655a672d6cb83e1a180f8e',
'resources' : {
diff --git a/var/spack/repos/builtin/packages/m4/package.py b/var/spack/repos/builtin/packages/m4/package.py
index 5d76d8866b..d6829dbcd4 100644
--- a/var/spack/repos/builtin/packages/m4/package.py
+++ b/var/spack/repos/builtin/packages/m4/package.py
@@ -7,7 +7,17 @@ class M4(Package):
version('1.4.17', 'a5e9954b1dae036762f7b13673a2cf76')
+ variant('sigsegv', default=True, description="Build the libsigsegv dependency")
+
+ depends_on('libsigsegv', when='+sigsegv')
+
def install(self, spec, prefix):
- configure("--prefix=%s" % prefix)
+ configure_args = []
+ if 'libsigsegv' in spec:
+ configure_args.append('--with-libsigsegv-prefix=%s' % spec['libsigsegv'].prefix)
+ else:
+ configure_args.append('--without-libsigsegv-prefix')
+
+ configure("--prefix=%s" % prefix, *configure_args)
make()
make("install")
diff --git a/var/spack/repos/builtin/packages/mpc/package.py b/var/spack/repos/builtin/packages/mpc/package.py
index 50477a0ccb..108fec678f 100644
--- a/var/spack/repos/builtin/packages/mpc/package.py
+++ b/var/spack/repos/builtin/packages/mpc/package.py
@@ -37,6 +37,12 @@ class Mpc(Package):
depends_on("gmp")
depends_on("mpfr")
+ def url_for_version(self, version):
+ if version < Version("1.0.1"):
+ return "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % version
+ else:
+ return "ftp://ftp.gnu.org/gnu/mpc/mpc-%s.tar.gz" % version
+
def install(self, spec, prefix):
configure("--prefix=%s" % prefix)
make()
diff --git a/var/spack/repos/builtin/packages/netcdf-cxx4/package.py b/var/spack/repos/builtin/packages/netcdf-cxx4/package.py
new file mode 100644
index 0000000000..b83e964b00
--- /dev/null
+++ b/var/spack/repos/builtin/packages/netcdf-cxx4/package.py
@@ -0,0 +1,15 @@
+from spack import *
+
+class NetcdfCxx4(Package):
+ """C++ interface for NetCDF4"""
+ homepage = "http://www.unidata.ucar.edu/software/netcdf"
+ url = "http://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-cxx4-4.2.tar.gz"
+
+ version('4.2', 'd019853802092cf686254aaba165fc81')
+
+ depends_on('netcdf')
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix)
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/netcdf-fortran/package.py b/var/spack/repos/builtin/packages/netcdf-fortran/package.py
new file mode 100644
index 0000000000..e4e33445e5
--- /dev/null
+++ b/var/spack/repos/builtin/packages/netcdf-fortran/package.py
@@ -0,0 +1,16 @@
+from spack import *
+
+class NetcdfFortran(Package):
+ """Fortran interface for NetCDF4"""
+
+ homepage = "http://www.unidata.ucar.edu/software/netcdf"
+ url = "http://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-fortran-4.4.3.tar.gz"
+
+ version('4.4.3', 'bfd4ae23a34635b273d3eb0d91cbde9e')
+
+ depends_on('netcdf')
+
+ def install(self, spec, prefix):
+ configure("--prefix=%s" % prefix)
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/netcdf/package.py b/var/spack/repos/builtin/packages/netcdf/package.py
index 41a0d2b6f9..227362399a 100644
--- a/var/spack/repos/builtin/packages/netcdf/package.py
+++ b/var/spack/repos/builtin/packages/netcdf/package.py
@@ -6,14 +6,13 @@ class Netcdf(Package):
data formats that support the creation, access, and sharing of array-oriented
scientific data."""
- homepage = "http://www.unidata.ucar.edu/software/netcdf/"
+ homepage = "http://www.unidata.ucar.edu/software/netcdf"
url = "ftp://ftp.unidata.ucar.edu/pub/netcdf/netcdf-4.3.3.tar.gz"
version('4.4.0', 'cffda0cbd97fdb3a06e9274f7aef438e')
version('4.3.3', '5fbd0e108a54bd82cb5702a73f56d2ae')
variant('mpi', default=True, description='Enables MPI parallelism')
- variant('fortran', default=False, description="Download and install NetCDF-Fortran")
variant('hdf4', default=False, description="Enable HDF4 support")
# Dependencies:
@@ -66,11 +65,7 @@ class Netcdf(Package):
# Fortran support
# In version 4.2+, NetCDF-C and NetCDF-Fortran have split.
- # They can be installed separately, but this bootstrap procedure
- # should be able to install both at the same time.
- # Note: this is a new experimental feature.
- if '+fortran' in spec:
- config_args.append("--enable-remote-fortran-bootstrap")
+ # Use the netcdf-fortran package to install Fortran support.
config_args.append('CPPFLAGS=%s' % ' '.join(CPPFLAGS))
config_args.append('LDFLAGS=%s' % ' '.join(LDFLAGS))
@@ -79,8 +74,3 @@ class Netcdf(Package):
configure(*config_args)
make()
make("install")
-
- # After installing NetCDF-C, install NetCDF-Fortran
- if '+fortran' in spec:
- make("build-netcdf-fortran")
- make("install-netcdf-fortran")
diff --git a/var/spack/repos/builtin/packages/openssl/package.py b/var/spack/repos/builtin/packages/openssl/package.py
index c73102f05d..70afaf4038 100644
--- a/var/spack/repos/builtin/packages/openssl/package.py
+++ b/var/spack/repos/builtin/packages/openssl/package.py
@@ -17,6 +17,7 @@ class Openssl(Package):
version('1.0.2d', '38dd619b2e77cbac69b99f52a053d25a')
version('1.0.2e', '5262bfa25b60ed9de9f28d5d52d77fc5')
version('1.0.2f', 'b3bf73f507172be9292ea2a8c28b659d')
+ version('1.0.2g', 'f3c710c045cdee5fd114feb69feba7aa')
depends_on("zlib")
parallel = False
diff --git a/var/spack/repos/builtin/packages/proj/package.py b/var/spack/repos/builtin/packages/proj/package.py
new file mode 100644
index 0000000000..797772f4f6
--- /dev/null
+++ b/var/spack/repos/builtin/packages/proj/package.py
@@ -0,0 +1,20 @@
+from spack import *
+
+class Proj(Package):
+ """Cartographic Projections"""
+ homepage = "https://github.com/OSGeo/proj.4/wiki"
+ url = "http://download.osgeo.org/proj/proj-4.9.2.tar.gz"
+
+ version('4.9.2', '9843131676e31bbd903d60ae7dc76cf9')
+ version('4.9.1', '3cbb2a964fd19a496f5f4265a717d31c')
+ version('4.8.0', 'd815838c92a29179298c126effbb1537')
+ version('4.7.0', '927d34623b52e0209ba2bfcca18fe8cd')
+ version('4.6.1', '7dbaab8431ad50c25669fd3fb28dc493')
+
+ # No dependencies
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix)
+
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/udunits2/package.py b/var/spack/repos/builtin/packages/udunits2/package.py
new file mode 100644
index 0000000000..9954a733bb
--- /dev/null
+++ b/var/spack/repos/builtin/packages/udunits2/package.py
@@ -0,0 +1,16 @@
+from spack import *
+
+class Udunits2(Package):
+ """Automated units conversion"""
+
+ homepage = "http://www.unidata.ucar.edu/software/udunits"
+ url = "ftp://ftp.unidata.ucar.edu/pub/udunits/udunits-2.2.20.tar.gz"
+
+ version('2.2.20', '1586b70a49dfe05da5fcc29ef239dce0')
+
+ depends_on('expat')
+
+ def install(self, spec, prefix):
+ configure("--prefix=%s" % prefix)
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/zfp/package.py b/var/spack/repos/builtin/packages/zfp/package.py
new file mode 100644
index 0000000000..620fe9d456
--- /dev/null
+++ b/var/spack/repos/builtin/packages/zfp/package.py
@@ -0,0 +1,26 @@
+from spack import *
+
+class Zfp(Package):
+ """zfp is an open source C library for compressed floating-point arrays that supports
+ very high throughput read and write random acces, target error bounds or bit rates.
+ Although bit-for-bit lossless compression is not always possible, zfp is usually
+ accurate to within machine epsilon in near-lossless mode, and is often orders of
+ magnitude more accurate than other lossy compressors.
+ """
+
+ homepage = "http://computation.llnl.gov/projects/floating-point-compression"
+ url = "http://computation.llnl.gov/projects/floating-point-compression/download/zfp-0.5.0.tar.gz"
+
+ version('0.5.0', '2ab29a852e65ad85aae38925c5003654')
+
+ def install(self, spec, prefix):
+ make("shared")
+
+ # No install provided
+ mkdirp(prefix.lib)
+ mkdirp(prefix.include)
+ install('lib/libzfp.so', prefix.lib)
+ install('inc/zfp.h', prefix.include)
+ install('inc/types.h', prefix.include)
+ install('inc/bitstream.h', prefix.include)
+ install('inc/system.h', prefix.include)