Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 26 additions & 26 deletions tutorial_advanced_packaging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
Advanced Topics in Packaging
============================

Spack tries to automatically configure packages with information from dependencies such that all you need to do is to list the dependencies (i.e., with the ``depends_on`` directive) and the build system (for example by deriving from ``CmakePackage``).
Spack tries to automatically configure packages with information from dependencies such that all we will need to do is to list the dependencies (i.e., with the ``depends_on`` directive) and the build system (for example by deriving from ``CmakePackage``).

However, there are many special cases.
Often you need to retrieve details about dependencies to set package-specific configuration options, or to define package-specific environment variables used by the package's build system.
This tutorial covers how to retrieve build information from dependencies, and how you can automatically provide important information to dependents in your package.
Often we will need to retrieve details about dependencies to set package-specific configuration options, or to define package-specific environment variables used by the package's build system.
This tutorial covers how to retrieve build information from dependencies, and how we can automatically provide important information to dependents in your package.

----------------------
Setup for the Tutorial
Expand All @@ -33,29 +33,29 @@ These package definitions are stored in a separate package repository, which can
$ spack repo add --scope=site var/spack/repos/tutorial

This section of the tutorial may also require a newer version of gcc.
If you have not already installed gcc @7.2.0 and added it to your configuration, you can do so with:
If we have not already installed gcc @7.2.0 and added it to your configuration, we can do so with:

.. code-block:: console

$ spack install gcc@7.2.0 %gcc@5.4.0
$ spack compiler add --scope=site `spack location -i gcc@7.2.0 %gcc@5.4.0`

If you are using the tutorial docker image, all dependency packages will have been installed.
Otherwise, to install these packages you can use the following commands:
Otherwise, to install these packages we can use the following commands:

.. code-block:: console

$ spack install openblas
$ spack install netlib-lapack
$ spack install mpich

Now, you are ready to set your preferred ``EDITOR`` and continue with the rest of the tutorial.
Now, we are ready to set our preferred ``EDITOR`` and continue with the rest of the tutorial.

.. note::

Several of these packages depend on an MPI implementation. You can use
OpenMPI if you install it from scratch, but this is slow (>10 min.).
A binary cache of MPICH may be provided, in which case you can force
Several of these packages depend on an MPI implementation. We can use
OpenMPI if we install it from scratch, but this is slow (>10 min.).
A binary cache of MPICH may be provided, in which case we can force
the package to use it and install quickly. All tutorial examples with
packages that depend on MPICH include the spec syntax for building with it.

Expand Down Expand Up @@ -97,7 +97,7 @@ We can practice by editing the ``mpich`` package to set the ``MPICC`` environmen

root@advanced-packaging-tutorial:/# spack edit mpich

Once you're finished, the method should look like this:
Once we're finished, the method should look like this:

.. code-block:: python

Expand All @@ -113,7 +113,7 @@ Once you're finished, the method should look like this:
spack_env.set('MPICH_F90', spack_fc)
spack_env.set('MPICH_FC', spack_fc)

At this point we can, for instance, install ``netlib-scalapack`` with ``mpich``:
At this point, we will, for instance, install ``netlib-scalapack`` with ``mpich``:

.. code-block:: console

Expand Down Expand Up @@ -198,7 +198,7 @@ In the end your method should look like:
spack_env.append_flags('LDFLAGS', spec['lapack'].libs.search_flags)
spack_env.append_flags('LIBS', spec['lapack'].libs.link_flags)

At this point it's possible to proceed with the installation of ``elpa ^mpich``
At this point, it's possible to proceed with the installation of ``elpa ^mpich``

------------------------------
Retrieving Library Information
Expand All @@ -213,7 +213,7 @@ This section covers how to retrieve library information from dependencies and ho
Accessing dependency libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you need to access the libraries of a dependency, you can do so via the ``libs`` property of the spec, for example in the ``arpack-ng`` package:
If we need to access the libraries of a dependency, we can do so via the ``libs`` property of the spec, for example in the ``arpack-ng`` package:

.. code-block:: python

Expand All @@ -229,13 +229,13 @@ If you need to access the libraries of a dependency, you can do so via the ``lib
Note that ``arpack-ng`` is querying virtual dependencies, which Spack automatically resolves to the installed implementation (e.g. ``openblas`` for ``blas``).

