Tutorial setup

If you have not done the prior sections, you’ll need to set Spack up like this:

git clone https://github.com/spack/spack
. spack/share/spack/setup-env.sh
spack tutorial

See the Basic Installation Tutorial for full details on setup. For more help join us in the #tutorial channel on Slack – get an invitation at spackpm.herokuapp.com

Scripting with Spack

This tutorial introduces advanced Spack features related to scripting. Specifically, we will show you how to write scripts using spack find and spack python. Earlier sections of the tutorial demonstrated using spack find to list and search installed packages. The spack python command gives you access to all of Spack’s internal APIs, allowing you to write more complex queries, for example.

Since Spack has an extensive API, we’ll only scratch the surface here. We’ll give you enough information to start writing your own scripts and to find what you need, with a little digging.

Setting up the tutorial

Before proceeding, let’s ensure the outputs for this segment are reasonable. Since you may have a lot of packages installed from earlier sections of the tutorial, we want to perform a little cleanup.

Let’s remove gcc@8.3.0 and re-install hdf5 and zlib@clang using the following commands:

$ spack uninstall -ay
==> Successfully uninstalled patchelf@0.13%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/2txxrad
==> Successfully uninstalled gcc@8.4.0%gcc@7.5.0~binutils+bootstrap~graphite~nvptx~piclibs~strip languages=c,c++,fortran patches=b48e48736062e64a6da7cbe7e21a6c1c89422d1f49ef547c73b479a3f3f4935f arch=linux-ubuntu18.04-x86_64/jmhauhy
==> Successfully uninstalled diffutils@3.8%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/kg5jymj
==> Successfully uninstalled zlib@1.2.11%clang@7.0.0+optimize+pic+shared arch=linux-ubuntu18.04-x86_64/atdrszv
==> Successfully uninstalled autoconf@2.69%gcc@7.5.0 patches=35c449281546376449766f92d49fc121ca50e330e60fefcfc9be2af3253082c2,7793209b33013dc0f81208718c68440c5aae80e7a1c4b8d336e382525af791a7,a49dd5bac3b62daa0ff688ab4d508d71dbd2f4f8d7e2a02321926346161bf3ee arch=linux-ubuntu18.04-x86_64/7hurwa7
==> Successfully uninstalled util-macros@1.19.3%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/h5cf2g4
==> Successfully uninstalled libtool@2.4.6%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/2kia6gf
==> Successfully uninstalled automake@1.16.3%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/6rqxcsn
==> Successfully uninstalled cmake@3.21.4%gcc@7.5.0~doc+ncurses+openssl+ownlibs~qt build_type=Release arch=linux-ubuntu18.04-x86_64/anj6kcx
==> Successfully uninstalled hdf5@1.10.7%gcc@7.5.0~cxx~fortran~hl~ipo~java+mpi+shared~szip~threadsafe+tools api=default build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64/vt7sza3
==> Successfully uninstalled m4@1.4.19%gcc@7.5.0+sigsegv patches=9dc5fbd0d5cb1037ab1e6d0ecc74a30df218d0a94bdd5a02759a97f62daca573,bfdffa7c2eb01021d5849b36972c069693654ad826c1a20b53534009a4ec7a89 arch=linux-ubuntu18.04-x86_64/ybvezwz
==> Successfully uninstalled openmpi@4.1.1%gcc@7.5.0~atomics~cuda~cxx~cxx_exceptions+gpfs~internal-hwloc~java~legacylaunchers~lustre~memchecker~pmi~pmix~singularity~sqlite3+static~thread_multiple+vt+wrapper-rpath fabrics=none schedulers=none arch=linux-ubuntu18.04-x86_64/p5qicac
==> Successfully uninstalled perl@5.34.0%gcc@7.5.0+cpanm+shared+threads arch=linux-ubuntu18.04-x86_64/672tzld
==> Successfully uninstalled mpc@1.1.0%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/tjv2csr
==> Successfully uninstalled pkgconf@1.8.0%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/ucp6vz7
==> Successfully uninstalled hwloc@2.6.0%gcc@7.5.0~cairo~cuda~gl~libudev+libxml2~netloc~nvml~opencl+pci~rocm+shared arch=linux-ubuntu18.04-x86_64/gedgnpg
==> Successfully uninstalled berkeley-db@18.1.40%gcc@7.5.0+cxx~docs+stl patches=b231fcc4d5cff05e5c3a4814f6a5af0e9a966428dc2176540d2c05aff41de522 arch=linux-ubuntu18.04-x86_64/ue5lnfm
==> Successfully uninstalled gdbm@1.19%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/oftaepj
==> Successfully uninstalled mpfr@3.1.6%gcc@7.5.0 patches=7a6dd71bcda4803d6b89612706a17b8816e1acd5dd9bf1bec29cf748f3b60008 arch=linux-ubuntu18.04-x86_64/z7hztfv
==> Successfully uninstalled bzip2@1.0.8%gcc@7.5.0~debug~pic+shared arch=linux-ubuntu18.04-x86_64/55rtzz4
==> Successfully uninstalled openssh@8.7p1%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/ux36qlb
==> Successfully uninstalled numactl@2.0.14%gcc@7.5.0 patches=4e1d78cbbb85de625bad28705e748856033eaafab92a66dffd383a3d7e00cc94,62fc8a8bf7665a60e8f4c93ebbd535647cebf74198f7afafec4c085a8825c006,ff37630df599cfabf0740518b91ec8daaf18e8f288b19adaae5364dc1f6b2296 arch=linux-ubuntu18.04-x86_64/3opot4q
==> Successfully uninstalled libevent@2.1.12%gcc@7.5.0+openssl arch=linux-ubuntu18.04-x86_64/xai6pyc
==> Successfully uninstalled libsigsegv@2.13%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/g2vgcne
==> Successfully uninstalled libpciaccess@0.16%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/ryhmw2g
==> Successfully uninstalled libxml2@2.9.12%gcc@7.5.0~python arch=linux-ubuntu18.04-x86_64/2hw4ddh
==> Successfully uninstalled readline@8.1%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/27u6g7p
==> Successfully uninstalled openssl@1.1.1l%gcc@7.5.0~docs certs=system arch=linux-ubuntu18.04-x86_64/lygx3cq
==> Successfully uninstalled gmp@6.2.1%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/7kpzyzg
==> Successfully uninstalled libedit@3.1-20210216%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64/3lzuqwn
==> Successfully uninstalled ncurses@6.2%gcc@7.5.0~symlinks+termlib abi=none arch=linux-ubuntu18.04-x86_64/d34lizg
==> Successfully uninstalled xz@5.2.5%gcc@7.5.0~pic libs=shared,static arch=linux-ubuntu18.04-x86_64/nplaaps
==> Successfully uninstalled libiconv@1.16%gcc@7.5.0 libs=shared,static arch=linux-ubuntu18.04-x86_64/qi7dxj6
==> Successfully uninstalled zlib@1.2.11%gcc@7.5.0+optimize+pic+shared arch=linux-ubuntu18.04-x86_64/3rlgy7y
$ spack compiler rm gcc@8.4.0
==> Removed compiler gcc@8.4.0
$ spack install hdf5
==> Installing pkgconf-1.8.0-ucp6vz7fe6ihtcmqav3vucwgqjwyw7po
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/pkgconf-1.8.0/linux-ubuntu18.04-x86_64-gcc-7.5.0-pkgconf-1.8.0-ucp6vz7fe6ihtcmqav3vucwgqjwyw7po.spack
==> Extracting pkgconf-1.8.0-ucp6vz7fe6ihtcmqav3vucwgqjwyw7po from binary cache
==> Installing patchelf-0.13-2txxradgazf7zvc5kzwmc26oqjuop7ej
==> No binary for patchelf-0.13-2txxradgazf7zvc5kzwmc26oqjuop7ej found: installing from source
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/4c/4c7ed4bcfc1a114d6286e4a0d3c1a90db147a4c3adda1814ee0eee0f9ee917ed.tar.bz2
==> No patches needed for patchelf
==> patchelf: Executing phase: 'autoreconf'
==> patchelf: Executing phase: 'configure'
==> patchelf: Executing phase: 'build'
==> patchelf: Executing phase: 'install'
==> patchelf: Successfully installed patchelf-0.13-2txxradgazf7zvc5kzwmc26oqjuop7ej
  Fetch: 0.01s.  Build: 7.16s.	Total: 7.16s.
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/patchelf-0.13-2txxradgazf7zvc5kzwmc26oqjuop7ej
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/pkgconf-1.8.0-ucp6vz7fe6ihtcmqav3vucwgqjwyw7po
==> Installing berkeley-db-18.1.40-ue5lnfmm3yaiwm2jha4pnbg2s4h7jaqb
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/berkeley-db-18.1.40/linux-ubuntu18.04-x86_64-gcc-7.5.0-berkeley-db-18.1.40-ue5lnfmm3yaiwm2jha4pnbg2s4h7jaqb.spack
==> Extracting berkeley-db-18.1.40-ue5lnfmm3yaiwm2jha4pnbg2s4h7jaqb from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/berkeley-db-18.1.40-ue5lnfmm3yaiwm2jha4pnbg2s4h7jaqb
==> Installing libiconv-1.16-qi7dxj6rgdydno5mdjzyolz6applztig
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/libiconv-1.16/linux-ubuntu18.04-x86_64-gcc-7.5.0-libiconv-1.16-qi7dxj6rgdydno5mdjzyolz6applztig.spack
==> Extracting libiconv-1.16-qi7dxj6rgdydno5mdjzyolz6applztig from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/libiconv-1.16-qi7dxj6rgdydno5mdjzyolz6applztig
==> Installing zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/zlib-1.2.11/linux-ubuntu18.04-x86_64-gcc-7.5.0-zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd.spack
==> Extracting zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd
==> Installing libsigsegv-2.13-g2vgcnev7aspdihdmfbviefdbinclpy7
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/libsigsegv-2.13/linux-ubuntu18.04-x86_64-gcc-7.5.0-libsigsegv-2.13-g2vgcnev7aspdihdmfbviefdbinclpy7.spack
==> Extracting libsigsegv-2.13-g2vgcnev7aspdihdmfbviefdbinclpy7 from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/libsigsegv-2.13-g2vgcnev7aspdihdmfbviefdbinclpy7
==> Installing util-macros-1.19.3-h5cf2g4fzeytdsypsm5gsb4h6saddfev
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/util-macros-1.19.3/linux-ubuntu18.04-x86_64-gcc-7.5.0-util-macros-1.19.3-h5cf2g4fzeytdsypsm5gsb4h6saddfev.spack
==> Extracting util-macros-1.19.3-h5cf2g4fzeytdsypsm5gsb4h6saddfev from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/util-macros-1.19.3-h5cf2g4fzeytdsypsm5gsb4h6saddfev
==> Installing xz-5.2.5-nplaapsuxr5djslmxm6sdmaw2xl4d2ti
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/xz-5.2.5/linux-ubuntu18.04-x86_64-gcc-7.5.0-xz-5.2.5-nplaapsuxr5djslmxm6sdmaw2xl4d2ti.spack
==> Extracting xz-5.2.5-nplaapsuxr5djslmxm6sdmaw2xl4d2ti from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/xz-5.2.5-nplaapsuxr5djslmxm6sdmaw2xl4d2ti
==> Installing ncurses-6.2-d34lizgt45miuctn4cmx7quklvukdd2w
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/ncurses-6.2/linux-ubuntu18.04-x86_64-gcc-7.5.0-ncurses-6.2-d34lizgt45miuctn4cmx7quklvukdd2w.spack
==> Extracting ncurses-6.2-d34lizgt45miuctn4cmx7quklvukdd2w from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/ncurses-6.2-d34lizgt45miuctn4cmx7quklvukdd2w
==> Installing diffutils-3.8-kg5jymjbqjurpq52nvycbddt5ia5uypy
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/diffutils-3.8/linux-ubuntu18.04-x86_64-gcc-7.5.0-diffutils-3.8-kg5jymjbqjurpq52nvycbddt5ia5uypy.spack
==> Extracting diffutils-3.8-kg5jymjbqjurpq52nvycbddt5ia5uypy from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/diffutils-3.8-kg5jymjbqjurpq52nvycbddt5ia5uypy
==> Installing m4-1.4.19-ybvezwzldr6ibw767ihpeoal625y76qb
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/m4-1.4.19/linux-ubuntu18.04-x86_64-gcc-7.5.0-m4-1.4.19-ybvezwzldr6ibw767ihpeoal625y76qb.spack
==> Extracting m4-1.4.19-ybvezwzldr6ibw767ihpeoal625y76qb from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/m4-1.4.19-ybvezwzldr6ibw767ihpeoal625y76qb
==> Installing libxml2-2.9.12-2hw4ddh7dbtl3wcw5hrt4kk2fkwhfuzj
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/libxml2-2.9.12/linux-ubuntu18.04-x86_64-gcc-7.5.0-libxml2-2.9.12-2hw4ddh7dbtl3wcw5hrt4kk2fkwhfuzj.spack
==> Extracting libxml2-2.9.12-2hw4ddh7dbtl3wcw5hrt4kk2fkwhfuzj from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/libxml2-2.9.12-2hw4ddh7dbtl3wcw5hrt4kk2fkwhfuzj
==> Installing libedit-3.1-20210216-3lzuqwnyuelfhjrxpn45akh7huu3ifr5
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/libedit-3.1-20210216/linux-ubuntu18.04-x86_64-gcc-7.5.0-libedit-3.1-20210216-3lzuqwnyuelfhjrxpn45akh7huu3ifr5.spack
==> Extracting libedit-3.1-20210216-3lzuqwnyuelfhjrxpn45akh7huu3ifr5 from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/libedit-3.1-20210216-3lzuqwnyuelfhjrxpn45akh7huu3ifr5
==> Installing readline-8.1-27u6g7pchcquj67llpfzttc6n7e5pfjg
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/readline-8.1/linux-ubuntu18.04-x86_64-gcc-7.5.0-readline-8.1-27u6g7pchcquj67llpfzttc6n7e5pfjg.spack
==> Extracting readline-8.1-27u6g7pchcquj67llpfzttc6n7e5pfjg from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/readline-8.1-27u6g7pchcquj67llpfzttc6n7e5pfjg
==> Installing bzip2-1.0.8-55rtzz4s6m4swr6x7exse22ucbmluwl3
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/bzip2-1.0.8/linux-ubuntu18.04-x86_64-gcc-7.5.0-bzip2-1.0.8-55rtzz4s6m4swr6x7exse22ucbmluwl3.spack
==> Extracting bzip2-1.0.8-55rtzz4s6m4swr6x7exse22ucbmluwl3 from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/bzip2-1.0.8-55rtzz4s6m4swr6x7exse22ucbmluwl3
==> Installing libtool-2.4.6-2kia6gf4yz6k3vsdqlg5lmp6n5hplrxq
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/libtool-2.4.6/linux-ubuntu18.04-x86_64-gcc-7.5.0-libtool-2.4.6-2kia6gf4yz6k3vsdqlg5lmp6n5hplrxq.spack
==> Extracting libtool-2.4.6-2kia6gf4yz6k3vsdqlg5lmp6n5hplrxq from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/libtool-2.4.6-2kia6gf4yz6k3vsdqlg5lmp6n5hplrxq
==> Installing gdbm-1.19-oftaepjelizkam37ezxwkuw27clnosqn
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/gdbm-1.19/linux-ubuntu18.04-x86_64-gcc-7.5.0-gdbm-1.19-oftaepjelizkam37ezxwkuw27clnosqn.spack
==> Extracting gdbm-1.19-oftaepjelizkam37ezxwkuw27clnosqn from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/gdbm-1.19-oftaepjelizkam37ezxwkuw27clnosqn
==> Installing libpciaccess-0.16-ryhmw2gqeeqclg65uuabqgsgpiac2nm2
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/libpciaccess-0.16/linux-ubuntu18.04-x86_64-gcc-7.5.0-libpciaccess-0.16-ryhmw2gqeeqclg65uuabqgsgpiac2nm2.spack
==> Extracting libpciaccess-0.16-ryhmw2gqeeqclg65uuabqgsgpiac2nm2 from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/libpciaccess-0.16-ryhmw2gqeeqclg65uuabqgsgpiac2nm2
==> Installing perl-5.34.0-672tzldkvypvrxirrs5okvjrfvhxzyzv
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/perl-5.34.0/linux-ubuntu18.04-x86_64-gcc-7.5.0-perl-5.34.0-672tzldkvypvrxirrs5okvjrfvhxzyzv.spack
==> Extracting perl-5.34.0-672tzldkvypvrxirrs5okvjrfvhxzyzv from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/perl-5.34.0-672tzldkvypvrxirrs5okvjrfvhxzyzv
==> Installing hwloc-2.6.0-gedgnpght7xquztmkhthmaid6lbhlz4p
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/hwloc-2.6.0/linux-ubuntu18.04-x86_64-gcc-7.5.0-hwloc-2.6.0-gedgnpght7xquztmkhthmaid6lbhlz4p.spack
==> Extracting hwloc-2.6.0-gedgnpght7xquztmkhthmaid6lbhlz4p from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/hwloc-2.6.0-gedgnpght7xquztmkhthmaid6lbhlz4p
==> Installing openssl-1.1.1l-lygx3cqqbvl5gkyvfkggphorm7xus2ih
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/openssl-1.1.1l/linux-ubuntu18.04-x86_64-gcc-7.5.0-openssl-1.1.1l-lygx3cqqbvl5gkyvfkggphorm7xus2ih.spack
==> Extracting openssl-1.1.1l-lygx3cqqbvl5gkyvfkggphorm7xus2ih from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/openssl-1.1.1l-lygx3cqqbvl5gkyvfkggphorm7xus2ih
==> Installing autoconf-2.69-7hurwa7ymeksnawbazxutf7k7qvjm772
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/autoconf-2.69/linux-ubuntu18.04-x86_64-gcc-7.5.0-autoconf-2.69-7hurwa7ymeksnawbazxutf7k7qvjm772.spack
==> Extracting autoconf-2.69-7hurwa7ymeksnawbazxutf7k7qvjm772 from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/autoconf-2.69-7hurwa7ymeksnawbazxutf7k7qvjm772
==> Installing cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/cmake-3.21.4/linux-ubuntu18.04-x86_64-gcc-7.5.0-cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea.spack
==> Extracting cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea from binary cache
==> Warning: patchelf --print-rpath /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea/share/cmake-3.21/Modules/Internal/CPack/CPack.OSXScriptLauncher.in produced an error [Command exited with status 1:
    '/home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/patchelf-0.13-2txxradgazf7zvc5kzwmc26oqjuop7ej/bin/patchelf' '--print-rpath' '/home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea/share/cmake-3.21/Modules/Internal/CPack/CPack.OSXScriptLauncher.in'
patchelf: not an ELF executable
]
==> Warning: patchelf --force-rpath --set-rpath /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea/share/cmake-3.21/Modules/Internal/CPack/CPack.OSXScriptLauncher.in failed with error Command exited with status 1:
    '/home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/patchelf-0.13-2txxradgazf7zvc5kzwmc26oqjuop7ej/bin/patchelf' '--force-rpath' '--set-rpath' '' '/home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea/share/cmake-3.21/Modules/Internal/CPack/CPack.OSXScriptLauncher.in'
