Building With Spack
Spack is a system for installing packages for HPC centers. Spack can be easily installed on supercomputers since it does not require root privileges. Spack works by building code from source.
This section provides an overview of installing software with spack and some of the complexities of spack. This is not a full documentation of spack, it just contains the things we see come up often. Read through their documentation to understand better how to use spack.
Spack is by no means perfect. It has plenty of bugs and nuances.
Installing spack
The official install guide for spack
is here.
Since the install is fairly simple, we'll just repeat here:
# Clone spack into your current directory
# This will clone spack v0.20
git clone --depth=100 --branch=releases/v0.20 https://github.com/spack/spack.git
# Setup the spack environment for this shell
# This will modify environment variables
cd spack
. share/spack/setup-env.sh
# Ensure that spack is loaded every time you reboot or start a new shell
# ~/.bashrc is called every time you login
echo ". ${PWD}/share/spack/setup-env.sh" >> ~/.bashrc
NOTE: spack
creates a folder in your HOME
directory for storing caches. The folder is located at ~/.spack
.
ls ~/.spack
Uninstalling spack
# All packages will be installed under your cloned spack directory
rm -rf /path/to/spack
# Spack automatically creates ~/.spack for holding caches
rm -rf ~/.spack
# Remove ". ${PWD}/share/spack/setup-env.sh" from ~/.bashrc
List packages provided by spack
To identify the set of packages that spack can install, use spack list
.
# List every package spack has
spack list
# Will list all packages which have the word zlib
spack list zlib
Spack packages also have various properties:
- Version: the available versions of a package
- Variants: add, remove, or modify features of the package. For example, zlib provides a variants for enabling/disabling compiler optimization.
- Dependencies: the software this package depends on.
# Will list the details of a package (versions, description, etc.)
spack info zlib
In our case, the output is:
Package: zlib
Description:
A free, general-purpose, legally unencumbered lossless data-compression
library.
Homepage: https://zlib.net
Preferred version:
1.2.12 https://zlib.net/fossils/zlib-1.2.12.tar.gz
Safe versions:
1.2.12 https://zlib.net/fossils/zlib-1.2.12.tar.gz
Deprecated versions:
1.2.11 https://zlib.net/fossils/zlib-1.2.11.tar.gz
1.2.8 https://zlib.net/fossils/zlib-1.2.8.tar.gz
1.2.3 https://zlib.net/fossils/zlib-1.2.3.tar.gz
Variants:
Name [Default] When Allowed values Description
============== ==== ============== ===================================================
optimize [on] -- on, off Enable -O2 for a more optimized lib
pic [on] -- on, off Produce position-independent code (for shared libs)
shared [on] -- on, off Enables the build of shared libraries.
Build Dependencies:
None
Link Dependencies:
None
Run Dependencies:
None
This output may change with different versions of spack
.
Install packages
There are many parameters that can be set when installing a package. However, the installation methods that come up most often are below:
# This will install the default tar package
spack install zlib
# This will install zlib version 1.2.12
# This should say zlib 1.2.12 is already installed
spack install zlib@1.2.12
# This will install zlib 1.2.11 without optimization
# The "-" in -optimize means subtract
spack install zlib@1.2.12 -optimize
# This will install zlib 1.2.11 with optimization
# The "+" in +optimize means add
# This will say that zlib is already installed,
# since +optimize is enabled by default
spack install zlib@1.2.12 +optimize
List installed packages
All installed packages
To find all installed packages, run:
spack find
Particular package
To find a particluar package, run:
spack find zlib
Output:
==> 2 installed packages
-- linux-linuxmint20-zen2 / gcc@9.3.0 ---------------------------
zlib@1.2.12 zlib@1.2.12
This output is unhelpful since there are two different versions of zlib
installed.
Particular package with verbosity
To get a more verbose output to identify differences between packages, run:
spack find -f -v zlib
Output:
==> 2 installed packages
-- linux-linuxmint20-zen2 / gcc@9.3.0 ---------------------------
zlib@1.2.12%gcc ~optimize+pic+shared patches=0d38234 zlib@1.2.12%gcc +optimize+pic+shared patches=0d38234
Load packages
In order to make use of a spack package, the package must be loaded. Spack primarily works by setting environment
variables, such as PATH
and LD_LIBRARY_PATH
.
To load the environment variables, do:
# Load the version of zlib with optimization
spack load zlib +optimize
Spack load must be executed every time you open a new shell or reboot your computer. You can add the spack load to your
~/.bashrc
to avoid having to do this.
There are various caveats to know about spack load:
- Spack packages for C++ libraries may use the
CMAKE_PREFIX_PATH
variable and not set any other environment variable. This means you really do need to use CMake when building C++ projects and using spack for installing things. CMake is discussed later, just be warned that some spack packages do this and building using methods alternative to CMake (e.g., building manually) will likely fail. - Sometimes calling spack load can cause conflict with system packages. Unless otherwise specified, spack will install
everything -- even things which your system already has installed. This can cause programs to break. I notice that
vim
andnano
sometimes segfault after spack load because it installs custom versions of software that vim and nano were not compiled with. - You should not run spack load for two different versions of the same package. This will almost definitely lead to correctness problems.
Unload packages
To unload a package's changes to the current environment, run:
# Unloads every spack package
spack unload
# Unload the zlib package specifically
spack unload zlib
Uninstall packages
To uninstall packages, run:
# Uninstall a specific package
# Will fail if more than one package matches query
spack uninstall zlib +optimize
# Uninstall all packages matching query
spack uninstall --all zlib
What happens if spack
fails?
Sometimes, you may find that a package fails to compile for some reason. These are the general steps to take when something goes wrong:
- Check if the software version you're installing is compatible with your machine. If it's not easy to discover with Google or AI, then move on to step 2. It's likely a bug in the spack package
- Try checking if there is a new stable release of spack. If so, try upgrading by switching to that version. You should be able to do
this without destroying all of your packages by using
git checkout
- Try deleting your spack cache directory.
rm -rf ~/.spack
And then try reinstalling the package. - Try reinstalling spack by following 2.1.2 and 2.1.1 instructions
- Submit an issue to the spack team. They aren't a very large team, so it may take time to address. You'll have to either find another package or install from scratch
Sometimes, spack may successfully install the package, but you may still find that your program doesn't compile or execute. If this is the case, you'll have to do some research (Google, ChatGPT, etc.) to identify why this is happening. You may also find it helpful to check exactly what spack installed. You can find where spack installed your package as follows:
# Find where the "zlib" package is installed
spack find --paths zlib