We've started work on a package for ``armadillo``.
You should open it, read through the comment that starts with ``# TUTORIAL:`` and complete the ``cmake_args`` section:
We should open it, read through the comment that starts with ``# TUTORIAL:`` and complete the ``cmake_args`` section:

.. code-block:: console

root@advanced-packaging-tutorial:/# spack edit armadillo

If you followed the instructions in the package, when you are finished your ``cmake_args`` method should look like:
If we followed the instructions in the package, when we are finished our ``cmake_args`` method should look like:

.. code-block:: python

Expand All @@ -256,10 +256,10 @@ If you followed the instructions in the package, when you are finished your ``cm
'-DDETECT_HDF5={0}'.format('ON' if '+hdf5' in spec else 'OFF')
]

As you can see, getting the list of libraries that your dependencies provide is as easy as accessing the their ``libs`` attribute.
Furthermore, the interface remains the same whether you are querying regular or virtual dependencies.
As we can see, getting the list of libraries that our dependencies provide is as easy as accessing the their ``libs`` attribute.
Furthermore, the interface remains the same whether we are querying regular or virtual dependencies.

At this point you can complete the installation of ``armadillo`` using ``openblas`` as a LAPACK provider (``armadillo ^openblas ^mpich``):
At this point, we can complete the installation of ``armadillo`` using ``openblas`` as a LAPACK provider (``armadillo ^openblas ^mpich``):

.. code-block:: console

Expand All @@ -280,7 +280,7 @@ At this point you can complete the installation of ``armadillo`` using ``openbla
Fetch: 0.01s. Build: 3.96s. Total: 3.98s.
[+] /usr/local/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/armadillo-8.100.1-n2eojtazxbku6g4l5izucwwgnpwz77r4

