summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/docs/basic_usage.rst716
-rw-r--r--lib/spack/docs/conf.py4
-rw-r--r--lib/spack/docs/packaging_guide.rst309
-rw-r--r--lib/spack/llnl/util/tty/colify.py9
-rw-r--r--lib/spack/spack/cmd/activate.py2
-rw-r--r--lib/spack/spack/cmd/deactivate.py5
-rw-r--r--lib/spack/spack/cmd/package-list.py2
-rw-r--r--lib/spack/spack/cmd/uninstall.py1
-rw-r--r--lib/spack/spack/package.py17
9 files changed, 764 insertions, 301 deletions
diff --git a/lib/spack/docs/basic_usage.rst b/lib/spack/docs/basic_usage.rst
index 196b7077f9..bd25d739ea 100644
--- a/lib/spack/docs/basic_usage.rst
+++ b/lib/spack/docs/basic_usage.rst
@@ -4,18 +4,17 @@ Basic usage
=====================
Spack is implemented as a single command (``spack``) with many
-*subcommands*, much like ``git``, ``svn``, ``yum``, or ``apt-get``.
-Only a small subset of commands are needed for typical usage.
-
-This section covers a small set of subcommands that should cover most
-general use cases for Spack.
+*subcommands*. Only a small subset of commands is needed for typical
+usage.
Listing available packages
------------------------------
-The first thing you will likely want to do with spack is find out what
-software is available to install. There are a few relevant commands.
+The first thing you likely want to do with spack is to install some
+software. Before that, you need to know what's available. You can
+see avaialble package names either using the :ref:`package-list`, or
+using the commands below.
``spack list``
~~~~~~~~~~~~~~~~
@@ -36,33 +35,273 @@ do wildcard searches using ``*``:
``spack info``
~~~~~~~~~~~~~~~~
-To get information on a particular package from the full list, run
-``spack info <package name>``. For example, for ``mpich`` the output
-looks like this:
+To get more information on a particular package from `spack list`, use
+`spack info`. Just supply the name of a package:
.. command-output:: spack info mpich
-This includes basic information about the package: where to download
-it, its dependencies, virtual packages it provides (e.g. an MPI
-implementation will provide the MPI interface), and a text
-description, if one is available. :ref:`Dependencies
-<sec-specs>` and :ref:`virtual dependencies
-<sec-virtual-dependencies>` are described in more detail later.
+Most of the information is self-explanatory. *Safe versions* are
+versions that Spack has a checksum for, and Spack will use the
+checksum to ensure they downloaded without any errors or malicious
+attacks. :ref:`Dependencies <sec-specs>` and :ref:`virtual
+dependencies <sec-virtual-dependencies>`, are described in more detail
+later.
``spack versions``
~~~~~~~~~~~~~~~~~~~~~~~~
-To see available versions of a package, run ``spack versions``, for
-example:
+To see *more* available versions of a package, run ``spack versions``,
+for example:
.. command-output:: spack versions libelf
-Since it has to manage many different software packages, Spack doesn't
-place many restrictions on what a package version has to look like.
-Packages like ``mpich`` use traditional version numbers like
-``3.0.4``. Other packages, like ``libdwarf`` use date-stamp versions
-like ``20130729``. Versions can contain numbers, letters, dashes,
-underscores, and periods.
+There are two sections in the output. *Safe versions* are ones that
+have already been checksummed. Spack goes a step further, though, and
+also shows you what versions are available out on the web---these are
+*remote versions*. Spack gets this information by scraping it
+directly from webpages. Depending on the package, Spack may or may
+not be able to find any remote versions.
+
+
+Installing and uninstalling
+------------------------------
+
+Now that you know how to list avaiable packages and versions, you're
+ready to start installing things.
+
+``spack install``
+~~~~~~~~~~~~~~~~~~~~~
+
+``spack install`` will install any package shown by ``spack list``.
+To install the latest version of a pacakge, along with all of its
+dependencies, simply give it a package name:
+
+.. code-block:: sh
+
+ $ spack install mpileaks
+
+If `mpileaks` depends on other packages, Spack will install those
+first. It then fetches the tarball for ``mpileaks``, expands it,
+verifies that it was downloaded without errors, builds it, and
+installs it in its own directory under ``$SPACK_HOME/opt``. You'll see
+a number of messages from spack, a lot of build output, and a message
+that the packages is installed:
+
+.. code-block:: sh
+
+ $ spack install mpileaks
+ ==> Installing mpileaks
+ ==> mpich is already installed in /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/mpich@3.0.4.
+ ==> callpath is already installed in /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/callpath@1.0.2-5dce4318.
+ ==> adept-utils is already installed in /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/adept-utils@1.0-5adef8da.
+ ==> Trying to fetch from https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz
+ ######################################################################## 100.0%
+ ==> Staging archive: /home/gamblin2/spack/var/spack/stage/mpileaks@1.0%gcc@4.4.7=chaos_5_x86_64_ib-59f6ad23/mpileaks-1.0.tar.gz
+ ==> Created stage in /home/gamblin2/spack/var/spack/stage/mpileaks@1.0%gcc@4.4.7=chaos_5_x86_64_ib-59f6ad23.
+ ==> No patches needed for mpileaks.
+ ==> Building mpileaks.
+
+ ... build output ...
+
+ ==> Successfully installed mpileaks.
+ Fetch: 2.16s. Build: 9.82s. Total: 11.98s.
+ [+] /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/mpileaks@1.0-59f6ad23
+
+The last line, with the ``[+]``, indicates where the package is
+installed.
+
+Building a specific version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Spack can also build *specific versions* of a package. To do this,
+just add ``@`` after the package name, followed by a version:
+
+.. code-block:: sh
+
+ $ spack install mpich@3.0.4
+
+Any number of versions of the same package can be installed at once
+without interfering with each other. This is good for multi-user
+sites, as installing a version that one user needs will not disrupt
+existing installations for other users.
+
+In addition to different versions, Spack can customize the compiler,
+compile-time options (variants), and platform (for cross compiles) of
+an installation. Spack is unique in that it can also configure the
+*dependencies* a package is built with. For example, two
+configurations of the same version of a package, one built with boost
+1.39.0, and the other version built with version 1.43.0, can coexist.
+
+This can all be done on the command line using special syntax. Spack
+calls the descriptor used to refer to a particular package
+configuration a **spec**. In the command lines above, both
+``mpileaks`` and ``mpileaks@3.0.4`` are specs. Specs are described in
+detail in :ref:`sec-specs`.
+
+
+``spack uninstall``
+~~~~~~~~~~~~~~~~~~~~~
+
+To uninstall a package, type ``spack uninstall <package>``. This will
+completely remove the directory in which the package was installed.
+
+.. code-block:: sh
+
+ spack uninstall mpich
+
+If there are still installed packages that depend on the package to be
+uninstalled, spack will refuse to uninstall it. You can override this
+behavior with ``spack uninstall -f <package>``, but you risk breaking
+other installed packages. In general, it is safer to remove dependent
+packages *before* removing their dependencies.
+
+A line like ``spack uninstall mpich`` may be ambiguous, if multiple
+``mpich`` configurations are installed. For example, if both
+``mpich@3.0.2`` and ``mpich@3.1`` are installed, ``mpich`` could refer
+to either one. Because it cannot determine which one to uninstall,
+Spack will ask you to provide a version number to remove the
+ambiguity. As an example, ``spack uninstall mpich@3.1`` is
+unambiguous in this scenario.
+
+
+Seeing installed packages
+-----------------------------------
+
+We know that ``spack list`` shows you the names of available packages,
+but how do you figure out which are installed?
+
+
+``spack find``
+~~~~~~~~~~~~~~~~~~~~~~
+
+``spack find`` shows the *specs* of installed packages. A spec is
+like a name, but it has a version, compiler, architecture, and build
+options associated with it. In spack, you can have many installations
+of the same package with different specs.
+
+Running ``spack find`` with no arguments lists installed packages:
+
+.. code-block:: sh
+
+ $ spack find
+ ==> 74 installed packages.
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ ImageMagick@6.8.9-10 libdwarf@20130729 py-dateutil@2.4.0
+ adept-utils@1.0 libdwarf@20130729 py-ipython@2.3.1
+ atk@2.14.0 libelf@0.8.12 py-matplotlib@1.4.2
+ boost@1.55.0 libelf@0.8.13 py-nose@1.3.4
+ bzip2@1.0.6 libffi@3.1 py-numpy@1.9.1
+ cairo@1.14.0 libmng@2.0.2 py-pygments@2.0.1
+ callpath@1.0.2 libpng@1.6.16 py-pyparsing@2.0.3
+ cmake@3.0.2 libtiff@4.0.3 py-pyside@1.2.2
+ dbus@1.8.6 libtool@2.4.2 py-pytz@2014.10
+ dbus@1.9.0 libxcb@1.11 py-setuptools@11.3.1
+ dyninst@8.1.2 libxml2@2.9.2 py-six@1.9.0
+ fontconfig@2.11.1 libxml2@2.9.2 python@2.7.8
+ freetype@2.5.3 llvm@3.0 qhull@1.0
+ gdk-pixbuf@2.31.2 memaxes@0.5 qt@4.8.6
+ glib@2.42.1 mesa@8.0.5 qt@5.4.0
+ graphlib@2.0.0 mpich@3.0.4 readline@6.3
+ gtkplus@2.24.25 mpileaks@1.0 sqlite@3.8.5
+ harfbuzz@0.9.37 mrnet@4.1.0 stat@2.1.0
+ hdf5@1.8.13 ncurses@5.9 tcl@8.6.3
+ icu@54.1 netcdf@4.3.3 tk@src
+ jpeg@9a openssl@1.0.1h vtk@6.1.0
+ launchmon@1.0.1 pango@1.36.8 xcb-proto@1.11
+ lcms@2.6 pixman@0.32.6 xz@5.2.0
+ libdrm@2.4.33 py-dateutil@2.4.0 zlib@1.2.8
+
+ -- chaos_5_x86_64_ib / gcc@4.9.2 --------------------------------
+ libelf@0.8.10 mpich@3.0.4
+
+Packages are divided into groups according to their architecture and
+compiler. Within each group, Spack tries to keep the view simple, and
+only shows the version of installed packages.
+
+In some cases, there may be differnt configurations of the *same*
+version of a package installed. For example, there are two
+installations of of ``libdwarf@20130729`` above. We can look at them
+in more detail using ``spack find -d``, and by asking only to show
+``libdwarf`` packages:
+
+.. code-block:: sh
+
+ $ spack find --deps libdwarf
+ ==> 2 installed packages.
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ libdwarf@20130729-d9b90962
+ ^libelf@0.8.12
+ libdwarf@20130729-b52fac98
+ ^libelf@0.8.13
+
+Now we see that the two instances of ``libdwarf`` depend on
+*different* versions of ``libelf``: 0.8.12 and 0.8.13. This view can
+become complicated for packages with many dependencies. If you just
+want to know whether two packages' dependencies differ, you can use
+``spack find -l``:
+
+.. code-block:: sh
+
+ $ spack find -l libdwarf
+ ==> 2 installed packages.
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ libdwarf@20130729-d9b90962 libdwarf@20130729-b52fac98
+
+Now the ``libwarf`` installs have hashes after their names. These are
+hashes over all of the dependencies of each package. If the hashes
+are the same, then the packages have the same dependency configuration.
+
+If you want to know the path where each package is installed, you can
+use ``spack find -p``:
+
+.. code-block:: sh
+
+ $ spack find -p
+ ==> 74 installed packages.
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ ImageMagick@6.8.9-10 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/ImageMagick@6.8.9-10-4df950dd
+ adept-utils@1.0 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/adept-utils@1.0-5adef8da
+ atk@2.14.0 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/atk@2.14.0-3d09ac09
+ boost@1.55.0 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/boost@1.55.0
+ bzip2@1.0.6 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/bzip2@1.0.6
+ cairo@1.14.0 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/cairo@1.14.0-fcc2ab44
+ callpath@1.0.2 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/callpath@1.0.2-5dce4318
+ ...
+
+And, finally, you can restrict your search to a particular package
+by supplying its name:
+
+.. code-block:: sh
+
+ $ spack find -p libelf
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ libelf@0.8.11 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.11
+ libelf@0.8.12 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.12
+ libelf@0.8.13 /home/gamblin2/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.13
+
+``spack find`` actually does a lot more than this. You can use
+*specs* to query for specific configurations and builds of each
+package. If you want to find only libelf versions greater than version
+0.8.12, you could say:
+
+.. code-block:: sh
+
+ $ spack find libelf@0.8.12:
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ libelf@0.8.12 libelf@0.8.13
+
+Finding just the versions of libdwarf built with a particular version
+of libelf would look like this:
+
+.. code-block:: sh
+
+ $ spack find -l libdwarf ^libelf@0.8.12
+ ==> 1 installed packages.
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ libdwarf@20130729-d9b90962
+
+The full spec syntax is discussed in detail in :ref:`sec-specs`.
+
Compiler Configuration
-----------------------------------
@@ -110,15 +349,18 @@ where the compiler is installed. For example::
intel@13.0.079
Or you can run ``spack compiler add`` with no arguments to force
-autodetection. This is useful if you do not know where compilers
-live, but new compilers have been added to your ``PATH``. For
-example, using dotkit, you might do this::
+autodetection. This is useful if you do not know where compilers are
+installed, but you know that new compilers have been added to your
+``PATH``. For example, using dotkit, you might do this::
- $ use gcc-4.9.0
+ $ module load gcc-4.9.0
$ spack compiler add
==> Added 1 new compiler to /Users/gamblin2/.spackconfig
gcc@4.9.0
+This loads the environment module for gcc-4.9.0 to get it into the
+``PATH``, and then it adds the compiler to Spack.
+
``spack compiler info``
~~~~~~~~~~~~~~~~~~~~~~~
@@ -126,17 +368,20 @@ example, using dotkit, you might do this::
If you want to see specifics on a particular compiler, you can run
``spack compiler info`` on it::
- $ spack compiler info intel@12.1.3
- intel@12.1.3:
- cc = /usr/local/bin/icc-12.1.293
- cxx = /usr/local/bin/icpc-12.1.293
- f77 = /usr/local/bin/ifort-12.1.293
- fc = /usr/local/bin/ifort-12.1.293
+ $ spack compiler info intel@15
+ intel@15.0.0:
+ cc = /usr/local/bin/icc-15.0.090
+ cxx = /usr/local/bin/icpc-15.0.090
+ f77 = /usr/local/bin/ifort-15.0.090
+ fc = /usr/local/bin/ifort-15.0.090
This shows which C, C++, and Fortran compilers were detected by Spack.
+Notice also that we didn't have to be too specific about the
+version. We just said ``intel@15``, and information about the only
+matching Intel compiler was displayed.
-Manual configuration
+Manual compiler configuration
~~~~~~~~~~~~~~~~~~~~~~~
If autodetection fails, you can manually conigure a compiler by
@@ -153,8 +398,8 @@ Each compiler configuration in the file looks like this::
fc = /usr/local/bin/ifort-15.0.024-beta
...
-For compilers, like ``clang``, that do not support Fortran, you can simply
-put ``None`` for ``f77`` and ``fc``::
+For compilers, like ``clang``, that do not support Fortran, put
+``None`` for ``f77`` and ``fc``::
[compiler "clang@3.3svn"]
cc = /usr/bin/clang
@@ -163,169 +408,7 @@ put ``None`` for ``f77`` and ``fc``::
fc = None
Once you save the file, the configured compilers will show up in the
-list displayed when you run ``spack compilers``.
-
-
-Seeing installed packages -----------------------------------
-
-``spack find``
-~~~~~~~~~~~~~~~~~~~~~~
-
-The second thing you're likely to want to do with Spack, and the first
-thing users of your system will likely want to do, is to find what
-software is already installed and ready to use. You can do that with
-``spack find``.
-
-Running ``spack find`` with no arguments will list all the installed
-packages:
-
-.. code-block:: sh
-
- $ spack find
- == chaos_5_x86_64_ib ===========================================
- -- gcc@4.4.7 ---------------------------------------------------
- libdwarf@20130207-d9b909
- libdwarf@20130729-d9b909
- libdwarf@20130729-b52fac
- libelf@0.8.11
- libelf@0.8.12
- libelf@0.8.13
-
-Packages are grouped by architecture, then by the compiler used to
-build them, and then by their versions and options. If a package has
-dependencies, there will also be a hash at the end of the name
-indicating the dependency configuration. Packages with the same hash
-have the same dependency configuration. If you want ALL information
-about dependencies, as well, then you can supply ``-l`` or ``--long``:
-
-.. code-block:: sh
-
- $ spack find -l
- == chaos_5_x86_64_ib ===========================================
- -- gcc@4.4.7 ---------------------------------------------------
- libdwarf@20130207
- ^libelf@0.8.12
- libdwarf@20130729
- ^libelf@0.8.12
- libdwarf@20130729
- ^libelf@0.8.13
- libelf@0.8.11
- libelf@0.8.12
- libelf@0.8.13
-
-Now you can see which versions of ``libelf`` each version of
-``libdwarf`` was built with.
-
-If you want to know the path where each of these packages is
-installed, do ``spack find -p`` or ``--path``:
-
-.. code-block:: sh
-
- $ spack find -p
- == chaos_5_x86_64_ib ===========================================
- -- gcc@4.4.7 ---------------------------------------------------
- libdwarf@20130207-d9b909 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libdwarf@20130207-d9b909
- libdwarf@20130729-d9b909 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libdwarf@20130729-d9b909
- libdwarf@20130729-b52fac /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libdwarf@20130729-b52fac
- libelf@0.8.11 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.11
- libelf@0.8.12 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.12
- libelf@0.8.13 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.13
-
-
-And, finally, you can restrict your search to a particular package
-by supplying its name:
-
-.. code-block:: sh
-
- $ spack find -p libelf
- == chaos_5_x86_64_ib ===========================================
- -- gcc@4.4.7 ---------------------------------------------------
- libelf@0.8.11 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.11
- libelf@0.8.12 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.12
- libelf@0.8.13 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/libelf@0.8.13
-
-
-``spack find`` actually does a lot more than this. You can use
-*specs* to query for specific configurations and builds of each
-package. The full spec syntax is discussed in detail in
-:ref:`sec-specs`.
-
-
-
-Installing and uninstalling
-------------------------------
-
-``spack install``
-~~~~~~~~~~~~~~~~~~~~~
-
-``spack install`` will install any package that appears in the output
-of ``spack list``. To install the latest version of a pacakge and all
-of its dependencies, simply run ``spack install <package>``:
-
-.. code-block:: sh
-
- spack install mpileaks
-
-Spack will fetch the tarball for ``mpileaks``, expand it, verify that
-it was downloaded without errors, build it, and install it in its own
-directory under ``$SPACK_HOME/opt``. If the requested package depends
-on other packages in order to build, Spack fetches them as well, and
-installs them before it installs the requested package. Like the main
-package, each dependency is also installed in its own directory.
-
-Spack can also build *specific* configurations of a package. For
-example, to install something with a specific version, add ``@`` after
-the package name, followed by a version string:
-
-.. code-block:: sh
-
- spack install mpich@3.0.4
-
-Any number of configurations of the same package can be installed at
-once without interfering with each other. This is good for multi-user
-sites, as installing a version that one user needs will not disrupt
-existing installations for other users.
-
-In addition to version configuraitons, Spack can customize the
-compiler, compile-time options (variants), and platform (for cross
-compiles) of an installation. Spack is unique in that it can also
-configure the *dependencies* a package is built with. For example,
-two configurations of the same version of a package, one built with
-boost 1.39.0, and the other version built with version 1.43.0, can
-coexist.
-
-This can all be done on the command line using special syntax. Spack
-calls the descriptor used to refer to a particular package
-configuration a **spec**. In the command lines above, both
-``mpileaks`` and ``mpileaks@3.0.4`` are specs. To customize
-additional properties, simply add more attributes to the spec. Specs
-and their syntax are covered in more detail in :ref:`sec-specs`.
-
-
-``spack uninstall``
-~~~~~~~~~~~~~~~~~~~~~
-
-To uninstall a package, type ``spack uninstall <package>``. This will
-completely remove the directory in which the package was installed.
-
-.. code-block:: sh
-
- spack uninstall mpich
-
-If there are still installed packages that depend on the package to be
-uninstalled, spack will refuse to uninstall. If you know what you're
-doing, you can override this with ``spack uninstall -f <package>``.
-However, running this risks breaking other installed packages. In
-general, it is safer to remove dependent packages *before* removing
-their dependencies.
-
-A line like ``spack uninstall mpich`` may be ambiguous, if multiple
-``mpich`` configurations are installed. For example, if both
-``mpich@3.0.2`` and ``mpich@3.1`` are installed, it could refer to
-either one, and Spack cannot determine which one to uninstall. Spack
-will ask you to provide a version number to remove the ambiguity. For
-example, ``spack uninstall mpich@3.1`` is unambiguous in the above
-scenario.
+list displayed by ``spack compilers``.
.. _sec-specs:
@@ -333,10 +416,10 @@ scenario.
Specs & Dependencies
-------------------------
-We now know that ``spack install`` and ``spack uninstall`` both take a
-package name with an optional version specifier. In Spack, that
-descriptor is called a *spec*. Spack uses specs to refer to a
-particular build configuration (or configurations) of a package.
+We know that ``spack install``, ``spack uninstall``, and other
+commands take a package name with an optional version specifier. In
+Spack, that descriptor is called a *spec*. Spack uses specs to refer
+to a particular build configuration (or configurations) of a package.
Specs are more than a package name and a version; you can use them to
specify the compiler, compiler version, architecture, compile options,
and dependency options for a build. In this section, we'll go over
@@ -499,6 +582,11 @@ based on site policies.
Variants
~~~~~~~~~~~~~~~~~~~~~~~
+.. Note::
+
+ Variants are not yet supported, but will be in the next Spack
+ release (0.9), due in Q2 2015.
+
Variants are named options associated with a particular package, and
they can be turned on or off. For example, above, supplying
``+debug`` causes ``mpileaks`` to be built with debug flags. The
@@ -544,6 +632,11 @@ the command line is provided for convenience and legibility.
Architecture specifier
~~~~~~~~~~~~~~~~~~~~~~~
+.. Note::
+
+ Architecture specifiers are part of specs but are not yet
+ functional. They will be in Spack version 1.0, due in Q3 2015.
+
The architecture specifier starts with a ``=`` and also comes after
some package name within a spec. It allows a user to specify a
particular architecture for the package to be built. This is mostly
@@ -678,10 +771,6 @@ For ``csh`` and ``tcsh`` run:
You can put the above code in your ``.bashrc`` or ``.cshrc``, and
Spack's shell support will be available on the command line.
-
--------------------------------
-
-
When you install a package with Spack, it automatically generates an
environment module that lets you add the package to your environment.
@@ -710,7 +799,7 @@ of installed packages.
$ module avail
- ------- /g/g21/gamblin2/src/spack/share/spack/modules/chaos_5_x86_64_ib --------
+ ------- /home/gamblin2/spack/share/spack/modules/chaos_5_x86_64_ib --------
adept-utils@1.0%gcc@4.4.7-5adef8da libelf@0.8.13%gcc@4.4.7
automaded@1.0%gcc@4.4.7-d9691bb0 libelf@0.8.13%intel@15.0.0
boost@1.55.0%gcc@4.4.7 mpc@1.0.2%gcc@4.4.7-559607f5
@@ -858,6 +947,215 @@ regenerate all module and dotkit files from scratch:
==> Regenerating tcl module files.
==> Regenerating dotkit module files.
+
+.. _extensions:
+
+Extensions & Python Support
+------------------------------------
+
+Spack's installation model assumes that each package will live in its
+own install prefix. However, certain packages are typically installed
+*within* the directory hierarchy of other packages. For example,
+modules in interpreted languages like `Python
+<https://www.python.org>`_ are typically installed in the
+``$prefix/lib/python-2.7/site-packages`` directory.
+
+Spack has support for this type of installation as well. In Spack,
+a package that can live inside the prefix of another package is called
+an *extension*. Suppose you have Python installed like so:
+
+.. code-block:: sh
+
+ $ spack find python
+ ==> 1 installed packages.
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ python@2.7.8
+
+``spack extensions``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+You can find extensions for your Python installation like this:
+
+.. code-block:: sh
+
+ $ spack extensions python
+ ==> python@2.7.8%gcc@4.4.7=chaos_5_x86_64_ib-703c7a96
+ ==> 36 extensions:
+ geos py-ipython py-pexpect py-pyside py-sip
+ py-basemap py-libxml2 py-pil py-pytz py-six
+ py-biopython py-mako py-pmw py-rpy2 py-sympy
+ py-cython py-matplotlib py-pychecker py-scientificpython py-virtualenv
+ py-dateutil py-mpi4py py-pygments py-scikit-learn
+ py-epydoc py-mx py-pylint py-scipy
+ py-gnuplot py-nose py-pyparsing py-setuptools
+ py-h5py py-numpy py-pyqt py-shiboken
+
+ ==> 12 installed:
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ py-dateutil@2.4.0 py-nose@1.3.4 py-pyside@1.2.2
+ py-dateutil@2.4.0 py-numpy@1.9.1 py-pytz@2014.10
+ py-ipython@2.3.1 py-pygments@2.0.1 py-setuptools@11.3.1
+ py-matplotlib@1.4.2 py-pyparsing@2.0.3 py-six@1.9.0
+
+ ==> None activated.
+
+The extensions are a subset of what's returned by ``spack list``, and
+they are packages like any ohter. They are installed into their own
+prefixes, and you can see this with ``spack find -p``:
+
+.. code-block:: sh
+ $ spack find -p py-numpy
+ ==> 1 installed packages.
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ py-numpy@1.9.1 /g/g21/gamblin2/src/spack/opt/chaos_5_x86_64_ib/gcc@4.4.7/py-numpy@1.9.1-66733244
+
+However, even though this package is installed, you cannot use it
+directly when you run ``python``:
+
+.. code-block:: sh
+
+ $ spack load python
+ $ python
+ Python 2.7.8 (default, Feb 17 2015, 01:35:25)
+ [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux2
+ Type "help", "copyright", "credits" or "license" for more information.
+ >>> import numpy
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ ImportError: No module named numpy
+ >>>
+
+Extensions & Environment Modules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are two ways to get ``numpy`` working in Python. The first is
+to use :ref:`shell-support`. You can simply ``use`` or ``load`` the
+module for the extension, and it will be added to the ``PYTHONPATH``
+in your current shell.
+
+For tcl modules:
+
+.. code-block:: sh
+
+ $ spack load python
+ $ spack load py-numpy
+
+or, for dotkit:
+
+.. code-block:: sh
+
+ $ spack use python
+ $ spack use py-numpy
+
+Now ``import numpy`` will succeed for as long as you keep your current
+session open.
+
+
+Activating Extensions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is often desirable to have certain packages *always* available as
+part of a Python installation. Spack offers a more permanent solution
+for this case. Instead of requiring users to load particular
+environment modules, you can *activate* the package within the Python
+installation:
+
+``spack activate``
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: sh
+
+ $ spack activate py-numpy
+ ==> Activated extension py-setuptools@11.3.1%gcc@4.4.7=chaos_5_x86_64_ib-3c74eb69 for python@2.7.8%gcc@4.4.7.
+ ==> Activated extension py-nose@1.3.4%gcc@4.4.7=chaos_5_x86_64_ib-5f70f816 for python@2.7.8%gcc@4.4.7.
+ ==> Activated extension py-numpy@1.9.1%gcc@4.4.7=chaos_5_x86_64_ib-66733244 for python@2.7.8%gcc@4.4.7.
+
+Several things have happened here. The user requested that
+``py-numpy`` be activated in the ``python`` installation it was built
+with. Spack knows that ``py-numpy`` depends on ``py-nose`` and
+``py-setuptools``, so it activated those packages first. Finally,
+once all dpeendencies were activated in the ``python`` installation,
+``py-numpy`` was activated as well.
+
+If we run ``spack extensions`` again, we now see the three new
+packages listed as activated:
+
+.. code-block:: sh
+
+ $ spack extensions python
+ ==> python@2.7.8%gcc@4.4.7=chaos_5_x86_64_ib-703c7a96
+ ==> 36 extensions:
+ geos py-ipython py-pexpect py-pyside py-sip
+ py-basemap py-libxml2 py-pil py-pytz py-six
+ py-biopython py-mako py-pmw py-rpy2 py-sympy
+ py-cython py-matplotlib py-pychecker py-scientificpython py-virtualenv
+ py-dateutil py-mpi4py py-pygments py-scikit-learn
+ py-epydoc py-mx py-pylint py-scipy
+ py-gnuplot py-nose py-pyparsing py-setuptools
+ py-h5py py-numpy py-pyqt py-shiboken
+
+ ==> 12 installed:
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ py-dateutil@2.4.0 py-nose@1.3.4 py-pyside@1.2.2
+ py-dateutil@2.4.0 py-numpy@1.9.1 py-pytz@2014.10
+ py-ipython@2.3.1 py-pygments@2.0.1 py-setuptools@11.3.1
+ py-matplotlib@1.4.2 py-pyparsing@2.0.3 py-six@1.9.0
+
+ ==> 3 currently activated:
+ -- chaos_5_x86_64_ib / gcc@4.4.7 --------------------------------
+ py-nose@1.3.4 py-numpy@1.9.1 py-setuptools@11.3.1
+
+
+Now, when a user runs python, ``numpy`` will be avaiable for import
+*without* the user having to explicitly loaded. ``python@2.7.8`` now
+acts like a system Python installation with ``numpy`` installed inside
+of it.
+
+Spack accomplishes this by symbolically linking the *entire* prefix of
+the ``py-numpy`` into the prefix of the ``python`` package. To the
+python interpreter, it looks like ``numpy`` is installed in the
+``site-packages`` directory.
+
+The only limitation of activation is that you can only have a *single*
+version of an extension activated at a time. This is because multiple
+versions of the same extension would conflict if symbolically linked
+into the same prefix. Users who want a different version of a package
+can still get it by using environment modules, but they will have to
+explicitly load their preferred version.
+
+``spack activate -f``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+If, for some reason, you want to activate a package *without* its
+dependencies, you can use ``spack activate -f``:
+
+.. code-block:: sh
+
+ $ spack activate -f py-numpy
+ ==> Activated extension py-numpy@1.9.1%gcc@4.4.7=chaos_5_x86_64_ib-66733244 for python@2.7.8%gcc@4.4.7.
+
+
+``spack deactivate``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We've seen how activating an extension can be used to set up a default
+version of a Python module. Obviously, you may want to change that at
+some point. ``spack deactivate`` is the command for this. There are
+several variants:
+
+ * ``spack deactivate <extension>`` will deactivate a single
+ extension. If another activated extension depends on this one,
+ Spack will warn you and exit with an error.
+ * ``spack deactivate -f <extension>`` deactivates an extension
+ regardless of packages that depend on it.
+ * ``spack deactivate -a <extension>`` deactivates an extension and
+ all of its dependencies. Use ``-f`` to disregard dependents.
+ * ``spack deactivate -a <extendee>`` deactivates *all* activated
+ extensions of a package. For example, to deactivate *all* python
+ extensions, use::
+
+ spack deactivate -a python
+
+
Getting Help
-----------------------
diff --git a/lib/spack/docs/conf.py b/lib/spack/docs/conf.py
index b01f33d4b8..86df113074 100644
--- a/lib/spack/docs/conf.py
+++ b/lib/spack/docs/conf.py
@@ -54,9 +54,7 @@ spack_version = subprocess.Popen(
# Set an environment variable so that colify will print output like it would to
# a terminal.
-os.environ['COLIFY_TTY'] = 'true'
-os.environ['COLUMNS'] = '80'
-os.environ['LINES'] = '25'
+os.environ['COLIFY_SIZE'] = '25x80'
# Enable todo items
todo_include_todos = True
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst
index 076d3ca0e6..bc3bacf8f2 100644
--- a/lib/spack/docs/packaging_guide.rst
+++ b/lib/spack/docs/packaging_guide.rst
@@ -16,16 +16,17 @@ There are two key parts of Spack:
software according to a spec.
Specs allow a user to describe a *particular* build in a way that a
-package author can understand. Packages allow a developer to
-encapsulate the logic build logic for different versions, compilers,
+package author can understand. Packages allow a the packager to
+encapsulate the build logic for different versions, compilers,
options, platforms, and dependency combinations in one place.
+Essentially, a package translates a spec into build logic.
Packages in Spack are written in pure Python, so you can do anything
in Spack that you can do in Python. Python was chosen as the
implementation language for two reasons. First, Python is becoming
-ubiquitous in the HPC community due to its use in numerical codes.
-Second, it's a modern language and has many powerful features to help
-make package writing easy.
+ubiquitous in the scientific software community. Second, it's a modern
+language and has many powerful features to help make package writing
+easy.
Creating & Editing Packages
----------------------------------
@@ -35,24 +36,23 @@ Creating & Editing Packages
``spack create``
~~~~~~~~~~~~~~~~~~~~~
-The ``spack create`` command generates boilerplate package template
-from a URL pointing to a tarball or other software archive. In most
-cases, you'll only need to run this once, then slightly modify the
-boilerplate to get your package working.
+The ``spack create`` command generates a boilerplate package template
+from a URL. The URL should point to a tarball or other software
+archive. In most cases, ``spack create`` plus a few modifications is
+all you need to get a package working.
-All you need is the URL to a tarball (other archive formats are ok
-too) you want to package:
+Here's an example:
.. code-block:: sh
$ spack create http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz
-When you run this, Spack looks at the tarball URL and tries to figure
-out the name of the package to be created. It also tries to determine
-out what version strings look like for this package. Using this
-information, it tries to find *additional* versions by spidering the
-package's webpage. If it finds multiple versions, Spack prompts you
-to tell it how many versions you want to download and checksum.
+Spack examines the tarball URL and tries to figure out the name of the
+package to be created. It also tries to determine what version strings
+look like for this package. Using this information, it will try to
+find *additional* versions by spidering the package's webpage. If it
+finds multiple versions, Spack prompts you to tell it how many
+versions you want to download and checksum:
.. code-block:: sh
@@ -63,12 +63,6 @@ to tell it how many versions you want to download and checksum.
2.8.12.1 http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz
2.8.12 http://www.cmake.org/files/v2.8/cmake-2.8.12.tar.gz
2.8.11.2 http://www.cmake.org/files/v2.8/cmake-2.8.11.2.tar.gz
- 2.8.11.1 http://www.cmake.org/files/v2.8/cmake-2.8.11.1.tar.gz
- 2.8.11 http://www.cmake.org/files/v2.8/cmake-2.8.11.tar.gz
- 2.8.10.2 http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz
- 2.8.10.1 http://www.cmake.org/files/v2.8/cmake-2.8.10.1.tar.gz
- 2.8.10 http://www.cmake.org/files/v2.8/cmake-2.8.10.tar.gz
- 2.8.9 http://www.cmake.org/files/v2.8/cmake-2.8.9.tar.gz
...
2.8.0 http://www.cmake.org/files/v2.8/cmake-2.8.0.tar.gz
@@ -77,10 +71,30 @@ to tell it how many versions you want to download and checksum.
Spack will automatically download the number of tarballs you specify
(starting with the most recent) and checksum each of them.
-Note that you don't need to do everything up front. If your package
-is large, you can always choose to download just one tarball for now,
-then run :ref:`spack checksum <spack-checksum>` later if you end up
-wanting more. Let's say you choose to download 3 tarballs:
+You do not *have* to download all of the versions up front. You can
+always choose to download just one tarball initially, and run
+:ref:`spack checksum <spack-checksum>` later if you need more.
+
+.. note::
+
+ If ``spack create`` fails to detect the package name correctly,
+ you can try supplying it yourself, e.g.::
+
+ $ spack create --name cmake http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz
+
+ 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``.
+
+.. note::
+
+ Spack can fetch packages from source code repositories, but,
+ ``spack create`` will *not* currently create a boilerplate package
+ from a repository URL. You will need to use :ref:`spack-edit-f`
+ and manually edit the ``version()`` directives to fetch from a
+ repo. See :ref:`vcs-fetch` for details.
+
+Let's say you download 3 tarballs:
.. code-block:: sh
@@ -93,8 +107,8 @@ wanting more. Let's say you choose to download 3 tarballs:
==> Fetching http://www.cmake.org/files/v2.8/cmake-2.8.11.2.tar.gz
#################################################################### 95.2%
-Now Spack generates boilerplate code and opens the new
-``package.py`` file in your favorite ``$EDITOR``:
+Now Spack generates boilerplate code and opens a new ``package.py``
+file in your favorite ``$EDITOR``:
.. code-block:: python
:linenos:
@@ -141,12 +155,6 @@ Now Spack generates boilerplate code and opens the new
The tedious stuff (creating the class, checksumming archives) has been
done for you.
-.. note::
-
- If ``spack create`` fails to download or to detect the package
- version, you can use ``spack edit -f`` to generate simpler
- boilerplate. See the next section for more on this.
-
In the generated package, the download ``url`` attribute is already
set. All the things you still need to change are marked with
``FIXME`` labels. The first ``FIXME`` refers to the commented
@@ -199,27 +207,30 @@ The ``cmake`` package actually lives in
a much simpler shortcut and saves you the trouble of typing the full
path.
-
-``spack edit -f``
-~~~~~~~~~~~~~~~~~~~~
If you try to edit a package that doesn't exist, Spack will recommend
-using ``spack create``:
+using ``spack create`` or ``spack edit -f``:
.. code-block:: sh
$ spack edit foo
==> Error: No package 'foo'. Use spack create, or supply -f/--force to edit a new file.
-As the output advises, You can use ``spack edit -f/--force`` to force
-the creation of a new, *very* simple boilerplate package:
+.. _spack-edit-f:
+
+``spack edit -f``
+~~~~~~~~~~~~~~~~~~~~
+
+``spack edit -f`` can be used to create a new, minimal boilerplate
+package:
.. code-block:: sh
$ spack edit -f foo
-Unlike ``spack create``, which tries to infer names and versions, and
-which actually downloads the tarball and checksums it for you, ``spack
-edit -f`` will substitute dummy values for you to fill in yourself:
+Unlike ``spack create``, which infers names and versions, and which
+actually downloads the tarball and checksums it for you, ``spack edit
+-f`` has no such fanciness. It will substitute dummy values for you
+to fill in yourself:
.. code-block:: python
:linenos:
@@ -246,6 +257,13 @@ version of your package from the archive URL.
Naming & Directory Structure
--------------------------------------
+.. note::
+
+ Spack's default naming and directory structure will change in
+ version 0.9. Specifically, 0.9 will stop using directory names
+ with special characters like ``@``, to avoid interfering with
+ certain packages that do not handle this well.
+
This section describes how packages need to be named, and where they
live in Spack's directory structure. In general, `spack-create`_ and
`spack-edit`_ handle creating package files for you, so you can skip
@@ -264,6 +282,7 @@ package:
.. command-output:: cd $SPACK_ROOT/var/spack/packages; ls -CF
:shell:
+ :ellipsis: 10
Each directory contains a file called ``package.py``, which is where
all the python code for the package goes. For example, the ``libelf``
@@ -280,11 +299,9 @@ Package Names
Packages are named after the directory containing ``package.py``. So,
``libelf``'s ``package.py`` lives in a directory called ``libelf``.
-The ``package.py`` file contains a class called ``Libelf``, which
-extends Spack's ``Package`` class. This is what makes it a Spack
-package:
-
-``var/spack/packages/libelf/package.py``
+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``:
.. code-block:: python
:linenos:
@@ -301,8 +318,9 @@ package:
def install():
...
-The **directory name** (``libelf``) is what users need to provide on
-the command line. e.g., if you type any of these:
+The **directory name** (``libelf``) determines the package name that
+users should provide on the command line. e.g., if you type any of
+these:
.. code-block:: sh
@@ -311,8 +329,8 @@ the command line. e.g., if you type any of these:
Spack sees the package name in the spec and looks for
``libelf/package.py`` in ``var/spack/packages``. Likewise, if you say
-``spack install docbook-xml``, then Spack looks for
-``docbook-xml/package.py``.
+``spack install py-numpy``, then Spack looks for
+``py-numpy/package.py``.
Spack uses the directory name as the package name in order to give
packagers more freedom in naming their packages. Package names can
@@ -342,8 +360,7 @@ some examples:
================= =================
In general, you won't have to remember this naming convention because
-`spack-create`_ and `spack-edit`_ will generate boilerplate for you,
-and you can just fill in the blanks.
+`spack-create`_ and `spack-edit`_ handle the details for you.
Adding new versions
@@ -381,9 +398,8 @@ For the URL above, you might have to add an explicit URL because the
version can't simply be substituted in the original ``url`` to
construct the new one for ``8.2.1``.
-Wehn you supply a custom URL for a version, Spack uses that URL
-*verbatim* when fetching the version, and will *not* perform
-extrapolation.
+When you supply a custom URL for a version, Spack uses that URL
+*verbatim* and does not perform extrapolation.
Checksums
~~~~~~~~~~~~~~~~~
@@ -392,10 +408,11 @@ Spack uses a checksum to ensure that the downloaded package version is
not corrupted or compromised. This is especially important when
fetching from insecure sources, like unencrypted http. By default, a
package will *not* be installed if it doesn't pass a checksum test
-(though users can overried this with ``spack install --no-checksum``).
+(though you can override this with ``spack install --no-checksum``).
Spack can currently support checksums using the MD5, SHA-1, SHA-224,
-SHA-256, SHA-384, and SHA-512 algorithms.
+SHA-256, SHA-384, and SHA-512 algorithms. It determines the algorithm
+to use based on the hash length.
``spack md5``
^^^^^^^^^^^^^^^^^^^^^^
@@ -459,16 +476,18 @@ By default, Spack will search for new tarball downloads by scraping
the parent directory of the tarball you gave it. So, if your tarball
is at ``http://example.com/downloads/foo-1.0.tar.gz``, Spack will look
in ``http://example.com/downloads/`` for links to additional versions.
-If you need to search another path for download links, see the
-reference documentation on `attribute_list_url`_ and
+If you need to search another path for download links, you can supply
+some extra attributes that control how your package finds new
+versions. See the documentation on `attribute_list_url`_ and
`attributee_list_depth`_.
.. note::
* This command assumes that Spack can extrapolate new URLs from an
existing URL in the package, and that Spack can find similar URLs
- on a webpage. If that's not possible, you'll need to manually add
- ``version`` calls yourself.
+ on a webpage. If that's not possible, e.g. if the package's
+ developers don't name their tarballs consistently, you'll need to
+ manually add ``version`` calls yourself.
* For ``spack checksum`` to work, Spack needs to be able to
``import`` your pacakge in Python. That means it can't have any
@@ -481,32 +500,33 @@ reference documentation on `attribute_list_url`_ and
Fetching from VCS Repositories
--------------------------------------
-For some packages, source code is hosted in a Version Control System
-(VCS) repository rather than as a tarball. Packages can be set up to
-fetch from a repository instead of a tarball. Currently, Spack
-supports fetching with `Git <git-fetch_>`_, `Mercurial (hg)
-<hg-fetch_>`_, and `Subversion (SVN) <svn-fetch_>`_.
+For some packages, source code is provided in a Version Control System
+(VCS) repository rather than in a tarball. Spack can fetch packages
+from VCS repositories. Currently, Spack supports fetching with `Git
+<git-fetch_>`_, `Mercurial (hg) <hg-fetch_>`_, and `Subversion (SVN)
+<svn-fetch_>`_.
To fetch a package from a source repository, you add a ``version()``
call to your package with parameters indicating the repository URL and
-any branch, tag, or revision to fetch. See below for the paramters
+any branch, tag, or revision to fetch. See below for the parameters
you'll need for each VCS system.
Repositories and versions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The package author is responsible for coming up with a sensible name
-for each version. For example, if you're fetching from a tag like
-``v1.0``, you might call that ``1.0``. If you're fetching a nameless
-git commit or an older subversion revision, you might give the commit
-an intuitive name, like ``dev`` for a development version, or
-``some-fancy-new-feature`` if you want to be more specific.
+for each version to be fetched from a repository. For example, if
+you're fetching from a tag like ``v1.0``, you might call that ``1.0``.
+If you're fetching a nameless git commit or an older subversion
+revision, you might give the commit an intuitive name, like ``dev``
+for a development version, or ``some-fancy-new-feature`` if you want
+to be more specific.
In general, it's recommended to fetch tags or particular
commits/revisions, NOT branches or the repository mainline, as
branches move forward over time and you aren't guaranteed to get the
same thing every time you fetch a particular version. Life isn't
-simple, though, so this is not strictly enforced.
+always simple, though, so this is not strictly enforced.
In some future release, Spack may support extrapolating repository
versions as it does for tarball URLs, but currently this is not
@@ -633,7 +653,7 @@ Subversion
To fetch with subversion, use the ``svn`` and ``revision`` parameters:
-Head
+Fetching the head
Simply add an ``svn`` parameter to ``version``:
.. code-block:: python
@@ -642,7 +662,7 @@ Head
This is not recommended, as the head will move forward over time.
-Revisions
+Fetching a revision
To fetch a particular revision, add a ``revision`` to the
version call:
@@ -746,6 +766,53 @@ from the URL and then applied to your source code.
applies cleanly with ``-p1``, but if you're using a patch you didn't
create yourself, ``level`` can be handy.
+``patch()`` functions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to supplying patch files, you can write a custom function
+to patch a package's source. For example, the ``py-pyside`` package
+contains some custom code for tweaking the way the PySide build
+handles ``RPATH``:
+
+.. code-block:: python
+ :linenos:
+
+ class PyPyside(Package):
+ ...
+
+ def patch(self):
+ """Undo PySide RPATH handling and add Spack RPATH."""
+ # Figure out the special RPATH
+ pypkg = self.spec['python'].package
+ rpath = self.rpath
+ rpath.append(os.path.join(self.prefix, pypkg.site_packages_dir, 'PySide'))
+
+ # Add Spack's standard CMake args to the sub-builds.
+ # They're called BY setup.py so we have to patch it.
+ filter_file(
+ r'OPTION_CMAKE,',
+ r'OPTION_CMAKE, ' + (
+ '"-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=FALSE", '
+ '"-DCMAKE_INSTALL_RPATH=%s",' % ':'.join(rpath)),
+ 'setup.py')
+
+ # PySide tries to patch ELF files to remove RPATHs
+ # Disable this and go with the one we set.
+ filter_file(
+ r'^\s*rpath_cmd\(pyside_path, srcpath\)',
+ r'#rpath_cmd(pyside_path, srcpath)',
+ 'pyside_postinstall.py')
+
+A ``patch`` function, if present, will be run after patch files are
+applied and before ``install()`` is run.
+
+You could put this logic in ``install()``, but putting it in a patch
+function gives you some benefits. First, spack ensures that the
+``patch()`` function is run once per code checkout. That means that
+if you run install, hit ctrl-C, and run install again, the code in the
+patch function is only run once. Also, you can tell Spack to run only the patching part of the build using the ..
+
+
Finding Package Downloads
----------------------------
@@ -1932,6 +1999,8 @@ A typical package workflow might look like this:
Below are some commands that will allow you some finer-grained
controll over the install process.
+.. _spack-fetch:
+
``spack fetch``
~~~~~~~~~~~~~~~~~
@@ -1944,6 +2013,8 @@ directory will be located under ``$SPACK_HOME/var/spack``.
When run after the archive has already been downloaded, ``spack
fetch`` is idempotent and will not download the archive again.
+.. _spack-stage:
+
``spack stage``
~~~~~~~~~~~~~~~~~
@@ -1952,6 +2023,8 @@ the downloaded archive in its temporary directory, where it will be
built by ``spack install``. Similar to ``fetch``, if the archive has
already been expanded, ``stage`` is idempotent.
+.. _spack-patch:
+
``spack patch``
~~~~~~~~~~~~~~~~~
@@ -1963,7 +2036,6 @@ this step if they have been. If Spack discovers that patches didn't
apply cleanly on some previous run, then it will restage the entire
package before patching.
-
``spack restage``
~~~~~~~~~~~~~~~~~
Restores the source code to pristine state, as it was before building.
@@ -2030,6 +2102,85 @@ to get rid of the install prefix before you build again:
spack uninstall -f <spec>
+Graphing Dependencies
+--------------------------
+
+.. _spack-graph:
+
+``spack graph``
+~~~~~~~~~~~~~~~~~~~
+
+Spack provides the ``spack graph`` command for graphing dependencies.
+The command by default generates an ASCII rendering of a spec's
+dependency graph. For example::
+
+ $ spack graph mpileaks
+ o mpileaks
+ |\
+ | |\
+ | o | callpath
+ |/| |
+ | |\|
+ | |\ \
+ | | |\ \
+ | | | | o adept-utils
+ | |_|_|/|
+ |/| | | |
+ o | | | | mpi
+ / / / /
+ | | o | dyninst
+ | |/| |
+ |/|/| |
+ | | |/
+ | o | libdwarf
+ |/ /
+ o | libelf
+ /
+ o boost
+
+At the top is the root package in the DAG, with dependency edges
+emerging from it. On a color terminal, the edges are colored by which
+dependency they lead to.
+
+You can also use ``spack graph`` to generate graphs in the widely used
+`Dot <http://www.graphviz.org/doc/info/lang.html>`_ format. For
+example::
+
+ $ spack graph --dot mpileaks
+ digraph G {
+ label = "Spack Dependencies"
+ labelloc = "b"
+ rankdir = "LR"
+ ranksep = "5"
+
+ "boost" [label="boost"]
+ "callpath" [label="callpath"]
+ "libdwarf" [label="libdwarf"]
+ "mpileaks" [label="mpileaks"]
+ "mpi" [label="mpi"]
+ "adept-utils" [label="adept-utils"]
+ "dyninst" [label="dyninst"]
+ "libelf" [label="libelf"]
+
+ "callpath" -> "dyninst"
+ "callpath" -> "adept-utils"
+ "callpath" -> "mpi"
+ "callpath" -> "libelf"
+ "callpath" -> "libdwarf"
+ "libdwarf" -> "libelf"
+ "mpileaks" -> "adept-utils"
+ "mpileaks" -> "callpath"
+ "mpileaks" -> "mpi"
+ "adept-utils" -> "boost"
+ "adept-utils" -> "mpi"
+ "dyninst" -> "boost"
+ "dyninst" -> "libelf"
+ "dyninst" -> "libdwarf"
+ }
+
+This graph can be provided as input to other graphing tools, such as
+those in `Graphviz <http://www.graphviz.org>`_.
+
Interactive Shell Support
--------------------------
diff --git a/lib/spack/llnl/util/tty/colify.py b/lib/spack/llnl/util/tty/colify.py
index 6b2909990c..66c52c3968 100644
--- a/lib/spack/llnl/util/tty/colify.py
+++ b/lib/spack/llnl/util/tty/colify.py
@@ -169,6 +169,15 @@ def colify(elts, **options):
if not elts:
return (0, ())
+ # environment size is of the form "<rows>x<cols>"
+ env_size = os.environ.get('COLIFY_SIZE')
+ if env_size:
+ try:
+ r, c = env_size.split('x')
+ console_rows, console_cols = int(r), int(c)
+ tty = True
+ except: pass
+
# Use only one column if not a tty.
if not tty:
if tty is False or not output.isatty():
diff --git a/lib/spack/spack/cmd/activate.py b/lib/spack/spack/cmd/activate.py
index 71eca4f453..4070baaa70 100644
--- a/lib/spack/spack/cmd/activate.py
+++ b/lib/spack/spack/cmd/activate.py
@@ -38,6 +38,7 @@ def setup_parser(subparser):
def activate(parser, args):
+ # TODO: shouldn't have to concretize here. Fix DAG issues.
specs = spack.cmd.parse_specs(args.spec, concretize=True)
if len(specs) != 1:
tty.die("activate requires one spec. %d given." % len(specs))
@@ -47,6 +48,7 @@ def activate(parser, args):
spack.db.get(specs[0])
spec = spack.cmd.disambiguate_spec(specs[0])
+
if not spec.package.is_extension:
tty.die("%s is not an extension." % spec.name)
diff --git a/lib/spack/spack/cmd/deactivate.py b/lib/spack/spack/cmd/deactivate.py
index bfec618c8e..c9a4d4b2f6 100644
--- a/lib/spack/spack/cmd/deactivate.py
+++ b/lib/spack/spack/cmd/deactivate.py
@@ -44,6 +44,7 @@ def setup_parser(subparser):
def deactivate(parser, args):
+ # TODO: shouldn't have to concretize here. Fix DAG issues.
specs = spack.cmd.parse_specs(args.spec, concretize=True)
if len(specs) != 1:
tty.die("deactivate requires one spec. %d given." % len(specs))
@@ -59,6 +60,7 @@ def deactivate(parser, args):
if pkg.extendable:
tty.msg("Deactivating all extensions of %s" % pkg.spec.short_spec)
ext_pkgs = spack.db.installed_extensions_for(spec)
+
for ext_pkg in ext_pkgs:
ext_pkg.spec.normalize()
if ext_pkg.activated:
@@ -68,6 +70,9 @@ def deactivate(parser, args):
# TODO: store DAG info properly (see above)
spec.normalize()
+ if not args.force and not spec.package.activated:
+ tty.die("%s is not activated." % pkg.spec.short_spec)
+
tty.msg("Deactivating %s and all dependencies." % pkg.spec.short_spec)
topo_order = topological_sort(spec)
diff --git a/lib/spack/spack/cmd/package-list.py b/lib/spack/spack/cmd/package-list.py
index 809c64a5b9..f048482845 100644
--- a/lib/spack/spack/cmd/package-list.py
+++ b/lib/spack/spack/cmd/package-list.py
@@ -50,6 +50,8 @@ def print_rst_package_list():
"""Print out information on all packages in restructured text."""
pkgs = sorted(spack.db.all_packages(), key=lambda s:s.name.lower())
+ print ".. _package-list:"
+ print
print "Package List"
print "=================="
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
index 0962942f43..6ded455390 100644
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -66,6 +66,7 @@ def uninstall(parser, args):
tty.die(*args)
if len(matching_specs) == 0:
+ if args.force: continue
tty.die("%s does not match any installed packages." % spec)
for s in matching_specs:
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 492af12053..137e8f8837 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -941,16 +941,17 @@ class Package(object):
def _sanity_check_extension(self):
if not self.is_extension:
- raise ValueError("This package is not an extension.")
+ raise ActivationError("This package is not an extension.")
+
extendee_package = self.extendee_spec.package
extendee_package._check_extendable()
if not extendee_package.installed:
- raise ValueError("Can only (de)activate extensions for installed packages.")
+ raise ActivationError("Can only (de)activate extensions for installed packages.")
if not self.installed:
- raise ValueError("Extensions must first be installed.")
+ raise ActivationError("Extensions must first be installed.")
if not self.extendee_spec.name in self.extendees:
- raise ValueError("%s does not extend %s!" % (self.name, self.extendee.name))
+ raise ActivationError("%s does not extend %s!" % (self.name, self.extendee.name))
def do_activate(self, **kwargs):
@@ -1170,12 +1171,8 @@ def validate_package_url(url_string):
def print_pkg(message):
"""Outputs a message with a package icon."""
- mac_ver = py_platform.mac_ver()[0]
- if mac_ver and Version(mac_ver) >= Version('10.7'):
- print u"\U0001F4E6" + tty.indent,
- else:
- from llnl.util.tty.color import cwrite
- cwrite('@*g{[+]} ')
+ from llnl.util.tty.color import cwrite
+ cwrite('@*g{[+]} ')
print message