patchelf: not an ELF executable

[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/cmake-3.21.4-anj6kcxdxzhfufoypya56mmsmxlyucea
==> Installing libevent-2.1.12-xai6pycqx4h6n2l7f676q3kwql5zjdaw
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/libevent-2.1.12/linux-ubuntu18.04-x86_64-gcc-7.5.0-libevent-2.1.12-xai6pycqx4h6n2l7f676q3kwql5zjdaw.spack
==> Extracting libevent-2.1.12-xai6pycqx4h6n2l7f676q3kwql5zjdaw from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/libevent-2.1.12-xai6pycqx4h6n2l7f676q3kwql5zjdaw
==> Installing openssh-8.7p1-ux36qlbxdga4c5oragb7o5r4y7bsgbpy
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/openssh-8.7p1/linux-ubuntu18.04-x86_64-gcc-7.5.0-openssh-8.7p1-ux36qlbxdga4c5oragb7o5r4y7bsgbpy.spack
==> Extracting openssh-8.7p1-ux36qlbxdga4c5oragb7o5r4y7bsgbpy from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/openssh-8.7p1-ux36qlbxdga4c5oragb7o5r4y7bsgbpy
==> Installing automake-1.16.3-6rqxcsn5r7kffecp45iumner6vnbbmho
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/automake-1.16.3/linux-ubuntu18.04-x86_64-gcc-7.5.0-automake-1.16.3-6rqxcsn5r7kffecp45iumner6vnbbmho.spack
==> Extracting automake-1.16.3-6rqxcsn5r7kffecp45iumner6vnbbmho from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/automake-1.16.3-6rqxcsn5r7kffecp45iumner6vnbbmho
==> Installing numactl-2.0.14-3opot4q2nxdmogm7t5pt5wkhvapqex76
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/numactl-2.0.14/linux-ubuntu18.04-x86_64-gcc-7.5.0-numactl-2.0.14-3opot4q2nxdmogm7t5pt5wkhvapqex76.spack
==> Extracting numactl-2.0.14-3opot4q2nxdmogm7t5pt5wkhvapqex76 from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/numactl-2.0.14-3opot4q2nxdmogm7t5pt5wkhvapqex76
==> Installing openmpi-4.1.1-p5qicacmcy72pjljd4lfdy66kavxp3tv
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/openmpi-4.1.1/linux-ubuntu18.04-x86_64-gcc-7.5.0-openmpi-4.1.1-p5qicacmcy72pjljd4lfdy66kavxp3tv.spack
==> Extracting openmpi-4.1.1-p5qicacmcy72pjljd4lfdy66kavxp3tv from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/openmpi-4.1.1-p5qicacmcy72pjljd4lfdy66kavxp3tv
==> Installing hdf5-1.10.7-vt7sza3ycdsw62lk3f2dtnlvmeyihe3r
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/hdf5-1.10.7/linux-ubuntu18.04-x86_64-gcc-7.5.0-hdf5-1.10.7-vt7sza3ycdsw62lk3f2dtnlvmeyihe3r.spack
==> Extracting hdf5-1.10.7-vt7sza3ycdsw62lk3f2dtnlvmeyihe3r from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/hdf5-1.10.7-vt7sza3ycdsw62lk3f2dtnlvmeyihe3r
$ spack install zlib%clang
==> Installing zlib-1.2.11-atdrszvduszjw55p5g7fnjezpb5l6veu
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/clang-7.0.0/zlib-1.2.11/linux-ubuntu18.04-x86_64-clang-7.0.0-zlib-1.2.11-atdrszvduszjw55p5g7fnjezpb5l6veu.spack
==> Extracting zlib-1.2.11-atdrszvduszjw55p5g7fnjezpb5l6veu from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/clang-7.0.0/zlib-1.2.11-atdrszvduszjw55p5g7fnjezpb5l6veu

Now we are ready to use the Spack’s find and python subcommands to query the installed packages.

Scripting with spack find

So far, the output we’ve seen from spack find has been for human consumption. But you can take advantage of some advanced options of the command to generate machine-readable output suitable for piping to a script.

spack find --format

The main job of spack find is to show the user a bunch of concrete specs that correspond to installed packages. By default, we display them with some default attributes, like the @version suffix you’re used to seeing in the output.

The --format argument allows you to display the specs however you choose, using custom format strings. Format strings let you specify the names of particular parts of the specs you want displayed. Let’s see the first option in action.

Suppose you only want to display the name, version, and first ten (10) characters of the hash for every package installed in your Spack instance. You can generate that output with the following command:

$ spack find --format "{name} {version} {hash:10}"
autoconf 2.69 7hurwa7yme	diffutils 3.8 kg5jymjbqj	 libevent 2.1.12 xai6pycqx4    libxml2 2.9.12 2hw4ddh7db  openssh 8.7p1 ux36qlbxdg   readline 8.1 27u6g7pchc
automake 1.16.3 6rqxcsn5r7	gdbm 1.19 oftaepjeli		 libiconv 1.16 qi7dxj6rgd      m4 1.4.19 ybvezwzldr	  openssl 1.1.1l lygx3cqqbv  util-macros 1.19.3 h5cf2g4fze
berkeley-db 18.1.40 ue5lnfmm3y	hdf5 1.10.7 vt7sza3ycd		 libpciaccess 0.16 ryhmw2gqee  ncurses 6.2 d34lizgt45	  patchelf 0.13 2txxradgaz   xz 5.2.5 nplaapsuxr
bzip2 1.0.8 55rtzz4s6m		hwloc 2.6.0 gedgnpght7		 libsigsegv 2.13 g2vgcnev7a    numactl 2.0.14 3opot4q2nx  perl 5.34.0 672tzldkvy     zlib 1.2.11 atdrszvdus
cmake 3.21.4 anj6kcxdxz 	libedit 3.1-20210216 3lzuqwnyue  libtool 2.4.6 2kia6gf4yz      openmpi 4.1.1 p5qicacmcy   pkgconf 1.8.0 ucp6vz7fe6   zlib 1.2.11 3rlgy7ycxt

Note that name, version, and hash are attributes of Spack’s internal Spec object and enclosing them in braces ensures they are output according to your format string.

Using spack find --format allows you to retrieve just the information you need to do things like pipe the output to typical UNIX command-line tools like sort or uniq.

spack find --json

Alternatively, you can get a serialized version of Spec objects in the JSON format using the --json option. For example, you can get attributes for all installations of zlib by entering:

$ spack find --json zlib
[
  {
    "name": "zlib",
    "version": "1.2.11",
    "arch": {
      "platform": "linux",
      "platform_os": "ubuntu18.04",
      "target": "x86_64"
    },
    "compiler": {
      "name": "clang",
      "version": "7.0.0"
    },
    "namespace": "builtin",
    "parameters": {
      "optimize": true,
      "pic": true,
      "shared": true,
      "cflags": [],
      "cppflags": [],
      "cxxflags": [],
      "fflags": [],
      "ldflags": [],
      "ldlibs": []
    },
    "hash": "atdrszvduszjw55p5g7fnjezpb5l6veu",
    "full_hash": "o7eooyu7rbmvdj6csiwjcbgyzrtxf5bf"
  },
  {
    "name": "zlib",
    "version": "1.2.11",
    "arch": {
      "platform": "linux",
      "platform_os": "ubuntu18.04",
      "target": "x86_64"
    },
    "compiler": {
      "name": "gcc",
      "version": "7.5.0"
    },
    "namespace": "builtin",
    "parameters": {
      "optimize": true,
      "pic": true,
      "shared": true,
      "cflags": [],
      "cppflags": [],
      "cxxflags": [],
      "fflags": [],
      "ldflags": [],
      "ldlibs": []
    },
    "hash": "3rlgy7ycxtoho44una6o3itgfjltkmpd",
    "full_hash": "svvrv2zzgiqm6iponmexjj6i6bu2sld6"
  }

The spack find --json command gives you everything we know about the specs in a structured format. You can pipe its output to JSON filtering tools like jq to extract just the parts you want.

Check out the basic usage docs for more examples.

Introducing the spack python command

What if we need to perform more advanced queries?

Spack provides the spack python command to launch a python interpreter with Spack’s python modules available to import. It uses the underlying python for the rest of its commands. So you can write scripts to:

  • run Spack commands;
  • explore abstract and concretized specs; and
  • directly access other internal components of Spack.

Let’s launch a Spack-aware python interpreter by entering:

$ spack python

Spack version 0.17.0
Python 3.6.9, Linux x86_64
>>> exit()

Since we are in a python interpreter, use exit() to end the session and return to the terminal.

Accessing the Spec object

Now let’s take a look at the internal representation of the Spack Spec. As you already know, specs can be either abstract or concrete. The specs you’ve seen in package.py files (e.g., in the install() method) have been concrete, or fully specified. The specs you’ve typed on the command line have been abstract. Understanding the differences between the two types is key to using Spack’s internal API.

Let’s open another python interpreter with spack python, instantiate the zlib spec, and check a few properties of an abstract spec:

  >>> from spack.spec import Spec
  >>> s = Spec('zlib target=ivybridge')
  >>> s.concrete
  False
  >>> s.version
  Traceback (most recent call last):
    File "<console>", line 1, in <module>
    File "/home/spack/spack/lib/spack/spack/spec.py", line 3166, in version
      raise SpecError("Spec version is not concrete: " + str(self))
  SpecError: Spec version is not concrete: zlib arch=linux-None-ivybridge
  >>> s.versions
  [:]
  >>> str(s.architecture)
  linux-None-ivybridge

Notice that there are Spec properties and methods that are not accessible to abstract specs; specifically:

  • an exception – SpecError – is raised if we try to access its version;
  • there are no associated versions; and
  • the spec’s operating system is None.

Now, without exiting the interpreter, let’s concretize the spec and try again:

  >>> s.concretize()
  >>> s.concrete
  True
  >>> s.version
  Version('1.2.11')
  >>> s.versions
  [Version('1.2.11')]
  >>> str(s.architecture)
  linux-ubuntu18.04-ivybridge

Notice that the concretized spec now:

  • has a version;
  • has a single entry in its versions list; and
  • the operating system is now ubuntu18.04.

It is not necessary to store the intermediate abstract spec – you can use the .concretized() method as shorthand:

  >>> t = Spec('zlib target=ivybridge').concretized()
  >>> s == t
  True

Querying the Spack database

Even more powerful queries are available when we look at the information stored in the Spack database. The Database object in Spack is in the spack.store.db variable. We’ll interact with it mainly through the query() method. Let’s see the documentation available for query() using python’s built-in help() function:

  >>> import spack.store
  >>> help(spack.store.db.query)
  Help on method query in module spack.database:

  query(*args, **kwargs) method of spack.database.Database instance
      Query the Spack database including all upstream databases.

      Args:
          query_spec: queries iterate through specs in the database and
              return those that satisfy the supplied ``query_spec``. If
              query_spec is `any`, This will match all specs in the
              database.  If it is a spec, we'll evaluate
              ``spec.satisfies(query_spec)``

          known (bool or any, optional): Specs that are "known" are those
              for which Spack can locate a ``package.py`` file -- i.e.,
              Spack "knows" how to install them.  Specs that are unknown may
              represent packages that existed in a previous version of
              Spack, but have since either changed their name or
              been removed

          installed (bool or any, or InstallStatus or iterable of
              InstallStatus, optional): if ``True``, includes only installed
              specs in the search; if ``False`` only missing specs, and if
              ``any``, all specs in database. If an InstallStatus or iterable
              of InstallStatus, returns specs whose install status
              (installed, deprecated, or missing) matches (one of) the
              InstallStatus. (default: True)

          explicit (bool or any, optional): A spec that was installed
              following a specific user request is marked as explicit. If
              instead it was pulled-in as a dependency of a user requested
              spec it's considered implicit.

          start_date (datetime, optional): filters the query discarding
              specs that have been installed before ``start_date``.

          end_date (datetime, optional): filters the query discarding
              specs that have been installed after ``end_date``.

          hashes (container): list or set of hashes that we can use to
              restrict the search

      Returns:
          list of specs that match the query
  (END)

We will primarily make use of the query_spec argument.

Recall that queries using the spack find command are limited to queries of attributes with matching values, not values they do not have. In other words, we cannot use the spack find command for all packages that do not satisfy a certain criterion.

We can use the python interface to write these types of queries. For example, let’s find all packages that were compiled with gcc but do not depend on mpich. We can do this by using custom python code and Spack database queries. We will use the spack.cmd.display_specs for output to achieve the same printing functionality as the spack find command:

  >>> gcc_query_spec = Spec('%gcc')
  >>> gcc_specs = spack.store.db.query(gcc_query_spec)
  >>> result = filter(lambda spec: not spec.satisfies('^mpich'), gcc_specs)
  >>> import spack.cmd
  >>> spack.cmd.display_specs(result)
  -- linux-ubuntu18.04-x86_64 / gcc@7.5.0 -------------------------
  autoconf@2.69    libiconv@1.16        m4@1.4.18       perl@5.30.3         zlib@1.2.11
  automake@1.16.2  libpciaccess@0.13.5  ncurses@6.2     pkgconf@1.7.3
  gdbm@1.18.1      libsigsegv@2.12      numactl@2.0.12  readline@8.0
  hdf5@1.10.6      libtool@2.4.6        openmpi@3.1.6   util-macros@1.19.1
  hwloc@1.11.11    libxml2@2.9.10       patchelf@0.10   xz@5.2.5

Now we have a powerful query not available through spack find.

Let’s exit the interpreter to take us back to the command line:

>>> exit()

before generalizing the functionality for re-use.

Using scripts

Now let’s parameterize our script to accept arguments on the command line. With a few generalizations to use the include and exclude specs as arguments, we can create a powerful, general-purpose query script.

Open a file called find_exclude.py in your preferred editor and add the following code:

from spack.spec import Spec
import spack.store
import spack.cmd
import sys

include_spec = Spec(sys.argv[1])
exclude_spec = Spec(sys.argv[2])

all_included = spack.store.db.query(include_spec)
result = filter(lambda spec: not spec.satisfies(exclude_spec), all_included)

spack.cmd.display_specs(result)

Notice we added importing and using the system package (sys) to access the first and second command line arguments.

Now we can run our new script by entering the following:

$ spack python find_exclude.py %gcc ^mpich
-- linux-ubuntu18.04-x86_64 / gcc@7.5.0 -------------------------
autoconf@2.69	     bzip2@1.0.8    gdbm@1.19	 libedit@3.1-20210216  libpciaccess@0.16  libxml2@2.9.12  numactl@2.0.14  openssl@1.1.1l  pkgconf@1.8.0       xz@5.2.5
automake@1.16.3      cmake@3.21.4   hdf5@1.10.7  libevent@2.1.12       libsigsegv@2.13	  m4@1.4.19	  openmpi@4.1.1   patchelf@0.13   readline@8.1	      zlib@1.2.11
berkeley-db@18.1.40  diffutils@3.8  hwloc@2.6.0  libiconv@1.16	       libtool@2.4.6	  ncurses@6.2	  openssh@8.7p1   perl@5.34.0	  util-macros@1.19.3

This is great for us, as long as we remember to use Spack’s python command to run it.

Using the spack-python executable

What if we want to make our script available for others to use without the hassle of having to remember to use spack python?

We can take advantage of the shebang line typically added as the first line of python executable files. But there is a catch, as we will soon see.

Open the find_exclude.py script we created above in your preferred editor and add the shebang line with spack python as the arguments to env:

#!/usr/bin/env spack python
from spack.spec import Spec
import spack.store
import spack.cmd
import sys

include_spec = Spec(sys.argv[1])
exclude_spec = Spec(sys.argv[2])

all_included = spack.store.db.query(include_spec)
result = filter(lambda spec: not spec.satisfies(exclude_spec), all_included)

spack.cmd.display_specs(result)

Then exit our editor and add execute permissions to the script before running it as follows:

$ chmod u+x find_exclude.py
$ ./find_exclude.py %gcc ^mpich
/usr/bin/env: 'spack python': No such file or directory

If you are lucky, it worked on your system, but there is no guarantee. Some systems only support a single argument on the shebang line (see here). spack-python, which is a wrapper script for spack python, solves this issue.

Bring up the file in your editor again and change the env argument to spack-python as follows:

#!/usr/bin/env spack-python
from spack.spec import Spec
import spack.store
import spack.cmd
import sys

include_spec = Spec(sys.argv[1])
exclude_spec = Spec(sys.argv[2])

all_included = spack.store.db.query(include_spec)
result = filter(lambda spec: not spec.satisfies(exclude_spec), all_included)

spack.cmd.display_specs(result)

Exit your editor and let’s run the script again:

$ ./find_exclude.py %gcc ^mpich
-- linux-ubuntu18.04-x86_64 / gcc@7.5.0 -------------------------
autoconf@2.69	     bzip2@1.0.8    gdbm@1.19	 libedit@3.1-20210216  libpciaccess@0.16  libxml2@2.9.12  numactl@2.0.14  openssl@1.1.1l  pkgconf@1.8.0       xz@5.2.5
automake@1.16.3      cmake@3.21.4   hdf5@1.10.7  libevent@2.1.12       libsigsegv@2.13	  m4@1.4.19	  openmpi@4.1.1   patchelf@0.13   readline@8.1	      zlib@1.2.11
berkeley-db@18.1.40  diffutils@3.8  hwloc@2.6.0  libiconv@1.16	       libtool@2.4.6	  ncurses@6.2	  openssh@8.7p1   perl@5.34.0	  util-macros@1.19.3

Congratulations! It will now work on any system with Spack installed.

You now have the basic tools to create your own custom Spack queries and prototype ideas. We hope one day you’ll contribute them back to Spack.