Hopefully the installation went fine and the code we added expanded to the right list of semicolon separated libraries (you are encouraged to open ``armadillo``'s build logs to double check).
Hopefully the installation went fine and the code we added expanded to the right list of semicolon separated libraries (we are encouraged to open ``armadillo``'s build logs to double check).

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Providing libraries to dependents
Expand Down Expand Up @@ -338,7 +338,7 @@ Let's edit it:
root@advanced-packaging-tutorial:/# spack edit netlib-lapack

and follow the instructions in the ``# TUTORIAL:`` comment as before.
What we need to implement is:
What we will implement is:

.. code-block:: python

Expand All @@ -353,7 +353,7 @@ i.e., a property that returns the correct list of libraries for the LAPACK inter

We use the name ``lapack_libs`` rather than ``libs`` because ``netlib-lapack`` can also provide ``blas``, and when it does it is provided as a separate library file.
Using this name ensures that when dependents ask for ``lapack`` libraries, ``netlib-lapack`` will retrieve only the libraries associated with the ``lapack`` interface.
Now we can finally install ``armadillo ^netlib-lapack ^mpich``:
Now we will finally install ``armadillo ^netlib-lapack ^mpich``:

.. code-block:: console

Expand All @@ -379,8 +379,8 @@ Attach attributes to other packages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Build tools also usually provide a set of executables that can be used when another package is being installed.
Spack gives you the opportunity to monkey-patch dependent modules and attach attributes to them.
This helps make the packager's experience as similar as possible to what would have been the manual installation of the same package.
Spack gives us the opportunity to monkey-patch dependent modules and attach attributes to them.
This helps make our experience as similar as possible to what would have been the manual installation of the same package.

An example here is the ``automake`` package, which overrides
:py:func:`setup_dependent_package <spack.package.PackageBase.setup_dependent_package>`:
Expand Down Expand Up @@ -431,13 +431,13 @@ Let's look at an example and try to install ``netcdf ^mpich``:
/usr/local/var/spack/stage/netcdf-4.4.1.1-gk2xxhbqijnrdwicawawcll4t3c7dvoj/netcdf-4.4.1.1/spack-build-out.txt

We can see from the error that ``netcdf`` needs to know how to link the *high-level interface* of ``hdf5``, and thus passes the extra parameter ``hl`` after the request to retrieve it.
Clearly the implementation in the ``hdf5`` package is not complete, and we need to fix it:
Clearly the implementation in the ``hdf5`` package is not complete, and we will fix it:

.. code-block:: console

root@advanced-packaging-tutorial:/# spack edit hdf5

If you followed the instructions correctly, the code added to the ``lib`` property should be similar to:
If we followed the instructions correctly, the code added to the ``lib`` property should be similar to:

.. code-block:: python
:emphasize-lines: 1
Expand All @@ -451,7 +451,7 @@ If you followed the instructions correctly, the code added to the ``lib`` proper
)

where we highlighted the line retrieving the extra parameters.
Now we can successfully complete the installation of ``netcdf ^mpich``:
Now we will successfully complete the installation of ``netcdf ^mpich``:

.. code-block:: console

Expand Down
36 changes: 18 additions & 18 deletions tutorial_basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
Basic Installation Tutorial
=========================================

This tutorial will guide you through the process of installing software using Spack.
We will first cover the ``spack install`` command, focusing on the power of the spec syntax and the flexibility it gives to users.
This tutorial will guide us through the process of installing software using Spack.
First, we will cover the ``spack install`` command, focusing on the power of the spec syntax and the flexibility it gives to users.
We will also cover the ``spack find`` command for viewing installed packages and the ``spack uninstall`` command for uninstalling them.
Finally, we will touch on how Spack manages compilers, especially as it relates to using Spack-built compilers within Spack.
We will include full output from all of the commands demonstrated, although we will frequently call attention to only small portions of that output (or merely to the fact that it succeeded).
Expand All @@ -35,7 +35,7 @@ Spack has some nice command-line integration tools, so instead of simply prepend

$ . share/spack/setup-env.sh

You're good to go!
We're good to go!

-----------------
What is in Spack?
Expand Down Expand Up @@ -72,20 +72,20 @@ Let's go ahead and install ``gmake``,
.. literalinclude:: outputs/basics/gmake.out
:language: console

You will see Spack installed ``gmake``, ``gcc-runtime``, and ``glibc``.
We will see Spack installed ``gmake``, ``gcc-runtime``, and ``glibc``.
The ``glibc`` and ``gcc-runtime`` packages are automatically tracked by Spack to manage consistency requirements among compiler runtimes.
They do not represent separate software builds from source, but are records of the system's compiler runtime components Spack used for the install.
For the rest of this section, we will ignore these components and focus on the packages explicitly installed.

Spack can install software either from source or from a binary cache.
Packages in the binary cache are signed with GPG for security.
For the tutorial we have prepared a binary cache so you don't have to wait on slow compilation from source.
For the tutorial we have prepared a binary cache so we don't have to wait on slow compilation from source.
To be able to install from the binary cache, we will need to configure Spack with the location of the binary cache and trust the GPG key that the binary cache was signed with.

.. literalinclude:: outputs/basics/mirror.out
:language: console

You'll learn more about configuring Spack later in the tutorial, but for now you will be able to install the rest of the packages in the tutorial from a binary cache using the same ``spack install`` command.
We'll learn more about configuring Spack later in the tutorial, but for now we will be able to install the rest of the packages in the tutorial from a binary cache using the same ``spack install`` command.
By default this will install the binary cached version if it exists and fall back on installing from source if it does not.

Spack's "spec" syntax is the interface by which we can request specific configurations of a package.
Expand All @@ -97,7 +97,7 @@ The ``%`` sigil is used to specify compilers.
Note that this installation is located separately from the previous one.
We will discuss this in more detail later, but this is part of what allows Spack to support many versions of software packages.

You can check for particular versions before requesting them.
We can check for particular versions before requesting them.
We will use the ``spack versions`` command to see the available versions, and then install a different version of ``zlib-ng``.

.. literalinclude:: outputs/basics/versions-zlib.out
Expand Down Expand Up @@ -149,8 +149,8 @@ Anything we could specify about the top-level package, we can also specify about
Packages can also be referred to from the command line by their package hash.
Using the ``spack find -lf`` command earlier we saw that the hash of our optimized installation of zlib-ng (``cflags="-O3"``) began with ``umrbkwv``.
We can now explicitly build with that package without typing the entire spec, by using the ``/`` sigil to refer to it by hash.
As with other tools like Git, you do not need to specify an *entire* hash on the command line.
You can specify just enough digits to identify a hash uniquely.
As with other tools like Git, we do not need to specify an *entire* hash on the command line.
We can specify just enough digits to identify a hash uniquely.
If a hash prefix is ambiguous (i.e., two or more installed packages share the prefix) then Spack will report an error.

.. literalinclude:: outputs/basics/tcl-zlib-hash.out
Expand All @@ -164,7 +164,7 @@ Note that each package has a top-level entry, even if it also appears as a depen

Let's move on to slightly more complicated packages.
HDF5 is a good example of a more complicated package, with an MPI dependency.
If we install it with default settings it will build with OpenMPI.
If we install it with default settings, it will build with OpenMPI.

.. literalinclude:: outputs/basics/hdf5.out
:language: console
Expand Down Expand Up @@ -192,7 +192,7 @@ The partial spec ``^mpi@3`` can be satisfied by any of several MPI implementatio
.. literalinclude:: outputs/basics/hdf5-hl-mpi.out
:language: console

We'll do a quick check in on what we have installed so far.
Let's do a quick check in on what we have installed so far.

.. literalinclude:: outputs/basics/find-ldf-2.out
:language: console
Expand Down Expand Up @@ -234,7 +234,7 @@ Again, the ``spack graph`` command shows the full DAG of the dependency informat
.. literalinclude:: outputs/basics/graph-trilinos.out
:language: console

You can control how the output is displayed with a number of options.
We can control how the output is displayed with a number of options.

The ASCII output from ``spack graph`` can be difficult to parse for complicated packages.
The output can be changed to the Graphviz ``.dot`` format using the ``--dot`` flag.
Expand All @@ -250,7 +250,7 @@ Uninstalling Packages
---------------------

Earlier we installed many configurations each of zlib-ng and Tcl.
Now we will go through and uninstall some of those packages that we didn't really need.
Now, let's go through and uninstall some of those packages that we didn't really need.

.. literalinclude:: outputs/basics/find-d-tcl.out
:language: console
Expand All @@ -269,8 +269,8 @@ We can uninstall packages by spec using the same syntax as install.
We can also uninstall packages by referring only to their hash.

We can use either the ``--force`` (or ``-f``) flag or the ``--dependents`` (or ``-R``) flag to remove packages that are required by another installed package.
Use ``--force`` to remove just the specified package, leaving dependents broken.
Use ``--dependents`` to remove the specified package and all of its dependents.
Let's use ``--force`` to remove just the specified package, leaving dependents broken.
Let's use ``--dependents`` to remove the specified package and all of its dependents.

.. literalinclude:: outputs/basics/uninstall-needed.out
:language: console
Expand All @@ -291,7 +291,7 @@ The ``--all`` (or ``-a``) flag can be used to uninstall all packages matching an
Advanced ``spack find`` Usage
-----------------------------

We will go over some additional uses for the ``spack find`` command not already covered in the :ref:`basics-tutorial-install` and
Let's go over some additional uses for the ``spack find`` command not already covered in the :ref:`basics-tutorial-install` and
:ref:`basics-tutorial-uninstall` sections.

The ``spack find`` command can accept what we call "anonymous specs." These are expressions in spec syntax that do not contain a package name.
Expand Down Expand Up @@ -321,7 +321,7 @@ The ``spack compilers`` command is an alias for ``spack compiler list``.
:language: console

The compilers are maintained in a YAML file (``compilers.yaml``).
Later in the tutorial, you will learn how to configure compilers by hand for special cases.
Later in the tutorial, we will learn how to configure compilers by hand for special cases.
Spack also has tools to add compilers, and compilers built with Spack can be added to the configuration.

.. literalinclude:: outputs/basics/install-gcc-12.1.0.out
Expand All @@ -332,7 +332,7 @@ Spack also has tools to add compilers, and compilers built with Spack can be add

We can add GCC to Spack as an available compiler using the ``spack compiler add`` command.
This will allow future packages to build with ``gcc@12.3.0``.
To avoid having to copy and paste GCC's path, we can use ``spack location -i`` to get the installation prefix.
To avoid having to copy and paste GCC's path, we will use ``spack location -i`` to get the installation prefix.

.. literalinclude:: outputs/basics/compiler-add-location.out
:language: console
Expand Down
Loading