Compare commits

..

475 Commits

Author SHA1 Message Date
Gregory Becker
1b4ff30665 clean up post rebase 2023-06-14 11:18:41 -07:00
Gregory Becker
c10797718a fixup after rebase 2023-06-13 12:11:27 -07:00
becker33
81ea29b007 [@spackbot] updating style on behalf of becker33 2023-06-13 11:54:00 -07:00
Gregory Becker
d8666a7fdf !fixup 511dd5a968c23f3f0c660b0cc5216415e60c6018 2023-06-13 11:54:00 -07:00
Gregory Becker
7c41bba6f8 error causation in separate file loaded for debug only 2023-06-13 11:53:58 -07:00
Gregory Becker
20e9fe3785 solver: nodes directly caused by dependency conditions 2023-06-13 11:51:01 -07:00
Gregory Becker
401218b4f1 solver: reorder code so it's easier to instrument for debugging 2023-06-13 11:50:57 -07:00
Gregory Becker
adfc1c0896 error messages: add causation for conflicting variants error 2023-06-13 11:49:45 -07:00
Gregory Becker
f4402c1cde error messages: print cause tree as part of error 2023-06-13 11:48:02 -07:00
Gregory Becker
c1d6d93388 error-chaining: expand to additional error messages 2023-06-13 11:44:54 -07:00
Gregory Becker
e9012c7781 solver: first prototype of chained error messages for one message type 2023-06-13 11:42:05 -07:00
Gregory Becker
59acfe4f0b solver: treat literals as conditions 2023-06-13 11:28:47 -07:00
Gregory Becker
004ff9d4e2 error messages: compute connections between conditions 2023-06-13 11:28:47 -07:00
Gregory Becker
9d20be5fe5 solver: remove indirection for dependency conditions 2023-06-13 11:28:47 -07:00
Gregory Becker
edc07dab27 solver: remove indirection for external conditions 2023-06-13 11:28:47 -07:00
Gregory Becker
acde8ef104 solver: remove indirection for provider conditions 2023-06-13 11:28:47 -07:00
Massimiliano Culpo
ed76966a3a gnupg: add v2.4.2 (#38059)
* gnupg: add v2.4.2

* [@spackbot] updating style on behalf of alalazo

---------

Co-authored-by: alalazo <alalazo@users.noreply.github.com>
2023-06-02 09:28:54 -07:00
willdunklin
2015a51d1a sz: add versions v2.1.12.5 and v2.1.12.4 (#38060) 2023-06-02 09:28:05 -05:00
Manuela Kuhn
34b8fe827e py-flask: add 2.3.2, py-blinker: add 1.6.2, py-werkzeug: add 2.3.4 (#38025) 2023-06-02 05:57:22 -04:00
Manuela Kuhn
6f1ed9b2e4 py-exceptiongroup: add 1.1.1 (#38018) 2023-06-02 05:47:49 -04:00
M. Eric Irrgang
dd00f50943 Add py-gmxapi version 0.4.2 (#38053) 2023-06-02 03:07:34 -04:00
Sam Grayson
f0ec625321 singularityce: add v3.11.3 (#38055) 2023-06-02 08:04:39 +02:00
Manuela Kuhn
d406c371a8 py-formulaic: add 0.6.1 (#38035) 2023-06-01 19:23:15 -04:00
Sean Koyama
42d374a34d double-batched-fft-library: patch to add search paths to findOpenCL.cmake (#36355)
* double-batched-fft-library: PATCH: add search paths to find libOpenCL

* Apply patch up to version 0.3.6
2023-06-01 16:17:04 -07:00
Sean Koyama
d90e4fcc3d lua-luafilesystem: update source URL and improve rockspec detection (#36692)
* lua-luafilesystem: updated sources to new URL. Changed versioning to dot-separated versions.

* lua-luafilesystem: override install phase to find correct rockspec

* lua-luafilesystem: improved rockspec detection

* lua-luafilesystem: added lua version constraint for older versions
2023-06-01 16:15:42 -07:00
Manuela Kuhn
a44fde9dc9 py-docutils: add 0.20.1 (#38001) 2023-06-01 18:18:29 -04:00
Manuela Kuhn
9ac8841dab py-fonttools: add 4.39.4 (#38027) 2023-06-01 18:13:20 -04:00
Manuela Kuhn
a1f87638ec py-future: add 0.18.3 (#38041)
* py-future: add 0.18.3

* Update var/spack/repos/builtin/packages/py-future/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-06-01 17:48:13 -04:00
Manuela Kuhn
3b55e0a65d py-executing: add 1.2.0 (#38019) 2023-06-01 17:38:09 -04:00
Massimiliano Culpo
42667fe7fa Memoize a few hot functions during module file generation (#37739) 2023-06-01 13:36:42 -07:00
Ted Stern
cd27611d2f Adding libpsm3 package (#37444)
* Adding libpsm3 package
* Make changes suggested by flake8
* Make one more flake8-suggested change, blank line after 'import os'
* Change to standard header to pass flake8 tests
* Update doc string, remove unnecessary comments
* Reviewer-recommende changes
* Alphabetize variants
* Use helper functions
* Change quotes to pass spack style check
2023-06-01 13:01:43 -07:00
Massimiliano Culpo
b111d2172e py-archspec: add v0.2.1 (#38014) 2023-06-01 14:58:45 -05:00
Tobias Ribizel
055263fa3c Fix OpenCV detection on Ubuntu (#35336)
* fix OpenCV detection on Ubuntu

* Update package.py

* Simplify version detection

* remove superfluous `return`
2023-06-01 14:38:17 -05:00
Manuela Kuhn
f34f207bdc py-datalad-neuroimaging: add 0.3.3 (#38017) 2023-06-01 14:31:54 -05:00
snehring
0c9f0fd40d openssh: depend on krb5+shared when +gssapi (#38034) 2023-06-01 13:17:44 -04:00
pauleonix
24d5b1e645 asio: Add stable versions up to 1.28.0 (#38007)
Co-authored-by: Mikael Simberg <mikael.simberg@iki.fi>

- Add pkgconfig dependency from 1.23.0 onward.
- Add conflict of old versions with new gcc due to missing includes.
- Deprecate uneven minor versions because they are not regarded as stable.
- Add maintainer
2023-06-01 11:09:27 +02:00
Mikael Simberg
616f7bcaef pika: add 0.16.0 and pika-algorithms 0.1.3 (#38021)
* pika: add 0.16.0

* pika-algorithms: add 0.1.3

---------

Co-authored-by: Alberto Invernizzi <9337627+albestro@users.noreply.github.com>
2023-06-01 04:18:26 -04:00
Greg Becker
dace0316a2 Spec.format: print false attributes if requested (#37932) 2023-06-01 09:08:45 +02:00
Greg Sjaardema
3bb86418b8 seacas: add 2023-05 release, update fmt dependency (#38008)
The fmt dependency for the previous release was incorrect as does not work with latest lib::fmt.  Fixed that specification
2023-06-01 02:48:50 -04:00
Veselin Dobrev
6f6489a2c7 xSDK examples v0.4.0 (#37295)
* [xsdk-examples] Initial commit for v0.4.0

* [xsdk-examples] v0.4.0 depends on xsdk@0.8.0

* add in missing xsdk dependencies

* [xsdk-examples] remove repeated 'depends_on' directive

* [xsdk-examples] simplify and extend a bit the package

[mfem] process more optional dependencies of HiOp

[strumpack, superlu-dist] add a workaround for an issue on Mac

* [mfem] fix the handling of the hiop dependency

* [@spackbot] updating style on behalf of v-dobrev

* [xsdk-examples] enable 'heffte' and 'tasmanian' if enabled in 'xsdk'

* [xsdk-examples] Add PUMI dependency

* [xsdk-examples] Add preCICE dependency

* [xsdk-examples] add +rocm

* heffte: add in a backport fix for building xsdk-examples with cuda

* [xsdk] Remove the explicit requirement for deal.II to be built +hdf5

* ENABLE_ROCM -> ENABLE_HIP

* [hiop] Workaround for CMake not finding Cray's BLAS (libsci)

[xsdk-examples] Set CUDA/HIP architectures; sync cuda/rocm variants with xsdk

* [@spackbot] updating style on behalf of v-dobrev

* [exago] Workaround for CMake not finding Cray's LAPACK/BLAS, libsci

[mfem] Tweaks for running tests under Flux and PBS

* [slate] Pass CUDA/HIP architectures to CMake

* [heffte] For newer CMake versions, set CMAKE_CUDA_ARCHITECTURES

* [hypre] Patch v2.26.0 to fix sequential compilation in 'src/seq_mv'

* [xsdk-examples] Some tweaks in dependencies and compilers used

* [xsdk] Make the 'trilinos' variant sticky

[xsdk-examples] Tweak dependencies

* [slate] Fix copy-paste error

* [xsdk-examples] Workaround for CMakePackage not having the legacy
   property 'build_directory'

* [xsdk-examples] Replace the testing branch used temporarily for v0.4.0 with
                the official release

---------

Co-authored-by: Satish Balay <balay@mcs.anl.gov>
2023-05-31 21:57:53 -04:00
Brian Van Essen
543b697df1 CachedCMakePackage: add CUDA/HIP options and improve independent builds (#37592)
* Add CMake options for building with CUDA/HIP support to
  CachedCMakePackages (intended to reduce duplication across packages
  building with +hip/+cuda and using CachedCMakePackage)
* Define generic variables like CMAKE_PREFIX_PATH for
  CachedCMakePackages (so that a user may invoke "cmake" themselves
  without needing to setthem on the command line).
* Make `lbann` a CachedCMakePackage.

Co-authored-by: Chris White <white238@llnl.gov>
2023-05-31 17:35:11 -07:00
QuellynSnead
042dc2e1d8 libtheora: enforce math library (libm.so) linkage (#37891) 2023-05-31 13:45:11 -07:00
Mosè Giordano
f745e49d9a julia: add patch to fix printing of BigFloat with MPFR v4.2 (#37992) 2023-05-31 15:32:12 -04:00
Michael Kuhn
eda21cdfba gcc: add 11.4.0 (#37988) 2023-05-31 09:15:45 -04:00
Adam J. Stewart
bc8b026072 py-pandas: add v2.0.2 (#38005) 2023-05-30 22:48:51 -04:00
Tiziano Müller
0f84782fcc Bugfix: cray manifest parsing regression (#37909)
fa7719a changed syntax for specifying exact versions, which are
required for some compiler specs (including those read as part
of parsing a Cray manifest). This fixes that and also makes a
couple other improvements to manifest parsing.

* Instantiate compiler specs with exact versions (fixes #37893)
* fix slingshot network detection (CPE 22.10+ has libcxi.so
  in /usr/lib64)
* "spack external find": add arg to ignore default dir for cray
  manifests
2023-05-30 18:03:44 -07:00
AMD Toolchain Support
43b86ce282 HPL: amdalloc with AOCC 4.0 (#37757)
* adding amdalloc when using aocc 4


* adding and libm for aocc3.2
2023-05-30 16:40:41 -07:00
AMD Toolchain Support
d30698d9a8 cp2k fixes for aocc (#37758) 2023-05-30 16:33:00 -07:00
Massimiliano Culpo
8e9efa86c8 Simplify implementation of "get_compiler_config" (#37989) 2023-05-30 15:11:33 -07:00
Jack Morrison
84faf5a6cf intel-mpi-benchmarks: Add MPI implementation check variant (#37363)
* Add MPI implementation check variant to Intel MPI Benchmarks

* [@spackbot] updating style on behalf of jack-morrison
2023-05-30 16:37:58 -05:00
Eric Berquist
9428749a3c Update SST packages to 13.0.0 (#37467)
* add sst-{core,elements,macro} v13.0.0

* Add newest DUMPI versions and remove unavailable ones

* update maintainer lists

* sst-core: tracking and profiling flags

* sst-elements with Pin requires the Pin location

* sst-core: Zoltan integration was removed in version 12

* spack style fixes

* sst-core: ensure Python is in the sst{sim,info}.x rpaths

* sst-macro: update homepage and maintainers

* spack style --fix
2023-05-30 16:35:33 -05:00
Michael Kuhn
efdac68c28 julia: fix build for @1.8.4:1.8.5 (#37990)
julia@1.8.4:1.8.5 fails to build because it does not find libstdc++ (see https://github.com/JuliaLang/julia/issues/47987).
2023-05-30 13:49:15 -07:00
Carlos Bederián
5398c31e82 ucx: add 1.14.1 (#37991) 2023-05-30 13:46:39 -07:00
Thomas Madlener
188168c476 podio: Add 0.16.5 tag (#37994) 2023-05-30 13:39:15 -07:00
Michael Kuhn
4af84ac208 gobject-introspection: add 1.76.1 (#37995) 2023-05-30 13:37:53 -07:00
Manuela Kuhn
deb8b51098 py-dunamai: add 1.17.0 (#38003) 2023-05-30 15:34:15 -04:00
Manuela Kuhn
0d582b2ea9 py-duecredit: add 0.9.2 (#38002) 2023-05-30 15:33:54 -04:00
Manuela Kuhn
f88b01c34b py-datalad-container: add 1.2.0 (#38000) 2023-05-30 15:28:34 -04:00
Manuela Kuhn
0533c6a1b8 py-datalad-metalad: add 0-4-17 and new dep py-datalad-deprecated (#37993)
* py-datalad-metalad: add 0-4-17 and new dep py-datalad-deprecated

* Fix style
2023-05-30 15:18:15 -04:00
Manuela Kuhn
f73d5c2b0e py-cryptography: add 40.0.2 (#37925)
* py-cryptography: add 40.0.2

* Add pkgconfig dependency
2023-05-30 10:26:17 -05:00
Tamara Dahlgren
567d0ee455 tests/hdf5: convert to new stand-alone test process (#35732) 2023-05-29 16:56:17 +02:00
Tamara Dahlgren
577df6f498 sqlite: convert to new stand-alone test process (#37722) 2023-05-29 07:59:23 -04:00
Harmen Stoppels
8790efbcfe Remove patchelf self-relocation (#33834) 2023-05-29 13:14:24 +02:00
Tamara Dahlgren
212b1edb6b tests/biobambam2: convert to new stand-alone test process (#35696) 2023-05-29 12:54:38 +02:00
snehring
d85a27f317 sentieon-genomics: replacing square brackets in help (#37622) 2023-05-29 12:52:36 +02:00
Chris White
5622afbfd1 amgx: add v2.2.0 and v2.3.0 (#37567) 2023-05-29 12:42:36 +02:00
Carlos Bederián
f345038317 nwchem: fix non-fftw fftw-api providers (#37442) 2023-05-29 12:41:41 +02:00
Michael Kuhn
e43d4cfee0 glib: add 2.76.3 and 2.76.2, update build systems (#37226)
This also converts the package to the new way of handling multiple build
systems.

Co-authored-by: michaelkuhn <michaelkuhn@users.noreply.github.com>
2023-05-29 06:38:57 -04:00
Vanessasaurus
7070658e2a Automated deployment to update package flux-core 2023-05-15 (#37684)
Co-authored-by: github-actions <github-actions@users.noreply.github.com>
2023-05-29 12:35:22 +02:00
dependabot[bot]
fc4b032fb4 build(deps): bump codecov/codecov-action from 3.1.3 to 3.1.4 (#37688)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](894ff025c7...eaaf4bedf3)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-29 12:34:34 +02:00
Vanessasaurus
8c97d8ad3f add flux-security variant to flux-core (#37689)
This will build flux-security separately to have a flux-imp
that can be defined in a flux broker.toml. Note that the user
that wants a multi-user setup is recommended to create a view,
and then a system/broker.toml in flux config directory that
points to it.

Signed-off-by: vsoch <vsoch@users.noreply.github.com>
Co-authored-by: vsoch <vsoch@users.noreply.github.com>
2023-05-29 12:34:07 +02:00
Alberto Invernizzi
26107fe6b2 highfive: add newer versions + add git repo (#37635)
* add versions
* add develop pointing to git@master
2023-05-29 06:09:02 -04:00
Tamara Dahlgren
9278c0df21 binutils: convert to new stand-alone test process (#37690) 2023-05-29 11:59:09 +02:00
Tamara Dahlgren
37e95713f4 libsigsegv: convert to new stand-alone test process (#37691) 2023-05-29 11:58:39 +02:00
SXS Bot
3ae8a3a517 spectre: add v2023.05.16 (#37716)
Co-authored-by: sxs-bot <sxs-bot@users.noreply.github.com>
2023-05-29 11:56:21 +02:00
Tamara Dahlgren
031af84e90 m4: convert to new stand-alone test process (#37723) 2023-05-29 11:49:28 +02:00
Annop Wongwathanarat
7d4b65491d armpl-gcc: add version 23.04.1 (#37907) 2023-05-29 05:49:19 -04:00
Harmen Stoppels
3038d1e7cd Use @= in some packages (#37737)
Change the pattern @x.y:x.y.0 -> @=x.y

Co-authored-by: haampie <haampie@users.noreply.github.com>
2023-05-29 11:47:00 +02:00
Lehman Garrison
b2e6ef97ce hdfview: add 3.1.4, 3.2.0, 3.3.0. Update dependencies. (#37745) 2023-05-29 11:41:44 +02:00
Tamara Dahlgren
e55236ce5b tests/arborx: convert to new stand-alone test process (#37778)
Co-authored-by: Andrey Prokopenko <andrey.prok@gmail.com>
2023-05-29 11:33:07 +02:00
Alec Scott
68dfd6ba6e hbase: add v2.5.3 (#37518)
Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>
2023-05-29 11:29:11 +02:00
Jim Galarowicz
38d2459f94 survey: add v1.0.8 (#37385) 2023-05-29 11:26:56 +02:00
Nicolas Cornu
e309f367af catch2: new versions (#37742) 2023-05-29 11:26:06 +02:00
Harmen Stoppels
3b59c95323 fix InternalConcretizerError msg (#37791) 2023-05-29 11:24:43 +02:00
Howard Pritchard
fddaeadff8 OPENMPI: disable use of sphinx (#37717)
Sphinx is used to build Open MPI manpages, etc. as part of the make dist
process to create release tarballs.  There should be no need/use to do
this within Spack.  Also some sites have older Sphinx installs which
aren't compatible with the needs of the Open MPI documentation.
For example, attempts to install openmpi@main fail at NERSC owing to
such a situation.

Since Spack normally is used to build from release tarballs, in which
the docs have already been installed, this should present no issues.

This configuration option will be ignored for older than 5.0.0 Open MPI releases.

Signed-off-by: Howard Pritchard <howardp@lanl.gov>
2023-05-29 11:23:42 +02:00
Joel Falcou
c85eaf9dc5 Add package for KUMI tuple library (#37795) 2023-05-29 11:23:06 +02:00
Brian Vanderwende
ddec7f8aec bbcp: fix cloning "master" version (#37802) 2023-05-29 11:21:48 +02:00
AMD Toolchain Support
f057d7154b NAMD: add AVXTILES support (#37040) 2023-05-29 11:10:09 +02:00
Tamara Dahlgren
a102950d67 berkeley-db: convert to new stand-alone test process (#35702) 2023-05-29 10:56:42 +02:00
Howard Pritchard
783be9b350 dealii - add platform-introspection variant (#37833)
This option is needed for DFT FE - or more accurately the check needs to
be checked off for a number of platforms or else the code doesn't work.

Signed-off-by: Howard Pritchard <howardp@lanl.gov>
2023-05-29 10:56:03 +02:00
Juan Miguel Carceller
27c8135207 xrootd: add patch for when libraries are installed in lib64 (#37858)
Co-authored-by: jmcarcell <jmcarcell@users.noreply.github.com>
2023-05-29 10:36:57 +02:00
Tamara Dahlgren
77ce4701b9 Bugfix/tests: add slash to test log message (#37874) 2023-05-29 10:36:36 +02:00
Juan Miguel Carceller
73ad3f729e dd4hep: add patch to fix missing hits when using LCIO (#37854)
Co-authored-by: jmcarcell <jmcarcell@users.noreply.github.com>
2023-05-29 10:35:14 +02:00
Jim Edwards
1e7a64ad85 parallelio: add v2.6.0 release and ncint variant (#37805) 2023-05-29 10:19:15 +02:00
Tamara Dahlgren
3a5864bcdb tests/sip: convert to new stand-alone test process (#35693) 2023-05-29 10:16:35 +02:00
Alec Scott
7e13a7dccb cbc: add v2.10.9 (#37974) 2023-05-29 04:04:28 -04:00
Alec Scott
e3249fa155 bedops: add v2.4.41 (#37972) 2023-05-29 04:04:06 -04:00
Thomas-Ulrich
0c20760576 pumi: fix simmodsuite base variant, and mpi lib name (#37401) 2023-05-29 09:59:32 +02:00
Alec Scott
7ee7995493 cracklib: add v2.9.9 (#37976) 2023-05-29 03:59:13 -04:00
Alec Scott
ba1fac1c31 cpio: add v2.14 (#37975) 2023-05-29 03:58:53 -04:00
Adam J. Stewart
b05f0ecb6f py-segmentation-models-pytorch: add v0.3.3 (#37970) 2023-05-29 09:48:32 +02:00
Alec Scott
d5c66b75c3 cyrus-sasl: add v2.1.28 (#37978) 2023-05-29 09:31:54 +02:00
Alec Scott
98303d6956 double-conversion: add v3.3.0 (#37979) 2023-05-29 09:31:38 +02:00
Alec Scott
4622d638a6 elfio: add v3.11 (#37980) 2023-05-29 09:31:23 +02:00
Alec Scott
02023265fc erfa: add v2.0.0 (#37981) 2023-05-29 09:31:09 +02:00
Alec Scott
8a075998f8 erlang: add v26.0 (#37982) 2023-05-29 09:30:28 +02:00
Alec Scott
f2f48b1872 fasttransforms: add v0.6.2 (#37983) 2023-05-29 09:30:10 +02:00
Alec Scott
168d63c447 glog: add v0.6.0 (#37985) 2023-05-29 09:29:34 +02:00
Alec Scott
c25d4cbc1d gradle: add v8.1.1 (#37986) 2023-05-29 09:29:07 +02:00
snehring
ccb07538f7 Beast2: add v2.7.4, add javafx (#37419) 2023-05-29 09:28:32 +02:00
Alec Scott
1356b13b2f form: add v4.3.1 (#37984) 2023-05-29 09:24:34 +02:00
Tamara Dahlgren
935f862863 tests/flibcpp: convert to new stand-alone test process (#37782) 2023-05-28 10:47:23 +02:00
Tamara Dahlgren
9f6d9df302 patchelf: convert to new stand-alone test process (#37831) 2023-05-28 10:46:23 +02:00
Tamara Dahlgren
65d33c02a1 gasnet: convert to new stand-alone test process (#35727) 2023-05-28 10:45:11 +02:00
Tamara Dahlgren
40073e7b21 hdf: convert to new stand-alone test process (#37843) 2023-05-28 10:44:42 +02:00
Tamara Dahlgren
752e02e2f2 tests/upcxx: convert to new stand-alone test process (#37832)
Co-authored-by: Dan Bonachea <dobonachea@lbl.gov>
2023-05-28 10:44:04 +02:00
Vanessasaurus
d717b3a33f Automated deployment to update package flux-core 2023-05-04 (#37421)
Co-authored-by: github-actions <github-actions@users.noreply.github.com>
2023-05-28 10:42:44 +02:00
Bruno Turcksin
9817f24c9a kokkos-nvcc-wrapper: Remove unnecessary dependencies (#37794) 2023-05-28 10:19:30 +02:00
Bruno Turcksin
1f7c4b0557 Kokkos: remove unused variants (#37800) 2023-05-28 10:18:53 +02:00
Xavier Delaruelle
6c42d2b7f7 modules: improve default naming scheme (#37808)
Change default naming scheme for tcl modules for a more user-friendly
experience. 

Change from flat projection to "per software name" projection.

Flat naming scheme restrains module selection capabilities. The
`{name}/{version}...` scheme make possible to use user-friendly
mechanisms:

* implicit defaults (`module load git`)
* extended default (`module load git/2`)
* advanced version specifiers (`module load git@2:`)
2023-05-28 10:06:30 +02:00
Tamara Dahlgren
8df036a5a5 tests/cmake: convert to new stand-alone test process (#37724) 2023-05-28 09:59:21 +02:00
dependabot[bot]
582ebee74c build(deps): bump actions/setup-python from 4.6.0 to 4.6.1 (#37894)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.6.0 to 4.6.1.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](57ded4d7d5...bd6b4b6205)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-28 09:58:14 +02:00
Annop Wongwathanarat
1017b9ddde acfl: add version 23.04.1 and fix checksums for 22.1 (#37908)
Checksums for 22.1 need updates due to an IT incident at developer.arm.com. The package tarballs needed to be recreated.
2023-05-28 09:57:31 +02:00
Thomas Madlener
80ae73119d whizard: Fix parallel build race condition (#37890) 2023-05-28 09:55:52 +02:00
Tamara Dahlgren
1d88f690a4 tests/darshan-runtime: convert to new stand-alone test process (#37838) 2023-05-28 09:46:31 +02:00
Filippo Spiga
fbb271d804 Adding NVIDIA HPC SDK 23.5 (#37913) 2023-05-28 09:45:08 +02:00
Hao Lyu
d6aac873b7 copy namelist and xml to ./bin (#37933) 2023-05-28 09:43:27 +02:00
Tamara Dahlgren
ab3ffd9361 archer: convert to new stand-alone test process (#35697) 2023-05-28 09:41:38 +02:00
Tamara Dahlgren
3b9454a5cc tests/bolt: convert to new stand-alone test process (#35695)
* bolt: convert to new stand-alone test process
* Remove redundant test_requires_compiler (so above directives)
2023-05-27 18:46:11 -07:00
Tamara Dahlgren
c8eb0f9361 tests/amrex: convert to new stand-alone test process (#35698)
* amrex: convert to new stand-alone test process
* smoke->stand-alone
2023-05-27 18:44:06 -07:00
George Young
fb0f14eb06 py-macs2: add 2.2.8, updated dependencies (#37944)
* py-macs2: add 2.2.8, updated dependencies

* Update package.py

---------

Co-authored-by: LMS Bioinformatics <bioinformatics@lms.mrc.ac.uk>
2023-05-27 14:29:12 -05:00
George Young
e489ee4e2e py-cutadapt: add 4.4, 4.3, 4.2 versions (#37929)
* py-cutadapt: add 4.4, 4.3, 4.2 versions

* Update var/spack/repos/builtin/packages/py-cutadapt/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Update var/spack/repos/builtin/packages/py-cutadapt/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Update package.py

---------

Co-authored-by: LMS Bioinformatics <bioinformatics@lms.mrc.ac.uk>
Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-27 14:27:43 -05:00
Alex Richert
fcd49f2f08 Add shared and pic variants to libtiff (#37965)
* Add static-only option for libtiff

* update libtiff to add pic variant

* fix libtiff pic setting
2023-05-27 11:24:27 -05:00
Alex Richert
b3268c2703 freetype: add pic and shared variants (#37898) 2023-05-27 01:05:10 +02:00
George Young
d1bfcfafe3 py-multiqc: add 1.14, bump dependencies (#37946)
Co-authored-by: LMS Bioinformatics <bioinformatics@lms.mrc.ac.uk>
2023-05-26 17:55:03 -05:00
Manuela Kuhn
490c9f5e16 py-datalad-metadata-model: add 0.3.10 (#37937) 2023-05-26 17:28:36 -05:00
Manuela Kuhn
85628d1474 py-debugpy: add 1.6.7 (#37941) 2023-05-26 17:27:50 -05:00
Manuela Kuhn
720c34d18d py-distro: add 1.8.0 (#37942) 2023-05-26 17:27:06 -05:00
mschouler
cd175377ca Update melissa build (#37609)
* Remove deprecated package

* Add up-to-date melissa builds

* Remove blank lines and FIXME comments

* Use directive syntax for maintainers and remove unnecessary comments

* Remove unused function

* Deprecate former melissa recipe

* Change melissa python package name

* Update setuptools and rapidjson dependencies versions

* Fix mypy error

* Restore rapidjson version

* Variant simplification

* Make variants lower case

* Deprecate former omitted version

* Make torch version consistent with requirement file

* Fix variants definition

* Fix style error

---------

Co-authored-by: Marc Schouler <marc.schouler@inria.fr>
2023-05-26 17:26:29 -05:00
Manuela Kuhn
b91ec05e13 py-coloredlogs: add 15.0.1 and py-humanfriendly: add 10.0 (#37905) 2023-05-26 17:22:02 -05:00
Manuela Kuhn
3bb15f420b py-contourpy: add 1.0.7 (#37914) 2023-05-26 17:19:40 -05:00
Manuela Kuhn
124a81df5b py-coverage: add 5.5 (#37922) 2023-05-26 17:06:39 -05:00
Lee James O'Riordan
d9472c083d Update py-pennylane ecosystem to support v0.30.0 (#37763)
* Update PennyLane ecosystem for 0.30 release

* Update package dep versions

* Fix formatting

* Update dep versions

* Remove PL hard pin and rely on PLQ to define version

* Update var/spack/repos/builtin/packages/py-pennylane-lightning-kokkos/package.py

Co-authored-by: Vincent Michaud-Rioux <vincent.michaud-rioux@xanadu.ai>

* Convert pybind11 from build to link dep, and PL ver limit

---------

Co-authored-by: Vincent Michaud-Rioux <vincent.michaud-rioux@xanadu.ai>
2023-05-26 16:55:21 -05:00
Manuela Kuhn
ac2a5ef4dd py-beautifulsoup4: add 4.12.2 (#37820) 2023-05-26 16:54:43 -05:00
Manuela Kuhn
ea210a6acf py-chardet: add 5.1.0 (#37879)
* py-chardet: add 5.1.0

* Remove py-setuptools as run dependency
2023-05-26 16:51:54 -05:00
kwryankrattiger
afb3bef7af CI: Use relative path in default script (#36649) 2023-05-26 14:28:48 -06:00
George Young
b5b5881426 picard: add 3.0.0, switch to java@17: (#37948)
Co-authored-by: LMS Bioinformatics <bioinformatics@lms.mrc.ac.uk>
2023-05-26 15:38:26 -04:00
George Young
76fc7915a8 minimap2: adding 2.26 (#37945)
Co-authored-by: LMS Bioinformatics <bioinformatics@lms.mrc.ac.uk>
2023-05-26 10:12:14 -07:00
George Young
e7798b619b hyphy: add 2.5.51hf, update dependencies for switch to MPI (#37938)
Co-authored-by: LMS Bioinformatics <bioinformatics@lms.mrc.ac.uk>
2023-05-26 09:48:26 -07:00
Kai Torben Ohlhus
8ecef12a20 Strip inactive maintainer. (#36048) 2023-05-26 10:47:39 -04:00
Brian Spilner
694292ebbf cdo: add 2.2.0 (#37244) 2023-05-26 10:01:49 +02:00
Howard Pritchard
7f18f6f8a1 PMIx and PRRTe: disabled use of sphinx (#37750)
Related to https://github.com/spack/spack/pull/37717

No need to be rebuilding openmpi man pages and other docs in
spack as it almost always is used with release tarballs.

See #37717 for more details.

Signed-off-by: Howard Pritchard <howardp@lanl.gov>
2023-05-26 09:49:02 +02:00
John W. Parent
0b12a480eb Windows MSVC: do not set sdk version if installing sdk (#37930)
Note the win-sdk package is not installable and reports an error
which instructs the user how to add it. Without this fix, a
(more confusing) error occurs before this message can be generated.
2023-05-25 21:38:04 -04:00
George Young
2d91a79af3 fastp: add version 0.23.3, add build dependencies (#37931)
Co-authored-by: LMS Bioinformatics <bioinformatics@lms.mrc.ac.uk>
2023-05-25 21:28:13 -04:00
Leonard-Anderson-NNL
72fcee7227 gradle:add 7.3 (#37928)
Co-authored-by: Cloud User <leonardanderson@leonardander001.hzterscemazurawp3xenxzahla.bx.internal.cloudapp.net>
2023-05-25 20:55:09 -04:00
John W. Parent
d147ef231f Windows: fix "spack build-env" (#37923)
"spack build-env" was not generating proper environment variable
definitions on Windows; this commit updates the generated commands
to succeed with batch/PowerShell.
2023-05-25 17:08:15 -07:00
eugeneswalker
1c7af83d32 update ci ml darwin keypath (#37927) 2023-05-25 16:27:56 -07:00
John W. Parent
b982dfc071 Windows CI: add paraview deps nightly build (#37924)
Add a nightly job to attempt building all Paraview dependencies and
upload the results to cdash. This check doesn't affect the reported
build/test status of Spack. We are using this to monitor the state of
Windows support while working on more-robust checks (eventually the
Windows build will have to succeed to merge PRs to Spack).
2023-05-25 16:13:41 -07:00
H. Joe Lee
c0da8a00fc fix(protobuf-c): set version bound for protobuf dependency (#37917)
Fix #37887 GitLab CI failure.
2023-05-25 19:08:54 -04:00
H. Joe Lee
3f18f689d8 fix(dpdk): add a new version 23.03. (#37919)
Fix E4S GitLab CI issue #37887.
2023-05-25 18:58:41 -04:00
Simon Pintarelli
9dc4553cf3 sirius: add rocsolver/wannier90 (#37900)
* sirius: add rocsolver dependency for 7.5:
* add wannier90
2023-05-25 15:58:04 -07:00
Tim Haines
9a99c94b75 Dyninst: add standalone test (#37876)
* Dyninst: add standalone test
* Add docstring with description
* Don't use join_path for builtin path objects
* Whitespace
* Update format of docstring
2023-05-25 18:48:52 -04:00
John W. Parent
682f0b2a54 Protobuf package: CMake fix for Windows build (#37926)
Qualify reference with namespace. A pending upstream PR will eventually
make this unnecessary, so the patch is only applied for 3.22. versions.
2023-05-25 15:41:16 -07:00
Richard Berger
dbab0c1ff5 flecsi: disable cinch dependency for v1 release (#37857)
* flecsi: disable cinch dependency for v1 releases
* [@spackbot] updating style on behalf of rbberger

---------

Co-authored-by: rbberger <rbberger@users.noreply.github.com>
2023-05-25 14:59:45 -07:00
Xavier Delaruelle
2bf95f5340 environment-modules: fix @main version requirements (#37807)
Some requirements for @main version of environment-modules were missing:

* python (to build ChangeLog documentation file)
* py-sphinx@1.0: (to build man-pages, etc)

Also adding gzip, which is now required to build ChangeLog.gz (which is
now shipped instead of ChangeLog).

Other versions are not requiring these tools (as documentation is
pre-built in dist tarball).
2023-05-25 22:29:26 +02:00
Tamara Dahlgren
55561405b8 Bugfix/tests: write not append stand-alone test status (#37841) 2023-05-25 12:36:24 -07:00
H. Joe Lee
8eef458cea fix(pmdk): add pkconfig as dependency (#37896)
Fix #37887 failure.
2023-05-25 10:35:48 -07:00
Stephen Sachs
64eea9d996 [devito] Move to version 4.8.1 (#37915)
* [devito] Move to version 4.8.1

* Fix: Adding patch file

* Update var/spack/repos/builtin/packages/py-devito/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Update var/spack/repos/builtin/packages/py-devito/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Addressing @adamjstewart comments

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-25 13:33:10 -04:00
Alex Richert
60b4e2128b Add shared variant to geos package (#37899)
Co-authored-by: alexrichert <alexrichert@gmail.com>
2023-05-25 11:42:51 -04:00
Adam J. Stewart
2f8cea2792 Add macOS ML CI stacks (#36586)
* Add macOS ML CI stacks

* torchmeta is no longer maintained and requires ancient PyTorch

* Add MXNet

* update darwin aarch64 stacks

* add darwin-aarch64 scoped config.yaml

* remove unnecessary cleanup job

* fix specifications

* fix labels

* fix labels

* fix indent on tags specification

* no tags for trigger jobs

* try overriding tags in stack spack.yaml

* do not use CI_STACK_CONFIG_SCOPES

* incorporate config:install_tree:root: overrides and compiler defs

* copy relevant ci-scoped config settings directly into stack spack.yaml

* remove build-job-remove

* spack ci generate: add debug flag

* include cdash config directly in stack spack.yaml

* customize build-job script section to avoid absolute paths

* add any-job specification

* tags: use aarch64-macos instead of aarch64

* generate tags: use aarch64-macos instead of aarch64

* do not add morepadding

* use shared mirror; comment out known failures

* remove any-job

* nproc || true

* comment out specs failing due to bazel from cache codesign issue

---------

Co-authored-by: eugeneswalker <eugenesunsetwalker@gmail.com>
2023-05-25 01:12:54 -04:00
M. Eric Irrgang
06f9bcf734 Update for py-gmxapi for 0.4.1. (#37834)
* Update for py-gmxapi for 0.4.1.

* Note 0.4.1 hash from PyPI.
* Note relaxed dependencies for future versions.

* Update var/spack/repos/builtin/packages/py-gmxapi/package.py
2023-05-24 22:03:10 -05:00
Manuela Kuhn
ee2725762f py-charset-normalizer: add 3.1.0 (#37880) 2023-05-24 21:57:29 -05:00
Manuela Kuhn
eace0a177c py-bids-validator: add 1.11.0 (#37845) 2023-05-24 21:36:45 -05:00
Manuela Kuhn
80c7d74707 py-bottleneck: add 1.3.7 (#37847) 2023-05-24 21:36:01 -05:00
Manuela Kuhn
a6f5bf821d py-certifi: add 2023.5.7 (#37848) 2023-05-24 21:35:13 -05:00
Manuela Kuhn
b214406253 py-attrs: add 23.1.0 (#37817)
* py-attrs: add 23.1.0

* Add missing dependency
2023-05-24 20:21:31 -05:00
Manuela Kuhn
5b003d80e5 py-babel: add 2.12.1 (#37818)
* py-babel: add 2.12.1

* Update var/spack/repos/builtin/packages/py-babel/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-24 20:13:02 -05:00
Adam J. Stewart
185b2d3ee7 py-rasterio: add v1.3.7 (#37886) 2023-05-24 18:48:16 -04:00
Adam J. Stewart
71bb2a1899 py-lightly: add v1.4.6 (#37885) 2023-05-24 16:43:07 -04:00
Nathalie Furmento
785c31b730 starpu: add release 1.4.1 (#37883) 2023-05-24 09:36:56 -07:00
QuellynSnead
175da4a88a paraview (protobuf failure) #37437 (#37440)
When attempting to build paraview@5.10.1 using a recent Intel
compiler (Classic or OneAPI) or the IBM XL compiler, the build
fails if the version of protobuf used is > 3.18
2023-05-24 11:09:48 -05:00
willdunklin
73fc1ef11c sensei: Allow Paraview 5.11 for sensei develop version (#37719) 2023-05-24 11:00:35 -05:00
Stephen Sachs
2d77e44f6f Pcluster local buildcache (#37852)
* [pcluster pipeline] Use local buildcache instead of upstream spack

Spack currently does not relocate compiler references from upstream spack
installations. When using a buildcache we don't need an upstream spack.

* gcc needs to be installed via postinstall to get correct deps

* quantum-espresso@gcc@12.3.0 returns ICE on neoverse_{n,v}1

* Force gitlab to pull the new container

* Revert "Force gitlab to pull the new container"

This reverts commit 3af5f4cd88.

Seems the gitlab version does not yet support "pull_policy" in .gitlab-ci.yml

* Gitlab keeps picking up wrong container. Renaming

* Update containers once more after failed build
2023-05-24 06:55:00 -07:00
Greg Becker
033599c4cd bugfix: env concretize after remove (#37877) 2023-05-24 15:41:57 +02:00
Harmen Stoppels
8096ed4b22 spack remove: fix traversal when user specs intersect (#37882)
drop unnecessary double loop over the matching user specs.
2023-05-24 09:23:46 -04:00
Simon Pintarelli
b49bfe25af update nlcglib package (#37578) 2023-05-24 11:17:15 +02:00
Houjun Tang
8b2f34d802 Add async vol v1.6 (#37875) 2023-05-24 01:47:46 -04:00
H. Joe Lee
3daed0d6a7 hdf5-vol-daos: add a new package (#35653)
* hdf5-vol-daos: add a new package
* hdf5-vol-daos: address @soumagne review

---------

Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>
2023-05-23 23:42:42 -04:00
Glenn Johnson
d6c1f75e8d julia: remove myself from maintainers list (#37868) 2023-05-23 16:22:56 -05:00
Laura Weber
c80a4c1ddc Updated hash for latest maintenance release (2022.2.1) (#37842) 2023-05-23 14:08:55 -07:00
Glenn Johnson
466abcb62d gate: remove myself as maintainer (#37862) 2023-05-23 14:03:52 -07:00
Glenn Johnson
69e99f0c16 Remove myself as maintainer of R packages (#37859)
* Remove myself as maintainer of R packages
  I will no longer have the time to properly maintain these packages.
* fix flake8 test for import
2023-05-23 15:35:32 -05:00
Glenn Johnson
bbee6dfc58 bart: remove myself as maintainer (#37860) 2023-05-23 16:08:07 -04:00
Glenn Johnson
2d60cf120b heasoft: remove myself as maintainer (#37866) 2023-05-23 14:37:57 -05:00
Glenn Johnson
db17fc2f33 opencv: remove myself from maintainers list (#37870) 2023-05-23 14:34:52 -05:00
eugeneswalker
c62080d498 e4s ci: add dealii (#32484) 2023-05-23 21:34:31 +02:00
Glenn Johnson
f9bbe549fa gatetools: remove myself as maintainer (#37863) 2023-05-23 15:32:54 -04:00
H. Joe Lee
55d7fec69c daos: add a new package (#35649) 2023-05-23 21:30:23 +02:00
Glenn Johnson
e938907150 reditools: remove myself as maintainer (#37871) 2023-05-23 15:28:16 -04:00
Glenn Johnson
0c40b86e96 itk: remove myself as maintainer (#37867) 2023-05-23 15:27:55 -04:00
Glenn Johnson
3d4cf0d8eb mumax: remove myself as maintainer (#37869) 2023-05-23 15:23:28 -04:00
Glenn Johnson
966e19d278 gurobi: remove myself as maintainer (#37865) 2023-05-23 15:23:05 -04:00
Glenn Johnson
8f930462bd fplo: remove myself as maintainer (#37861) 2023-05-23 15:17:50 -04:00
kjrstory
bf4fccee15 New package: FDS (#37850) 2023-05-23 11:59:05 -07:00
Manuela Kuhn
784771a008 py-bleach: add 6.0.0 (#37846) 2023-05-23 11:50:53 -07:00
Glenn Johnson
e4a9d9ae5b Bioc updates (#37297)
* add version 1.48.0 to bioconductor package r-a4
* add version 1.48.0 to bioconductor package r-a4base
* add version 1.48.0 to bioconductor package r-a4classif
* add version 1.48.0 to bioconductor package r-a4core
* add version 1.48.0 to bioconductor package r-a4preproc
* add version 1.48.0 to bioconductor package r-a4reporting
* add version 1.54.0 to bioconductor package r-absseq
* add version 1.30.0 to bioconductor package r-acde
* add version 1.78.0 to bioconductor package r-acgh
* add version 2.56.0 to bioconductor package r-acme
* add version 1.70.0 to bioconductor package r-adsplit
* add version 1.72.0 to bioconductor package r-affxparser
* add version 1.78.0 to bioconductor package r-affy
* add version 1.76.0 to bioconductor package r-affycomp
* add version 1.58.0 to bioconductor package r-affycontam
* add version 1.72.0 to bioconductor package r-affycoretools
* add version 1.48.0 to bioconductor package r-affydata
* add version 1.52.0 to bioconductor package r-affyilm
* add version 1.70.0 to bioconductor package r-affyio
* add version 1.76.0 to bioconductor package r-affyplm
* add version 1.46.0 to bioconductor package r-affyrnadegradation
* add version 1.48.0 to bioconductor package r-agdex
* add version 3.32.0 to bioconductor package r-agilp
* add version 2.50.0 to bioconductor package r-agimicrorna
* add version 1.32.0 to bioconductor package r-aims
* add version 1.32.0 to bioconductor package r-aldex2
* add version 1.38.0 to bioconductor package r-allelicimbalance
* add version 1.26.0 to bioconductor package r-alpine
* add version 2.62.0 to bioconductor package r-altcdfenvs
* add version 2.24.0 to bioconductor package r-anaquin
* add version 1.28.0 to bioconductor package r-aneufinder
* add version 1.28.0 to bioconductor package r-aneufinderdata
* add version 1.72.0 to bioconductor package r-annaffy
* add version 1.78.0 to bioconductor package r-annotate
* add version 1.62.0 to bioconductor package r-annotationdbi
* add version 1.24.0 to bioconductor package r-annotationfilter
* add version 1.42.0 to bioconductor package r-annotationforge
* add version 3.8.0 to bioconductor package r-annotationhub
* add version 3.30.0 to bioconductor package r-aroma-light
* add version 1.32.0 to bioconductor package r-bamsignals
* add version 2.16.0 to bioconductor package r-beachmat
* add version 2.60.0 to bioconductor package r-biobase
* add version 2.8.0 to bioconductor package r-biocfilecache
* add version 0.46.0 to bioconductor package r-biocgeneric
* add version 1.10.0 to bioconductor package r-biocio
* add version 1.18.0 to bioconductor package r-biocneighbors
* add version 1.34.0 to bioconductor package r-biocparallel
* add version 1.16.0 to bioconductor package r-biocsingular
* add version 2.28.0 to bioconductor package r-biocstyle
* add version 3.17.1 to bioconductor package r-biocversion
* add version 2.56.0 to bioconductor package r-biomart
* add version 1.28.0 to bioconductor package r-biomformat
* add version 2.68.0 to bioconductor package r-biostrings
* add version 1.48.0 to bioconductor package r-biovizbase
* add version 1.10.0 to bioconductor package r-bluster
* add version 1.68.0 to bioconductor package r-bsgenome
* add version 1.36.0 to bioconductor package r-bsseq
* add version 1.42.0 to bioconductor package r-bumphunter
* add version 2.66.0 to bioconductor package r-category
* add version 2.30.0 to bioconductor package r-champ
* add version 2.32.0 to bioconductor package r-champdata
* add version 1.50.0 to bioconductor package r-chipseq
* add version 4.8.0 to bioconductor package r-clusterprofiler
* add version 1.36.0 to bioconductor package r-cner
* add version 1.32.0 to bioconductor package r-codex
* add version 2.16.0 to bioconductor package r-complexheatmap
* add version 1.74.0 to bioconductor package r-ctc
* add version 2.28.0 to bioconductor package r-decipher
* add version 0.26.0 to bioconductor package r-delayedarray
* add version 1.22.0 to bioconductor package r-delayedmatrixstats
* add version 1.40.0 to bioconductor package r-deseq2
* add version 1.46.0 to bioconductor package r-dexseq
* add version 1.42.0 to bioconductor package r-dirichletmultinomial
* add version 2.14.0 to bioconductor package r-dmrcate
* add version 1.74.0 to bioconductor package r-dnacopy
* add version 3.26.0 to bioconductor package r-dose
* add version 2.48.0 to bioconductor package r-dss
* add version 3.42.0 to bioconductor package r-edger
* add version 1.20.0 to bioconductor package r-enrichplot
* add version 2.24.0 to bioconductor package r-ensembldb
* add version 1.46.0 to bioconductor package r-exomecopy
* add version 2.8.0 to bioconductor package r-experimenthub
* add version 1.26.0 to bioconductor package r-fgsea
* add version 2.72.0 to bioconductor package r-gcrma
* add version 1.36.0 to bioconductor package r-gdsfmt
* add version 1.82.0 to bioconductor package r-genefilter
* add version 1.36.0 to bioconductor package r-genelendatabase
* add version 1.72.0 to bioconductor package r-genemeta
* add version 1.78.0 to bioconductor package r-geneplotter
* add version 1.22.0 to bioconductor package r-genie3
* add version 1.36.0 to bioconductor package r-genomeinfodb
* update r-genomeinfodbdata
* add version 1.36.0 to bioconductor package r-genomicalignments
* add version 1.52.0 to bioconductor package r-genomicfeatures
* add version 1.52.0 to bioconductor package r-genomicranges
* add version 2.68.0 to bioconductor package r-geoquery
* add version 1.48.0 to bioconductor package r-ggbio
* add version 3.8.0 to bioconductor package r-ggtree
* add version 2.10.0 to bioconductor package r-glimma
* add version 1.12.0 to bioconductor package r-glmgampoi
* add version 5.54.0 to bioconductor package r-globaltest
* update r-go-db
* add version 1.20.0 to bioconductor package r-gofuncr
* add version 2.26.0 to bioconductor package r-gosemsim
* add version 1.52.0 to bioconductor package r-goseq
* add version 2.66.0 to bioconductor package r-gostats
* add version 1.78.0 to bioconductor package r-graph
* add version 1.62.0 to bioconductor package r-gseabase
* add version 1.32.0 to bioconductor package r-gtrellis
* add version 1.44.0 to bioconductor package r-gviz
* add version 1.28.0 to bioconductor package r-hdf5array
* add version 1.72.0 to bioconductor package r-hypergraph
* add version 1.36.0 to bioconductor package r-illumina450probevariants-db
* add version 0.42.0 to bioconductor package r-illuminaio
* add version 1.74.0 to bioconductor package r-impute
* add version 1.38.0 to bioconductor package r-interactivedisplaybase
* add version 2.34.0 to bioconductor package r-iranges
* add version 1.60.0 to bioconductor package r-kegggraph
* add version 1.40.0 to bioconductor package r-keggrest
* add version 3.56.0 to bioconductor package r-limma
* add version 2.52.0 to bioconductor package r-lumi
* add version 1.76.0 to bioconductor package r-makecdfenv
* add version 1.78.0 to bioconductor package r-marray
* add version 1.12.0 to bioconductor package r-matrixgenerics
* add version 1.8.0 to bioconductor package r-metapod
* add version 2.46.0 to bioconductor package r-methylumi
* add version 1.46.0 to bioconductor package r-minfi
* add version 1.34.0 to bioconductor package r-missmethyl
* add version 1.80.0 to bioconductor package r-mlinterfaces
* add version 1.12.0 to bioconductor package r-mscoreutils
* add version 2.26.0 to bioconductor package r-msnbase
* add version 2.56.0 to bioconductor package r-multtest
* add version 1.38.0 to bioconductor package r-mzid
* add version 2.34.0 to bioconductor package r-mzr
* add version 1.62.0 to bioconductor package r-oligoclasses
* update r-org-hs-eg-db
* add version 1.42.0 to bioconductor package r-organismdbi
* add version 1.40.0 to bioconductor package r-pathview
* add version 1.92.0 to bioconductor package r-pcamethods
* update r-pfam-db
* add version 1.44.0 to bioconductor package r-phyloseq
* add version 1.62.0 to bioconductor package r-preprocesscore
* add version 1.32.0 to bioconductor package r-protgenerics
* add version 1.34.0 to bioconductor package r-quantro
* add version 2.32.0 to bioconductor package r-qvalue
* add version 1.76.0 to bioconductor package r-rbgl
* add version 2.40.0 to bioconductor package r-reportingtools
* add version 2.44.0 to bioconductor package r-rgraphviz
* add version 2.44.0 to bioconductor package r-rhdf5
* add version 1.12.0 to bioconductor package r-rhdf5filters
* add version 1.22.0 to bioconductor package r-rhdf5lib
* add version 1.76.0 to bioconductor package r-roc
* add version 1.28.0 to bioconductor package r-rots
* add version 2.16.0 to bioconductor package r-rsamtools
* add version 1.60.0 to bioconductor package r-rtracklayer
* add version 0.38.0 to bioconductor package r-s4vectors
* add version 1.8.0 to bioconductor package r-scaledmatrix
* add version 1.28.0 to bioconductor package r-scater
* add version 1.14.0 to bioconductor package r-scdblfinder
* add version 1.28.0 to bioconductor package r-scran
* add version 1.10.0 to bioconductor package r-scuttle
* add version 1.66.0 to bioconductor package r-seqlogo
* add version 1.58.0 to bioconductor package r-shortread
* add version 1.74.0 to bioconductor package r-siggenes
* add version 1.22.0 to bioconductor package r-singlecellexperiment
* add version 1.34.0 to bioconductor package r-snprelate
* add version 1.50.0 to bioconductor package r-snpstats
* add version 2.36.0 to bioconductor package r-somaticsignatures
* add version 1.12.0 to bioconductor package r-sparsematrixstats
* add version 1.40.0 to bioconductor package r-spem
* add version 1.38.0 to bioconductor package r-sseq
* add version 1.30.0 to bioconductor package r-summarizedexperiment
* add version 3.48.0 to bioconductor package r-sva
* add version 1.38.0 to bioconductor package r-tfbstools
* add version 1.22.0 to bioconductor package r-tmixclust
* add version 2.52.0 to bioconductor package r-topgo
* add version 1.24.0 to bioconductor package r-treeio
* add version 1.28.0 to bioconductor package r-tximport
* add version 1.28.0 to bioconductor package r-tximportdata
* add version 1.46.0 to bioconductor package r-variantannotation
* add version 3.68.0 to bioconductor package r-vsn
* add version 2.6.0 to bioconductor package r-watermelon
* add version 2.46.0 to bioconductor package r-xde
* add version 1.58.0 to bioconductor package r-xmapbridge
* add version 0.40.0 to bioconductor package r-xvector
* add version 1.26.0 to bioconductor package r-yapsa
* add version 1.26.0 to bioconductor package r-yarn
* add version 1.46.0 to bioconductor package r-zlibbioc
* Revert "add version 1.82.0 to bioconductor package r-genefilter"
  This reverts commit 1702071c6d.
* Revert "add version 0.38.0 to bioconductor package r-s4vectors"
  This reverts commit 58a7df2387.
* add version 0.38.0 to bioconductor package r-s4vectors
* Revert "add version 1.28.0 to bioconductor package r-aneufinder"
  This reverts commit 0a1f59de6c.
* add version 1.28.0 to bioconductor package r-aneufinder
* Revert "add version 2.16.0 to bioconductor package r-beachmat"
  This reverts commit cd49fb8e4c.
* add version 2.16.0 to bioconductor package r-beachmat
* Revert "add version 4.8.0 to bioconductor package r-clusterprofiler"
  This reverts commit 6e9a951cbe.
* add version 4.8.0 to bioconductor package r-clusterprofiler
* Fix syntax error
* r-genefilter: add version 1.82.0
* new package: r-basilisk-utils
* new package: r-basilisk
* new package: r-densvis
* new package: r-dir-expiry
* r-affyplm: add zlib dependency
* r-cner: add zlib dependency
* r-mzr: add zlib dependency
* r-rhdf5filters: add zstd dependency
* r-shortread: add zlib dependency
* r-snpstats: add zlib dependency

---------

Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>
2023-05-23 11:40:00 -07:00
snehring
a6886983dc usalign: new package (#37646)
* usalign: adding new package
* usalign: updating shasum, adding note about distribution
2023-05-23 11:30:40 -07:00
Andrey Parfenov
93a34a9635 hpcg: apply patch with openmp pragma changes for intel and oneapi compilers (#37856)
Signed-off-by: Andrey Parfenov <andrey.parfenov@intel.com>
2023-05-23 11:52:45 -04:00
Todd Gamblin
91a54029f9 libgcrypt: patch 1.10.2 on macos (#37844)
macOS doesn't have `getrandom`, and 1.10.2 fails to compile because of this.

There's an upstream fix at https://dev.gnupg.org/T6442 that will be in the next
`libgcrypt` release, but the patch is available now.
2023-05-23 06:03:13 -04:00
Juan Miguel Carceller
5400b49ed6 dd4hep: add LD_LIBRARY_PATH for plugins for Gaudi (#37824)
Co-authored-by: jmcarcell <jmcarcell@users.noreply.github.com>
2023-05-23 10:28:26 +01:00
Juan Miguel Carceller
c17fc3c0c1 gaudi: add gaudi to LD_LIBRARY_PATH (#37821)
Co-authored-by: jmcarcell <jmcarcell@users.noreply.github.com>
2023-05-23 10:27:55 +01:00
Juan Miguel Carceller
6f248836ea dd4hep: restrict podio versions (#37699)
Co-authored-by: jmcarcell <jmcarcell@users.noreply.github.com>
2023-05-23 10:20:31 +01:00
snehring
693c1821b0 py-pastml: adding version for compatibility with py-topiary-asr (#37828) 2023-05-22 14:44:00 -05:00
Manuela Kuhn
62afe3bd5a py-asttokens: add 2.2.1 (#37816) 2023-05-22 14:40:08 -05:00
genric
53a756d045 py-dask: add v2023.4.1 (#37550)
* py-dask: add v2023.4.1

* address review comments
2023-05-22 14:29:23 -05:00
Adam J. Stewart
321b687ae6 py-huggingface-hub: add v0.14.1, cli variant (#37815) 2023-05-22 11:19:41 -07:00
Adam J. Stewart
c8617f0574 py-fiona: add v1.9.4 (#37780) 2023-05-22 13:17:13 -05:00
Adam J. Stewart
7843e2ead0 azcopy: add new package (#37693) 2023-05-22 11:09:06 -07:00
Juan Miguel Carceller
dca3d071d7 gaudi: fix issue with fmt::format (#37810)
Co-authored-by: jmcarcell <jmcarcell@users.noreply.github.com>
2023-05-22 10:33:05 -07:00
eugeneswalker
436f077482 tau %oneapi: -Wno-error=implicit-function-declaration (#37829) 2023-05-22 13:13:02 -04:00
simonleary-umass-edu
ab3f705019 deleted package.py better error message (#37814)
adds the namespace to the exception object's string representation
2023-05-22 09:59:07 -07:00
Tamara Dahlgren
d739989ec8 swig: convert to new stand-alone test process (#37786) 2023-05-22 09:39:30 -07:00
Jordan Galby
52ee1967d6 llvm: Fix hwloc@1 and hwloc@:2.3 compatibility (#35387) 2023-05-22 10:28:57 -05:00
Andrey Prokopenko
1af7284b5d arborx: new version 1.4 (#37809) 2023-05-21 12:25:53 -07:00
Todd Gamblin
e1bcefd805 Update CHANGELOG.md for v0.20.0 2023-05-21 01:48:34 +02:00
Manuela Kuhn
2159b0183d py-argcomplete: add 3.0.8 (#37797)
* py-argcomplete: add 3.0.8

* Update var/spack/repos/builtin/packages/py-argcomplete/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* [@spackbot] updating style on behalf of manuelakuhn

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-20 11:31:28 -05:00
kwryankrattiger
078fd225a9 Mochi-Margo: Add patch for pthreads detection (#36109) 2023-05-20 07:43:27 -07:00
Manuela Kuhn
83974828c7 libtiff: disable use of sphinx (#37803) 2023-05-19 21:37:19 -05:00
Manuela Kuhn
2412f74557 py-anyio: add 3.6.2 (#37796) 2023-05-19 21:36:39 -05:00
Manuela Kuhn
db06d3621d py-alabaster: add 0.7.13 (#37798) 2023-05-19 21:34:00 -05:00
Jose E. Roman
c25170d2f9 New patch release SLEPc 3.19.1 (#37675)
* New patch release SLEPc 3.19.1

* py-slepc4py: add explicit dependency on py-numpy
2023-05-19 21:33:21 -05:00
Vanessasaurus
b3dfe13670 Automated deployment to update package flux-security 2023-05-16 (#37696)
Co-authored-by: github-actions <github-actions@users.noreply.github.com>
2023-05-19 12:07:57 -07:00
Harmen Stoppels
6358e84b48 fix binutils dep of spack itself (#37738) 2023-05-19 12:02:36 -07:00
Swann Perarnau
8e634d8e49 aml: v0.2.1 (#37621)
* aml: v0.2.1

* add version 0.2.1
* fix hip variant bug

* [fix] pkgconf required for all builds

On top of needing pkgconf for autoreconf builds, the release configure
scripts needs pkgconf do detect dependencies if any of the hwloc, ze, or
opencl variants are active.

* Remove deprecation for v0.2.0 based on PR advise.
2023-05-19 11:58:28 -07:00
Mark W. Krentel
1a21376515 intel-xed: add version 2023.04.16 (#37582)
* intel-xed: add version 2023.04.16
 1. add version 2023.04.16
 2. adjust the mbuild resource to better match the xed version at the time
 3. replace three conflicts() with one new requires() for x86_64 target
 4. add patch for libxed-ild for some new avx512 instructions
    * [@spackbot] updating style on behalf of mwkrentel
    * Fix the build for 2023.04.16.  XED requires its source directory to be exactly 'xed', so add a symlink.
 5. move the mbuild resource up one level, xed wants it to be in the same directory as the xed source dir
 6. deprecate 10.2019.03
    * semantic style fix: add OSError to except
    * [@spackbot] updating style on behalf of mwkrentel

---------

Co-authored-by: mwkrentel <mwkrentel@users.noreply.github.com>
2023-05-19 10:28:18 -07:00
Harmen Stoppels
bf45a2b6d3 spack env create: generate a view when newly created env has concrete specs (#37799) 2023-05-19 18:44:54 +02:00
Thomas-Ulrich
475ce955e7 hipsycl: add v0.9.4 (#37247) 2023-05-19 18:29:45 +02:00
Robert Underwood
5e44289787 updates for the libpressio ecosystem (#37764)
* updates for the libpressio ecosystem

* [@spackbot] updating style on behalf of robertu94

* style fix: remove FIXME

---------

Co-authored-by: Robert Underwood <runderwood@anl.gov>
Co-authored-by: eugeneswalker <eugenesunsetwalker@gmail.com>
2023-05-19 09:24:31 -07:00
Massimiliano Culpo
e66888511f archspec: fix entry in the JSON file (#37793) 2023-05-19 09:57:57 -04:00
Tamara Dahlgren
e9e5beee1f fortrilinos: convert to new stand-alone test process (#37783) 2023-05-19 08:06:33 -04:00
Tamara Dahlgren
ffd134c09d formetis: converted to new stand-alone test process (#37785) 2023-05-19 08:05:23 -04:00
Massimiliano Culpo
bfadd5c9a5 lmod: allow core compiler to be specified with a version range (#37789)
Use CompilerSpec with satisfies instead of string equality tests

Co-authored-by: Harmen Stoppels <harmenstoppels@gmail.com>
2023-05-19 13:21:40 +02:00
Greg Becker
16e9279420 compiler specs: do not print '@=' when clear from context (#37787)
Ensure that spack compiler add/find/list and lists of concrete specs
print the compiler effectively as {compiler.name}{@compiler.version}.

Co-authored-by: Harmen Stoppels <harmenstoppels@gmail.com>
2023-05-19 11:31:27 +02:00
Satish Balay
ac0903ef9f llvm: add version 16.0.3 (#37472) 2023-05-19 03:37:57 -04:00
Cyrus Harrison
648839dffd add conduit 0.8.8 release (#37776) 2023-05-19 00:34:19 -04:00
Pieter Ghysels
489a604920 Add STRUMPACK versions 7.1.2 and 7.1.3 (#37779) 2023-05-18 23:18:50 -04:00
eugeneswalker
2ac3435810 legion +rocm: apply patch for --offload-arch (#37775)
* legion +rocm: apply patch for --offload-arch

* constrain to latest version
2023-05-18 23:03:50 -04:00
Alec Scott
69ea180d26 fzf: add v0.40.0 and refactor package (#37569)
* fzf: add v0.40.0 and refactor package
* Remove unused imports
2023-05-18 15:23:20 -07:00
Alec Scott
f52f217df0 roctracer-dev-api: add v5.5.0 (#37484) 2023-05-18 15:11:36 -07:00
Alec Scott
df74aa5d7e amqp-cpp: add v4.3.24 (#37504) 2023-05-18 15:09:30 -07:00
Alec Scott
41932c53ae libjwt: add v1.15.3 (#37521) 2023-05-18 15:05:27 -07:00
Alec Scott
4296db794f rdkit: add v2023_03_1 (#37529) 2023-05-18 15:05:07 -07:00
H. Joe Lee
9ab9302409 py-jarvis-util: add a new package (#37729)
* py-jarvis-util: add a new package

* Apply suggestions from code review

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-18 17:28:59 -04:00
Benjamin Meyers
0187376e54 Update py-nltk (#37703)
* Update py-nltk

* [@spackbot] updating style on behalf of meyersbs

* Update var/spack/repos/builtin/packages/py-nltk/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-18 17:14:20 -04:00
Aditya Bhamidipati
7340d2cb83 update package nccl version 2.17, 2.18 (#37721) 2023-05-18 15:47:01 -05:00
Benjamin Meyers
641d4477d5 New package py-tensorly (#37705) 2023-05-18 15:38:23 -05:00
Benjamin Meyers
3ff2fb69af New package py-scikit-tensor-py3 (#37706) 2023-05-18 15:37:43 -05:00
vucoda
e3024b1bcb Update py-jedi 0.17.2 checksum in package.py (#37700)
Pypi for jedi-0.17.2.tar.gz does not match the package.py file.

https://pypi.org/project/jedi/0.17.2/#copy-hash-modal-60e943e3-1192-4b12-90e2-4d639cb5b4f7
2023-05-18 15:15:47 -05:00
Dom Heinzeller
e733b87865 Remove references to gmake executable, only use make (#37280) 2023-05-18 19:03:03 +00:00
Victor Lopez Herrero
919985dc1b dlb: add v3.3.1 (#37759) 2023-05-18 10:29:41 -07:00
Michael Kuhn
d746f7d427 harfbuzz: add 7.3.0 (#37753)
Do not prefer 5.3.1 anymore since it does not build with newer compilers. Linux distributions have also moved to 6.x and newer.
2023-05-18 10:27:48 -07:00
kaanolgu
b6deab515b [babelstream] FIX: maintainers list missing a comma (#37761) 2023-05-18 10:25:04 -07:00
Glenn Johnson
848220c4ba update R: add version 4.3.0 (#37090) 2023-05-18 10:13:28 -07:00
Glenn Johnson
98462bd27e Cran updates (#37296)
* add version 1.28.3 to r-hexbin
* add version 5.0-1 to r-hmisc
* add version 0.5.5 to r-htmltools
* add version 1.6.2 to r-htmlwidgets
* add version 1.4.2 to r-igraph
* add version 0.42.19 to r-imager
* add version 1.0-5 to r-inum
* add version 0.9-14 to r-ipred
* add version 1.3.2 to r-irkernel
* add version 2.2.0 to r-janitor
* add version 0.1-10 to r-jpeg
* add version 1.2.2 to r-jsonify
* add version 0.9-32 to r-kernlab
* add version 1.7-2 to r-klar
* add version 1.42 to r-knitr
* add version 1.14.0 to r-ks
* add version 2.11.0 to r-labelled
* add version 1.7.2.1 to r-lava
* add version 0.6-15 to r-lavaan
* add version 2.1.2 to r-leaflet
* add version 2.9-0 to r-lfe
* add version 1.1.6 to r-lhs
* add version 1.1-33 to r-lme4
* add version 1.5-9.7 to r-locfit
* add version 0.4.3 to r-log4r
* add version 5.6.18 to r-lpsolve
* add version 0.2-11 to r-lwgeom
* add version 2.7.4 to r-magick
* add version 1.22.1 to r-maldiquant
* add version 1.2.11 to r-mapproj
* add version 1.6 to r-markdown
* add version 7.3-59 to r-mass
* add version 1.5-4 to r-matrix
* add version 0.63.0 to r-matrixstats
* add version 4.2-3 to r-memuse
* add version 4.0-0 to r-metafor
* add version 1.8-42 to r-mgcv
* add version 3.15.0 to r-mice
* add version 0.4-5 to r-mitml
* add version 2.0.0 to r-mixtools
* add version 0.1.11 to r-modelr
* add version 1.4-23 to r-multcomp
* add version 0.1-9 to r-multcompview
* add version 0.1-13 to r-mutoss
* add version 1.18.1 to r-network
* add version 3.3.4 to r-nleqslv
* add version 3.1-162 to r-nlme
* add version 0.26 to r-nmf
* add version 0.60-17 to r-np
* add version 4.2.5.2 to r-openxlsx
* add version 2022.11-16 to r-ordinal
* add version 0.6.0.8 to r-osqp
* add version 0.9.1 to r-packrat
* add version 1.35.0 to r-parallelly
* add version 1.3-13 to r-party
* add version 1.2-20 to r-partykit
* add version 1.7-0 to r-pbapply
* add version 0.3-9 to r-pbdzmq
* add version 1.2 to r-pegas
* add version 1.5-1 to r-phytools
* add version 1.9.0 to r-pillar
* add version 1.4.0 to r-pkgbuild
* add version 2.1.0 to r-pkgcache
* add version 0.5.0 to r-pkgdepends
* add version 2.0.7 to r-pkgdown
* add version 1.3.2 to r-pkgload
* add version 0.1-8 to r-png
* add version 1.1.22 to r-polspline
* add version 1.0.1 to r-pool
* add version 1.4.1 to r-posterior
* add version 3.8.1 to r-processx
* add version 2023.03.31 to r-prodlim
* add version 1.0-12 to r-proj4
* add version 2.5.0 to r-projpred
* add version 0.1.6 to r-pryr
* add version 1.7.5 to r-ps
* add version 1.0.1 to r-purrr
* add version 1.3.2 to r-qqconf
* add version 0.25.5 to r-qs
* add version 1.60 to r-qtl
* add version 0.4.22 to r-quantmod
* add version 5.95 to r-quantreg
* add version 0.7.8 to r-questionr
* add version 1.2.5 to r-ragg
* add version 0.15.1 to r-ranger
* add version 3.6-20 to r-raster
* add version 2.2.13 to r-rbibutils
* add version 1.0.10 to r-rcpp
* add version 0.12.2.0.0 to r-rcpparmadillo
* add version 0.1.7 to r-rcppde
* add version 0.3.13 to r-rcppgsl
* add version 1.98-1.12 to r-rcurl
* add version 1.2-1 to r-rda
* add version 2.1.4 to r-readr
* add version 1.4.2 to r-readxl
* add version 1.0.6 to r-recipes
* add version 1.1.6 to r-repr
* add version 1.2.16 to r-reproducible
* add version 0.3.0 to r-require
* add version 1.28 to r-reticulate
* add version 2.0.7 to r-rfast
* add version 1.6-6 to r-rgdal
* add version 0.6-2 to r-rgeos
* add version 1.1.3 to r-rgl
* add version 0.2.18 to r-rinside
* add version 4-14 to r-rjags
* add version 1.3-1.8 to r-rjsonio
* add version 2.21 to r-rmarkdown
* add version 0.9-2 to r-rmpfr
* add version 0.7-1 to r-rmpi
* add version 6.6-0 to r-rms
* add version 0.10.25 to r-rmysql
* add version 0.8.7 to r-rncl
* add version 2.4.11 to r-rnexml
* add version 0.95-1 to r-robustbase
* add version 1.3-20 to r-rodbc
* add version 7.2.3 to r-roxygen2
* add version 1.4.5 to r-rpostgres
* add version 0.7-5 to r-rpostgresql
* add version 0.8.29 to r-rsconnect
* add version 0.4-15 to r-rsnns
* add version 2.3.1 to r-rsqlite
* add version 0.7.2 to r-rstatix
* add version 1.1.2 to r-s2
* add version 0.4.5 to r-sass
* add version 0.1.9 to r-scatterpie
* add version 0.3-43 to r-scatterplot3d
* add version 3.2.4 to r-scs
* add version 1.6-4 to r-segmented
* add version 4.2-30 to r-seqinr
* add version 0.26 to r-servr
* add version 4.3.0 to r-seurat
* add version 1.0-12 to r-sf
* add version 0.4.2 to r-sfheaders
* add version 1.1-15 to r-sfsmisc
* add version 1.7.4 to r-shiny
* add version 1.9.0 to r-signac
* add version 1.6.0.3 to r-smoof
* add version 0.1.7-1 to r-sourcetools
* add version 1.6-0 to r-sp
* add version 1.3-0 to r-spacetime
* add version 7.3-16 to r-spatial
* add version 2.0-0 to r-spatialeco
* add version 1.2-8 to r-spatialreg
* add version 3.0-5 to r-spatstat
* add version 3.0-1 to r-spatstat-data
* add version 3.1-0 to r-spatstat-explore
* add version 3.1-0 to r-spatstat-geom
* add version 3.1-0 to r-spatstat-linnet
* add version 3.1-4 to r-spatstat-random
* add version 3.0-1 to r-spatstat-sparse
* add version 3.0-2 to r-spatstat-utils
* add version 2.2.2 to r-spdata
* add version 1.2-8 to r-spdep
* add version 0.6-1 to r-stars
* add version 1.5.0 to r-statmod
* add version 4.8.0 to r-statnet-common
* add version 1.7.12 to r-stringi
* add version 1.5.0 to r-stringr
* add version 1.9.1 to r-styler
* add version 3.5-5 to r-survival
* add version 1.5-4 to r-tclust
* add version 1.7-29 to r-terra
* add version 3.1.7 to r-testthat
* add version 1.1-2 to r-th-data
* add version 1.2 to r-tictoc
* add version 1.3.2 to r-tidycensus
* add version 1.2.3 to r-tidygraph
* add version 1.3.0 to r-tidyr
* add version 2.0.0 to r-tidyverse
* add version 0.2.0 to r-timechange
* add version 0.45 to r-tinytex
* add version 0.4.1 to r-triebeard
* add version 1.0-9 to r-truncnorm
* add version 0.10-53 to r-tseries
* add version 0.8-1 to r-units
* add version 4.3.0 to r-v8
* add version 1.4-11 to r-vcd
* add version 1.14.0 to r-vcfr
* add version 0.6.2 to r-vctrs
* add version 1.1-8 to r-vgam
* add version 0.4.0 to r-vioplot
* add version 1.6.1 to r-vroom
* add version 1.72-1 to r-wgcna
* add version 0.4.1 to r-whisker
* add version 0.7.2 to r-wk
* add version 0.39 to r-xfun
* add version 1.7.5.1 to r-xgboost
* add version 1.0.7 to r-xlconnect
* add version 3.99-0.14 to r-xml
* add version 0.13.1 to r-xts
* add version 2.3.7 to r-yaml
* add version 2.3.0 to r-zip
* add version 1.8-12 to r-zoo
* r-bigmem: dependency on uuid
* r-bio3d: dependency on zlib
* r-devtools: dependency cleanup
* r-dose: dependency cleanup
* r-dss: dependency cleanup
* r-enrichplot: dependency cleanup
* r-fgsea: dependency cleanup
* r-geor: dependency cleanup
* r-ggridges: dependency cleanup
* r-lobstr: dependency cleanup
* r-lubridate: dependency cleanup
* r-mnormt: dependency cleanup
* r-sctransform: version format correction
* r-seuratobject: dependency cleanup
* r-tidyselect: dependency cleanup
* r-tweenr: dependency cleanup
* r-uwot: dependency cleanup
* new package: r-clock
* new package: r-conflicted
* new package: r-diagram
* new package: r-doby
* new package: r-httr2
* new package: r-kableextra
* new package: r-mclogit
* new package: r-memisc
* new package: r-spatstat-model
* r-rmysql: use mariadb-client
* r-snpstats: add zlib dependency
* r-qs: add zstd dependency
* r-rcppcnpy: add zlib dependency
* black reformatting
* Revert "r-dose: dependency cleanup"
  This reverts commit 4c8ae8f5615ee124fff01ce43eddd3bb5d06b9bc.
* Revert "r-dss: dependency cleanup"
  This reverts commit a6c5c15c617a9a688fdcfe2b70c501c3520d4706.
* Revert "r-enrichplot: dependency cleanup"
  This reverts commit 65e116c18a94d885bc1a0ae667c1ef07d1fe5231.
* Revert "r-fgsea: dependency cleanup"
  This reverts commit ffe2cdcd1f73f69d66167b941970ede0281b56d7.
* r-rda: this package is back in CRAN
* r-sctransform: fix copyright
* r-seurat: fix copyright
* r-seuratobject: fix copyright
* Revert "add version 6.0-94 to r-caret"
  This reverts commit 236260597de97a800bfc699aec1cd1d0e3d1ac60.
* add version 6.0-94 to r-caret
* Revert "add version 1.8.5 to r-emmeans"
  This reverts commit 64a129beb0bd88d5c88fab564cade16c03b956ec.
* add version 1.8.5 to r-emmeans
* Revert "add version 5.0-1 to r-hmisc"
  This reverts commit 517643f4fd8793747365dfcfc264b894d2f783bd.
* add version 5.0-1 to r-hmisc
* Revert "add version 1.42 to r-knitr"
  This reverts commit 2a0d9a4c1f0ba173f7423fed59ba725bac902c37.
* add version 1.42 to r-knitr
* Revert "add version 1.6 to r-markdown"
  This reverts commit 4b5565844b5704559b819d2e775fe8dec625af99.
* add version 1.6 to r-markdown
* Revert "add version 0.26 to r-nmf"
  This reverts commit 4c44a788b17848f2cda67b32312a342c0261caec.
* add version 0.26 to r-nmf
* Revert "add version 2.3.1 to r-rsqlite"
  This reverts commit 5722ee2297276e4db8beee461d39014b0b17e420.
* add version 2.3.1 to r-rsqlite
* Revert "add version 1.0-12 to r-sf"
  This reverts commit ee1734fd62cc02ca7a9359a87ed734f190575f69.
* add version 1.0-12 to r-sf
* fix syntax error
2023-05-18 09:57:43 -07:00
Cameron Stanavige
2e2515266d unifyfs: new v1.1 release (#37756)
Add v1.1 release
Update mochi-margo dependency compatible versions
Update version range of libfabric conflict
2023-05-18 09:42:27 -07:00
Chris Green
776ab13276 [xrootd] New variants, new version, improve build config (#37682)
* Add FNAL Spack team to maintainers

* New variants and configuration improvements

* Version dependent "no-systemd" patches.

* New variants `client_only`, and `davix`

* Better handling of `cxxstd` for different versions, including
  improved patching and CMake options.

* Version-specific CMake requirements.

* Better version-specific handling of `openssl` dependency.

* `py-setuptools` required for `+python` build.

* Specific enable/disable of CMake options and use of
  `-DFORCE_ENABLED=TRUE` to prevent unwanted/non-portable activation
  of features.

* Better handling of `+python` configuration.

* New version 5.5.5
2023-05-18 10:49:18 -05:00
Massimiliano Culpo
c2ce9a6d93 Bump Spack version on develop to 0.21.0.dev0 (#37760) 2023-05-18 12:47:55 +02:00
Peter Scheibel
4e3ed56dfa Bugfix: allow preferred new versions from externals (#37747) 2023-05-18 09:40:26 +02:00
Tamara Dahlgren
dcfcc03497 maintainers: switch from list to directive (#37752) 2023-05-17 22:25:57 +00:00
Stephen Sachs
125c20bc06 Add aws-plcuster[-aarch64] stacks (#37627)
Add aws-plcuster[-aarch64] stacks.  These stacks build packages defined in
https://github.com/spack/spack-configs/tree/main/AWS/parallelcluster

They use a custom container from https://github.com/spack/gitlab-runners which
includes necessary ParallelCluster software to link and build as well as an
upstream spack installation with current GCC and dependencies.

Intel and ARM software is installed and used during the build stage but removed
from the buildcache before the signing stage.

Files `configs/linux/{arch}/ci.yaml` select the necessary providers in order to
build for specific architectures (icelake, skylake, neoverse_{n,v}1).
2023-05-17 16:21:10 -06:00
Brian Van Essen
f7696a4480 Added version 1.3.1 (#37735) 2023-05-17 14:51:02 -07:00
Harmen Stoppels
a5d7667cb6 lmod: fix build, bump patch version (#37744) 2023-05-17 13:18:02 -04:00
Massimiliano Culpo
d45818ccff Limit deepcopy to just the initial "all" section (#37718)
Modifications:
- [x] Limit the scope of the deepcopy when initializing module file writers
2023-05-17 10:17:41 -07:00
Scott Wittenburg
bcb7af6eb3 gitlab ci: no copy-only pipelines w/ deprecated config (#37720)
Make it clear that copy-only pipelines are not supported while still
using the deprecated ci config format. Also ensure that the deprecated
stack does not fail on spack pipelines for tags.
2023-05-17 09:46:30 -06:00
Juan Miguel Carceller
f438fb6c79 whizard: build newer versions in parallel (#37422) 2023-05-17 17:15:50 +02:00
Harmen Stoppels
371a8a361a libxcb: depend on python, remove releases that need python 2 (#37698) 2023-05-17 17:05:30 +02:00
Tamara Dahlgren
86b9ce1c88 spack test: fix stand-alone test suite status reporting (#37602)
* Fix reporting of packageless specs as having no tests

* Add test_test_output_multiple_specs with update to simple-standalone-test (and tests)

* Refactored test status summary; added more tests or checks
2023-05-17 16:03:21 +02:00
Seth R. Johnson
05232034f5 celeritas: new version 0.2.2 (#37731)
* celeritas: new version 0.2.2

* [@spackbot] updating style on behalf of sethrj
2023-05-17 05:38:09 -04:00
Peter Scheibel
7a3da0f606 Tk/Tcl packages: speed up file search (#35902) 2023-05-17 09:27:05 +02:00
Yoshiaki Senda
d96406a161 Add recently added Spack Docker Images to documentation (#37732)
Signed-off-by: Yoshiaki Senda <yoshiaki@live.it>
2023-05-17 08:48:27 +02:00
Tamara Dahlgren
ffa5962356 emacs: convert to new stand-alone test process (#37725) 2023-05-17 00:25:35 -04:00
Massimiliano Culpo
67e74da3ba Fix spack find not able to display version ranges in compilers (#37715) 2023-05-17 00:24:38 -04:00
Chris Green
9ee2d79de1 libxpm package: fix RHEL8 build with libintl (#37713)
Set LDFLAGS rather than LDLIBS
2023-05-16 13:32:26 -05:00
John W. Parent
79e4a13eee Windows: fix MSVC version handling (#37711)
MSVC compiler logic was using string parsing to extract version
from compiler spec, which was fragile. This broke in #37572, so has
been fixed and made more robust by using attribute access.
2023-05-16 11:00:55 -07:00
kwryankrattiger
4627438373 CI: Expand E4S ROCm stack to include missing DaV packages (#36843)
* CI: Expand E4S ROCm stack to include missing DaV packages

Ascent: Fixup for VTK-m with Kokkos backend

* DaV SDK: Removed duplicated openmp variant for ascent

* Drop visit and add conflict for Kokkos

* E4S: Drop ascent from CUDA builds
2023-05-16 09:34:52 -05:00
Harmen Stoppels
badaaf7092 gha rhel8-platform-python: configure git safe.directory (#37708) 2023-05-16 16:31:13 +02:00
Harmen Stoppels
815ac000cc Revert "hdf5: fix showconfig (#34920)" (#37707)
This reverts commit 192e564e26.
2023-05-16 15:57:15 +02:00
Peter Scheibel
7bc5b26c52 Requirements and preferences should not define (non-git) versions (#37687)
Ensure that requirements `packages:*:require:@x` and preferences `packages:*:version:[x]`
fail concretization when no version defined in the package satisfies `x`. This always holds
except for git versions -- they are defined on the fly.
2023-05-16 15:45:11 +02:00
Harmen Stoppels
a0e7ca94b2 gha bootstrap-dev-rhel8: configure git safe.directory (#37702)
git has been updated to something more recent
2023-05-16 15:21:42 +02:00
Harmen Stoppels
e56c90d839 check_modules_set_name: do not check for "enable" key (#37701) 2023-05-16 11:51:52 +02:00
Ye Luo
54003d4d72 Update llvm recipe regarding libomptarget. (#36675) 2023-05-16 11:20:02 +02:00
QuellynSnead
c47b554fa1 libxcb/xcb-proto: Enable internal Python dependency (#37575)
In the past, Spack did not allow two different versions of the
same package within a DAG. That led to difficulties with packages
that still required Python 2 while other packages had already
switched to Python 3.

The libxcb and xcb-proto packages did not have Python 3 support
for a time. To get around this issue, Spack maintainers disabled
their dependency on an internal (i.e., Spack-provided) Python
(see #4145),forcing these packages to look for a system-provided
Python (see #7646).

This has worked for us all right, but with the arrival of our most
recent platform we seem to be missing the critical xcbgen Python
module on the system. Since most software has largely moved on to
Python 3 now, let's re-enable internal Spack dependencies for the
libxcb and xcb-proto packages.
2023-05-16 10:00:01 +02:00
Mikael Simberg
b027f64a7f Add conflict for pika with fmt@10 and +cuda/rocm (#37679) 2023-05-16 09:24:02 +02:00
Greg Becker
3765a5f7f8 unify: when_possible and unify: true -- Bugfix for error in 37438 (#37681)
Two bugs came in from #37438

1. `unify: when_possible` was broken, because of an incorrect assertion. abstract/concrete
   spec pairs were compared against the results that were in the process of being computed,
   rather than against the previous results.
2. `unify: true` had an ordering bug that could mix the association between abstract and
   concrete specs

- [x] 1 is resolved by creating a lookup from old concrete specs to old abstract specs,
      and we use that to associate the "new" concrete specs that happen to be the old
      ones with their abstract specs (since those are stripped out for concretization
- [x] 2 is resolved by combining the new and old abstract as lists instead of combining
      them as sets. This is important because `set() | set()` does not make any ordering
      promises, even though set ordering is otherwise guaranteed in `python@3.7:`
2023-05-16 01:08:34 -04:00
Robert Blake
690661eadd Upgrading kosh to 3.0 (#37471)
* Upgrading kosh to 3.0.

* Accidentally regressed the package, changing back.

* Updating py-hdbscan versions for kosh.

* Fixing bug in patch.

* Adding 3.0.1

* Removing 3.0.

* Updating package deps for hdbscan to match requirements.txt.

* Version reqs for 3.0.*, need newer numpy and networkx

* spack style

* Reordering to match setup.py, adding "type" to python depends.
2023-05-16 01:08:20 -04:00
eugeneswalker
f7bbc326e4 trilinos: @develop fixes (#37615)
* trilinos@develop fixes

* Update var/spack/repos/builtin/packages/trilinos/package.py

Co-authored-by: Seth R. Johnson <johnsonsr@ornl.gov>

---------

Co-authored-by: Seth R. Johnson <johnsonsr@ornl.gov>
2023-05-15 17:25:14 -07:00
Scott Wittenburg
a184bfc1a6 gitlab ci: reduce job name length of build_systems pipeline (#37686) 2023-05-16 00:26:37 +02:00
Alec Scott
81634440fb circos: add v0.69-9 (#37479) 2023-05-15 14:43:44 -07:00
Alec Scott
711d7683ac alluxio: add v2.9.3 (#37488) 2023-05-15 14:42:48 -07:00
Alec Scott
967356bcf5 codec2: add v1.1.0 (#37480) 2023-05-15 14:42:08 -07:00
Alec Scott
c006ed034a coinutils: add v2.11.9 (#37481) 2023-05-15 14:41:25 -07:00
Alec Scott
d065c65d94 g2c: add v1.7.0 (#37482) 2023-05-15 14:40:41 -07:00
Alec Scott
e23c372ff1 shadow: add v4.13 (#37485) 2023-05-15 14:38:32 -07:00
Alec Scott
25d2de5629 yoda: add v1.9.8 (#37487) 2023-05-15 14:37:31 -07:00
Alec Scott
d73a23ce35 cpp-httplib: add v0.12.3 (#37490) 2023-05-15 14:35:32 -07:00
Alec Scott
a62cb3c0f4 entt: add v3.11.1 (#37491) 2023-05-15 14:34:47 -07:00
Alec Scott
177da4595e harfbuzz: add v7.2.0 (#37492) 2023-05-15 14:34:06 -07:00
Alec Scott
e4f05129fe libconfuse: add v3.3 (#37493) 2023-05-15 14:33:19 -07:00
Alec Scott
c25b994917 libnsl: add v2.0.0 (#37494) 2023-05-15 14:32:49 -07:00
Alec Scott
95c4c5270a p11-kit: add v0.24.1 (#37495) 2023-05-15 14:31:43 -07:00
Alec Scott
1cf6a15a08 packmol: add v20.0.0 (#37496)
* packmol: add v20.0.0
* Fix zoltan homepage url
2023-05-15 14:29:01 -07:00
Alec Scott
47d206611a perl-module-build-tiny: add v0.044 (#37497) 2023-05-15 14:25:53 -07:00
Alec Scott
a6789cf653 zoltan: add v3.901 (#37498) 2023-05-15 14:25:00 -07:00
Alec Scott
933cd858e0 bdii: add v6.0.1 (#37499) 2023-05-15 14:24:14 -07:00
Alec Scott
8856361076 audit-userspace: add v3.1.1 (#37505) 2023-05-15 14:15:48 -07:00
Alec Scott
d826df7ef6 babl: add v0.1.106 (#37506) 2023-05-15 14:15:28 -07:00
Alec Scott
d8a9b42da6 actsvg: add v0.4.33 (#37503) 2023-05-15 14:14:45 -07:00
Alec Scott
7d926f86e8 bat: add v0.23.0 (#37507) 2023-05-15 14:09:51 -07:00
Alec Scott
1579544d57 beast-tracer: add v1.7.2 (#37508) 2023-05-15 14:09:18 -07:00
Alec Scott
1cee3fb4a5 cronie: add v1.6.1 (#37509) 2023-05-15 14:08:41 -07:00
Alec Scott
a8e2ad53dd cups: add v2.3.3 (#37510) 2023-05-15 14:08:09 -07:00
Alec Scott
6821fa7246 diamond: add v2.1.6 (#37511) 2023-05-15 14:07:31 -07:00
Alec Scott
09c68da1bd dust: add v0.8.6 (#37513) 2023-05-15 14:06:31 -07:00
Alec Scott
73064d62cf f3d: add v2.0.0 (#37514) 2023-05-15 14:05:37 -07:00
Alec Scott
168ed2a782 fullock: add v1.0.50 (#37515) 2023-05-15 14:02:36 -07:00
Alec Scott
9f60b29495 graphviz: add v8.0.5 (#37517) 2023-05-15 14:00:50 -07:00
Alec Scott
7abcd78426 krakenuniq: add v1.0.4 (#37519) 2023-05-15 13:59:15 -07:00
Alec Scott
d5295301de libfyaml: add v0.8 (#37520) 2023-05-15 13:58:13 -07:00
Alec Scott
beccc49b81 libluv: add v1.44.2-1 (#37522) 2023-05-15 13:55:57 -07:00
Alec Scott
037e7ffe33 libvterm: add v0.3.1 (#37524) 2023-05-15 13:54:15 -07:00
Alec Scott
293da8ed20 lighttpd: add v1.4.69 (#37525) 2023-05-15 13:53:30 -07:00
Alec Scott
2780ab2f6c mrchem: add v1.1.2 (#37526) 2023-05-15 13:51:54 -07:00
Alec Scott
1ed3c81b58 mutationpp: add v1.0.5 (#37527) 2023-05-15 13:50:48 -07:00
Alec Scott
50ce0a25b2 preseq: add v2.0.3 (#37528) 2023-05-15 13:49:47 -07:00
Alec Scott
d784227603 shtools: add v4.10.2 (#37530) 2023-05-15 13:47:15 -07:00
Alec Scott
ab9ed91539 tig: add v2.5.8 (#37531) 2023-05-15 13:46:03 -07:00
Alec Scott
421256063e trimgalore: add v0.6.9 (#37532) 2023-05-15 13:44:44 -07:00
Alec Scott
75459bc70c vdt: add v0.4.4 (#37533) 2023-05-15 13:43:40 -07:00
Carson Woods
33752eabb8 Improve package source code context display on error (#37655)
Spack displays package code context when it shouldn't (e.g., on `FetchError`s)
and doesn't display it when it should (e.g., when errors occur in builder classes.
The line attribution can sometimes be off by one, as well.

- [x] Display package context when errors occur in a subclass of `PackageBase`
- [x] Display package context when errors occur in a subclass of `BaseBuilder`
- [x] Do not display package context when errors occur in `PackageBase`,
      `BaseBuilder` or other core code that is not in a `package.py` file.
- [x] Fix off-by-one error for core code (don't subtract one from the line number *unless*
      it's in an actual `package.py` file.

---------

Co-authored-by: Todd Gamblin <tgamblin@llnl.gov>
2023-05-15 13:38:11 -07:00
Alec Scott
f1d1bb9167 gsl-lite: add v0.41.0 (#37483) 2023-05-15 13:36:03 -07:00
Alec Scott
68eaff24b0 crtm-fix: correct invalid checksum for v2.4.0 (#37500) 2023-05-15 13:34:32 -07:00
Alec Scott
862024cae1 dos2unix: add v7.4.4 (#37512) 2023-05-15 13:31:19 -07:00
Adam J. Stewart
9d6bcd67c3 Update PyTorch ecosystem (#37562) 2023-05-15 13:29:44 -07:00
Chris White
d97ecfe147 SUNDIALS: new version of sundials and guard against examples being install (#37576)
* add new version of sundials and guard against examples not installing
* fix flipping of variant
* fix directory not being there when writing a file
2023-05-15 13:21:37 -07:00
Alec Scott
0d991de50a subversion: add v1.14.2 (#37543) 2023-05-15 13:16:04 -07:00
Alec Scott
4f278a0255 go: add v1.20.4 (#37660)
* go: add v1.20.4
* Deprecate v1.20.2 and v1.19.7 due to CVE-2023-24538
2023-05-15 13:10:02 -07:00
Chris Green
6e72a3cff1 [davix] Enable third party copies with gSOAP (#37648)
* [davix] Enable third party copies with gSOAP

* Add FNAL Spack team to maintainers
2023-05-15 14:46:52 -05:00
snehring
1532c77ce6 micromamba: adding version 1.4.2 (#37594)
* micromamba: adding version 1.4.2
* micromamba: change to micromamba-1.4.2 tag artifacts
2023-05-15 10:40:54 -07:00
Mikael Simberg
5ffbce275c Add ut (#37603) 2023-05-15 10:35:55 -07:00
Carsten Uphoff
0e2ff2dddb Add double-batched FFT library v0.4.0 (#37616)
Signed-off-by: Carsten Uphoff <carsten.uphoff@intel.com>
2023-05-15 10:28:52 -07:00
Mikael Simberg
c0c446a095 stdexec: Add 23.03 (#37638) 2023-05-15 10:20:12 -07:00
snehring
33dbd44449 tmscore: adding new package (#37644) 2023-05-15 10:17:50 -07:00
Sean Koyama
7b0979c1e9 hwloc: explicitly disable building netloc for ~netloc (#35604)
* hwloc: explicitly disable building netloc for ~netloc

* hwloc: update syntax for netloc variant configure argument

---------

Co-authored-by: Sean Koyama <skoyama@anl.gov>
2023-05-15 12:16:21 -05:00
snehring
c9849dd41d tmalign: new version 20220412 (#37645) 2023-05-15 10:14:58 -07:00
Chris Green
d44e97d3f2 [scitokens-cpp] New variant cxxstd, depend on standalone jwt-cpp (#37643)
* Add FNAL Spack team to maintainers
* New variant `cxxstd`
* Depend on `jwt-cpp`
* New versions: 0.7.2, 0.7.3
2023-05-15 13:08:00 -04:00
Adam J. Stewart
8713ab0f67 py-timm: add v0.9 (#37654)
* py-timm: add v0.9
* add v0.9.1 and v0.9.2
* add new package py-safetensors (v0.3.1)
2023-05-15 09:41:58 -07:00
Harmen Stoppels
6a47339bf8 oneapi: before script load modules (#37678) 2023-05-15 18:39:58 +02:00
Alec Scott
1c0fb6d641 amrfinder: add v3.11.8 (#37656) 2023-05-15 09:38:29 -07:00
Alec Scott
b45eee29eb canal: add v1.1.6 (#37657) 2023-05-15 09:36:17 -07:00
Alec Scott
6d26274459 code-server: add v4.12.0 (#37658) 2023-05-15 09:35:17 -07:00
Alec Scott
2fb07de7bc fplll: add v5.4.4 (#37659) 2023-05-15 09:34:13 -07:00
Alec Scott
7678dc6b49 iso-codes: add v4.15.0 (#37661) 2023-05-15 09:27:05 -07:00
Frank Willmore
1944dd55a7 Update package.py for maker (#37662) 2023-05-15 09:25:43 -07:00
Adam J. Stewart
0b6c724743 py-sphinx: add v7.0.1 (#37665) 2023-05-15 09:23:22 -07:00
eugeneswalker
fa98023375 new pkg: py-psana (#37666) 2023-05-15 09:19:54 -07:00
Todd Gamblin
e79a911bac bugfix: allow reuse of packages from foreign namespaces
We currently throw a nasty error if you try to reuse packages from some other namespace
(e.g., OLCF), but we should be able to reuse patched local versions of builtin packages.

Right now the only obstacle to that is that we try to look up virtual info for unknown
namespaces, and we can't get the package from the repo to do that. We *can* assume that
a package with a known namespace is similar, and that its virtual provider information
is reasonably accurate, so we now do that. This isn't 100% accurate, but neither is
relying on the package itself, as it may have gone out of date.

The real solution here is virtual edge information, but this is a stopgap until we have
that.
2023-05-15 09:15:49 -07:00
Todd Gamblin
fd3efc71fd bugfix: don't look up virtual information for unknown packages
`spec_clauses()` attempts to look up package information for concrete specs in order to
determine which virtuals they may provide. This fails for renamed/deleted dependencies
of buildcaches and installed packages.

This will eventually be fixed by #35258, which adds virtual information on edges, but we
need a workaround to make older buildcaches usable.

- [x] make an exception for renamed packages and omit their virtual constraints
- [x] add a note that this will be solved by adding virtuals to edges
2023-05-15 09:15:49 -07:00
Todd Gamblin
0458de18de bugfix: don't look up patches from packages for concrete specs
The concretizer can fail with `reuse:true` if a buildcache or installation contains a
package with a dependency that has been renamed or deleted in the main repo (e.g.,
`netcdf` was refactored to `netcdf-c`, `netcdf-fortran`, etc., but there are still
binary packages with dependencies called `netcdf`).

We should still be able to install things for which we are missing `package.py` files.

`Spec.inject_patches_variant()` was failing this requirement by attempting to look up
the package class for concrete specs.  This isn't needed -- we can skip it.

- [x] swap two conditions in `Spec.inject_patches_variant()`
2023-05-15 09:15:49 -07:00
Vanessasaurus
f94ac8c770 add new package flux-security (#37668)
I will follow this up with a variant to flux-core to add flux-security, and then automation in the flux-framework/spack repository.

Signed-off-by: vsoch <vsoch@users.noreply.github.com>
Co-authored-by: vsoch <vsoch@users.noreply.github.com>
2023-05-15 09:14:44 -07:00
Andrew W Elble
a03c28a916 routinator: update, deprecate old version (#37676) 2023-05-15 09:10:40 -07:00
Victor Lopez Herrero
7b7fdf27f3 dlb: add v3.3 (#37677) 2023-05-15 09:08:57 -07:00
Sergey Kosukhin
192e564e26 hdf5: fix showconfig (#34920)
Co-authored-by: Bernhard Kaindl <43588962+bernhardkaindl@users.noreply.github.com>
2023-05-15 11:03:03 -05:00
Chris Green
b8c5099cde [jwt-cpp] New package (#37641)
* [jwt-cpp] New package

* Update homepage

Co-authored-by: Wouter Deconinck <wdconinc@gmail.com>

* [@spackbot] updating style on behalf of greenc-FNAL

---------

Co-authored-by: Wouter Deconinck <wdconinc@gmail.com>
Co-authored-by: greenc-FNAL <greenc-FNAL@users.noreply.github.com>
2023-05-15 10:16:11 -05:00
Stephen Sachs
ea5bca9067 palace: add v0.11.1 and explicit BLAS support (#37605) 2023-05-15 16:11:50 +02:00
Harmen Stoppels
e33eafd34f Bump tutorial command (#37674) 2023-05-15 13:54:52 +02:00
Xavier Delaruelle
e1344b5497 environment-modules: add version 5.3.0 (#37671) 2023-05-15 09:32:53 +02:00
Todd Gamblin
cf9dc3fc81 spack find: get rid of @= in arch/compiler headers (#37672)
The @= in `spack find` output adds a bit of noise. Remove it as we
did for `spack spec` and `spack concretize`.

This modifies display_specs so it actually covers other places we use that routine, as
well, e.g., `spack buildcache list`.

before:

```
-- linux-ubuntu20.04-aarch64 / gcc@=11.1.0 -----------------------
ofdlcpi libpressio@0.88.0
```

after:

```
-- linux-ubuntu20.04-aarch64 / gcc@11.1.0 -----------------------
ofdlcpi libpressio@0.88.0
```
2023-05-15 09:08:50 +02:00
Bruno Turcksin
d265dd2487 Kokkos: add new release and new architectures (#37650) 2023-05-14 13:21:40 -07:00
Greg Becker
a2a6e65e27 concretizer: don't change concrete environments without --force (#37438)
If a user does not explicitly `--force` the concretization of an entire environment,
Spack will try to reuse the concrete specs that are already in the lockfile.

---------

Co-authored-by: becker33 <becker33@users.noreply.github.com>
Co-authored-by: Todd Gamblin <tgamblin@llnl.gov>
2023-05-14 13:36:03 +02:00
Paul R. C. Kent
0085280db8 gcc: add 12.3.0 (#37553) 2023-05-14 12:08:41 +02:00
Andrew W Elble
6e07bf149d freecad: new package w/ dependencies/updates (#37557)
* freecad: new package w/ dependencies/updates

* review

* symbols/debug variants only when autotools
2023-05-13 21:14:50 -05:00
dale-mittleman
811cd5e7ef Adding librdkafka versions 1.9.2, 2.0.2 (#37501)
Co-authored-by: Alec Scott <hi@alecbcs.com>
2023-05-13 16:00:12 -07:00
Adam J. Stewart
081e21f55e py-lightly: py-torch~distributed supported in next release (#37558) 2023-05-13 15:49:45 -07:00
Todd Gamblin
c5a24675a1 spack spec: remove noisy @= from output (#37663)
@= is accurate, but noisy. Other UI commands tend not to
print the redundant `@=` for known concrete versions;
make `spack spec` consistent with them.
2023-05-13 11:34:15 -07:00
eugeneswalker
e9bfe5cd35 new pkg: py-psmon (#37652) 2023-05-13 11:16:44 -07:00
eugeneswalker
ca84c96478 new pkg: py-psalg (#37653) 2023-05-13 09:02:57 -07:00
Chris Green
c9a790bce9 [gsoap] New package gSOAP (#37647) 2023-05-13 11:01:50 -05:00
eugeneswalker
91c5b4aeb0 e4s ci stacks: add: hdf5-vol-{log,cache} (#37651) 2023-05-13 04:54:44 +00:00
Larry Knox
c2968b4d8c Add HDF5 version 1.14.1 (#37579)
* Add HDF5 version 1.14.1
* Update to version HDF5 1.14.1-2.
2023-05-12 20:54:08 -04:00
Scott Wittenburg
c08be95d5e gitlab ci: release fixes and improvements (#37601)
* gitlab ci: release fixes and improvements

  - use rules to reduce boilerplate in .gitlab-ci.yml
  - support copy-only pipeline jobs
  - make pipelines for release branches rebuild everything
  - make pipelines for protected tags copy-only

* gitlab ci: remove url changes used in testing

* gitlab ci: tag mirrors need public key

Make sure that mirrors associated with release branches and tags
contain the public key needed to verify the signed binaries.  This
also ensures that when stack-specific mirror contents are copied
to the root, the root mirror has the public key as well.

* review: be more specific about tags, curl flags

* Make the check in ci.yaml consistent with the .gitlab-ci.yml

---------

Co-authored-by: Ryan Krattiger <ryan.krattiger@kitware.com>
2023-05-12 15:22:42 -05:00
Lehman Garrison
4e5fb62679 py-asdf: add 2.15.0 and dependencies (#37642)
* py-asdf: add 2.15.0 and dependencies

* py-asdf: PR review
2023-05-12 15:35:22 -04:00
Adam J. Stewart
cafc21c43d py-lightly: add v1.4.5 (#37625) 2023-05-12 11:39:03 -07:00
Adam J. Stewart
72699b43ab py-dill: add v0.3.1.1 (#37415) 2023-05-12 11:37:51 -07:00
MatthewLieber
6c85f59a89 Osu/mvapich2.3.7 1 (#37636)
* add 3.0b release

* adding mvapich2 version 2.3.7-1

---------

Co-authored-by: Matt Lieber <lieber.31@osu.edu>
2023-05-12 11:30:05 -07:00
Nathan Hanford
eef2536055 Allow buildcache specs to be referenced by hash (#35042)
Currently, specs on buildcache mirrors must be referenced by their full description. This PR allows buildcache specs to be referenced by their hashes, rather than their full description.

### How it works

Hash resolution has been moved from `SpecParser` into `Spec`, and now includes the ability to execute a `BinaryCacheQuery` after checking the local store, but before concluding that the hash doesn't exist.

### Side-effects of Proposed Changes

Failures will take longer when nonexistent hashes are parsed, as mirrors will now be scanned.

### Other Changes

- `BinaryCacheIndex.update` has been modified to fail appropriately only when mirrors have been configured.
- Tests of hash failures have been updated to use `mutable_empty_config` so they don't needlessly search mirrors.
- Documentation has been clarified for `BinaryCacheQuery`, and more documentation has been added to the hash resolution functions added to `Spec`.
2023-05-12 10:27:42 -07:00
Massimiliano Culpo
e2ae60a3b0 Update archspec to v0.2.1 (#37633) 2023-05-12 18:59:58 +02:00
Chris Green
d942fd62b5 [root] New version 6.28.04 with C++20 support (#37640)
* Add FNAL Spack team to maintainers.
* New version 6.28/04.
* Support C++20 with ROOT >= 6.28.04.
2023-05-12 09:50:48 -07:00
Andrey Parfenov
99d511d3b0 Add more variants for STREAM to customize build (#37283)
* Added STREAM builds customization

* Changed stream_type to enum

* fix code style issues

Signed-off-by: Andrey Parfenov <andrey.parfenov@intel.com>

* rm not necessary optimization

Signed-off-by: Andrey Parfenov <andrey.parfenov@intel.com>

---------

Signed-off-by: Andrey Parfenov <andrey.parfenov@intel.com>
Co-authored-by: iermolae <igor.ermolaev@intel.com>
2023-05-12 12:17:59 -04:00
Adam J. Stewart
ab8661533b GDAL: add v3.7.0 (#37598) 2023-05-12 12:13:10 -04:00
Robert Cohn
f423edd526 intel-oneapi-mkl: support gnu openmp (#37637)
* intel-oneapi-mkl: support gnu openmp

* intel-oneapi-mkl: support gnu openmp
2023-05-12 12:03:19 -04:00
Manuela Kuhn
0a4d4da5ce py-rsatoolbox: add 0.0.5, 0.1.0 and 0.1.2 (#37595)
* py-rsatoolbox: add 0.0.5, 0.1.0 and 0.1.2 from wheels

* py-setuptools: add 63.4.3

* remove wheels and open up requirements

* Fix style

* Update var/spack/repos/builtin/packages/py-rsatoolbox/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Update var/spack/repos/builtin/packages/py-rsatoolbox/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Change version for python restriction

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-12 10:32:12 -05:00
Manuela Kuhn
845187f270 py-mne: add 1.4.0 and py-importlib-resources: add 5.12.0 (#37624)
* py-mne: add 1.4.0 and py-importlib-resources: add 5.12.0

* Fix style

* Update var/spack/repos/builtin/packages/py-mne/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-12 10:31:35 -05:00
Lehman Garrison
9b35c3cdcc Update tensorflow variant defaults to match upstream defaults (#37610)
* Update tensorflow variant defaults to match project's defaults

* Apply code style
2023-05-12 10:27:51 -05:00
Robert Cohn
fe8734cd52 Fix logic in setting oneapi microarchitecture flags (#37634) 2023-05-12 10:58:08 -04:00
Chris Green
40b1aa6b67 [geant4,geant4-data] New version 10.7.4 (#37382) 2023-05-12 15:20:50 +01:00
Eduardo Rothe
ced8ce6c34 cudnn: add versions 8.5.0, 8.6.0, 8.7.0 (#35998) 2023-05-12 07:38:11 -04:00
Tamara Dahlgren
9201b66792 AML: Convert to new stand-alone test process (#35701) 2023-05-12 13:22:11 +02:00
Massimiliano Culpo
fd45839c04 Improve error message for buildcaches (#37626) 2023-05-12 11:55:13 +02:00
Mikael Simberg
2e25db0755 Add pika 0.15.1 (#37628) 2023-05-12 11:45:30 +02:00
Massimiliano Culpo
ebfc706c8c Improve error messages when Spack finds a too new DB / lockfile (#37614)
This PR ensures that we'll get a comprehensible error message whenever an old
version of Spack tries to use a DB or a lockfile that is "too new".

* Fix error message when using a too new DB
* Add a unit-test to ensure we have a comprehensible error message
2023-05-12 08:13:10 +00:00
Steven R. Brandt
644a10ee35 Coastal Codes (#37176)
* Coastal codes installation
* Finished debugging swan.
* Fix formatting errors identified by flake8
* Another attempt to fix formatting.
* Fixed year in header.
* Fixed maintainers syntax and other details from review comments.
* Remove redundant url.

---------

Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>
2023-05-12 00:57:59 -04:00
snehring
bb96e4c9cc py-pysam: adding version 0.21.0 (#37623)
* py-pysam: adding version 0.21.0

* Update var/spack/repos/builtin/packages/py-pysam/package.py

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

---------

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
2023-05-12 00:47:53 -04:00
Tamara Dahlgren
d204a08aea Install/update the qt dependency (#37600) 2023-05-11 22:58:33 -05:00
Tamara Dahlgren
8e18297cf2 Environments: store spack version/commit in spack.lock (#32801)
Add a section to the lock file to track the Spack version/commit that produced
an environment. This should (eventually) enhance reproducibility, though we
do not currently do anything with the information. It just adds to provenance
at the moment.

Changes include:
- [x] adding the version/commit to `spack.lock`
- [x] refactor `spack.main.get_version()
- [x] fix a couple of environment lock file-related typos
2023-05-11 23:13:36 -04:00
MatthewLieber
b06d20be19 add 3.0b release (#37599)
Co-authored-by: Matt Lieber <lieber.31@osu.edu>
2023-05-11 17:10:15 -07:00
Alec Scott
a14d6fe56d gegl: add v0.4.44 (#37516) 2023-05-11 15:52:22 -07:00
eugeneswalker
47ec6a6ae5 e4s ci: trilinos +rocm: enable belos to fix build failure (#37617) 2023-05-11 14:02:20 -07:00
Massimiliano Culpo
5c7dda7e14 Allow using -j to control the parallelism of concretization (#37608)
fixes #29464

This PR allows to use
```
$ spack concretize -j X
```
to set a cap on the parallelism of concretization from the command line
2023-05-11 13:29:17 -07:00
Dom Heinzeller
0e87243284 libpng package: fix build error on macOS arm64 (#37613)
Turn off ARM NEON support on MacOS arm64

Co-authored-by: Stephen Herbener <stephen.herbener@gmail.com>
2023-05-11 16:27:43 -04:00
Nichols A. Romero
384f5f9960 Update Intel Pin package up to 3.27 (#37470) 2023-05-11 19:06:03 +02:00
Andrey Parfenov
c0f020d021 add openmp_max_threads variant and enable avx 512 optimizations for icelake (#37379)
* add openmp_max_threads variant and enable avx 512 optimizations for icelake and cascadelake

Signed-off-by: Andrey Parfenov <andrey.parfenov@intel.com>

* revert manual enabling of avx512 for icelake and cascadelake

Signed-off-by: Andrey Parfenov <andrey.parfenov@intel.com>

---------

Signed-off-by: Andrey Parfenov <andrey.parfenov@intel.com>
2023-05-11 09:23:04 -05:00
Tamara Dahlgren
dc58449bbf caliper: convert to new stand-alone test process (#35691) 2023-05-11 14:40:02 +02:00
Tamara Dahlgren
d8a72b68dd bricks: convert to new stand-alone test process (#35694) 2023-05-11 14:39:09 +02:00
Mosè Giordano
040c6e486e julia: Fix llvm shlib symbol version for v1.9 (#37606) 2023-05-11 08:22:40 -04:00
Harmen Stoppels
4fa7880b19 lmod: fix CompilerSpec concrete version / range (#37604) 2023-05-11 12:00:07 +02:00
Nisarg Patel
f090b05346 Update providers of virtual packages related to Intel OneAPI (#37412)
* add a virtual dependency name instead of complete package name

* add OneAPI components as providers of virtual packages

* Revert the default of tbb

---------

Co-authored-by: Nisarg Patel <nisarg.patel@lrz.de>
2023-05-11 05:58:24 -04:00
Mikael Simberg
0c69e5a442 Add fmt 10.0.0 (#37591) 2023-05-11 04:57:47 -04:00
Massimiliano Culpo
8da29d1231 Improve the message for errors in package recipes (#37589)
fixes #30355
2023-05-11 10:34:39 +02:00
Massimiliano Culpo
297329f4b5 Improve error message for missing "command" entry in containerize (#37590)
fixes #21242
2023-05-11 10:33:51 +02:00
Mosè Giordano
1b6621a14b julia: Add v1.9.0 (#35631) 2023-05-11 10:30:52 +02:00
Peter Scheibel
bfa54da292 Allow clingo to enforce flags when they appear in requirements (#37584)
Flags are encoded differently from other variants, and they need a choice rule to
ensure clingo has a choice to impose (or not) a constraint.
2023-05-11 09:17:16 +02:00
Jaelyn Litzinger
730ab1574f Upgrade exago's petsc dependency to v3.19.0 (#37092)
* add petsc 3.19 for exago@develop
* simplify version syntax
2023-05-10 18:25:11 -07:00
Harmen Stoppels
2c17c4e632 ci: remove --mirror-url flag (#37457)
The flags --mirror-name / --mirror-url / --directory were deprecated in 
favor of just passing a positional name, url or directory, and letting spack
figure it out.

---------

Co-authored-by: Scott Wittenburg <scott.wittenburg@kitware.com>
2023-05-10 16:34:29 -06:00
John W. Parent
ec800cccbb Windows: Fix external detection for service accounts (#37293)
Prior to this PR, the HOMEDRIVE environment variable was used to
detect what drive we are operating in. This variable is not available
for service account logins (like what is used for CI), so switch to
extracting the drive from PROGRAMFILES (which is more-widely defined).
2023-05-10 18:12:58 -04:00
John W. Parent
85cc9097cb Windows: prefer Python decompression support (#36507)
On Windows, several commonly available system tools for decompression
are unreliable (gz/bz2/xz). This commit refactors `decompressor_for`
to call out to a Windows or Unix-specific method:

* The decompressor_for_nix method behaves the same as before and
  generally treats the Python/system support options for decompression
  as interchangeable (although avoids using Python's built-in tar
  support since that has had issues with permissions).
* The decompressor_for_win method can only use Python support for
  gz/bz2/xz, although for a tar.gz it does use system support for
  untar (after the decompression step). .zip uses the system tar
  utility, and .Z depends on external support (i.e. that the user
  has installed 7zip).

A naming scheme has been introduced for the various _decompression
methods:

* _system_gunzip means to use a system tool (and fail if it's not
    available)
* _py_gunzip means to use Python's built-in support for decompressing
    .gzip files (and fail if it's not available)
* _gunzip is a method that can do either
2023-05-10 18:07:56 -04:00
snehring
830ee6a1eb py-gtdbtk: adding version 2.3.0 (#37581)
* py-gtdbtk: adding version 2.3.0

* py-gtdbtk: adding missing pydantic dep

* py-gtdbtk: restrict pydantic dep
2023-05-10 16:58:42 -05:00
Alec Scott
0da7b83d0b fd: merge fd-find with fd (#37580) 2023-05-10 14:29:13 -07:00
SoniaScard
f51a4a1ae1 Ophidia-analytics-framework, ophidia-io-server: Work (#36801)
* ophidia-io-server: new package at v1.7
* ophidia-io-server: Fix package
* ophidia-analytics-framework: new package at v1.7
* Fix code style in ophidia-analytics-framework
* Merge
* ophidia-analytics-framework: update package to v1.7.3
* Update package.py
* Fix style

---------

Co-authored-by: SoniaScard <SoniaScard@users.noreply.github.com>
Co-authored-by: Donatello Elia <eldoo@users.noreply.github.com>
2023-05-10 08:38:43 -07:00
H. Joe Lee
e49f10a28e fix(hdf5): h5pfc link failure (#37468)
* fix(hdf5): h5pfc link failure
  develop branch doesn't need linking any more.
  See: acb186f6e5
* [@spackbot] updating style on behalf of hyoklee

---------

Co-authored-by: hyoklee <hyoklee@users.noreply.github.com>
2023-05-10 08:33:27 -07:00
Harmen Stoppels
1d96fdc74a Fix compiler version issues (concrete vs range) (#37572) 2023-05-10 17:26:22 +02:00
Robert Cohn
8eb1829554 intel-oneapi-mkl: add threading support (#37586) 2023-05-10 10:47:57 -04:00
matteo-chesi
e70755f692 cuda: add versions 12.0.1, 12.1.0 and 12.1.1 (#37083) 2023-05-10 15:31:07 +02:00
G-Ragghianti
ebb40ee0d1 New option "--first" for "spack location" (#36283) 2023-05-10 12:26:29 +02:00
Robert Cohn
a2ea30aceb Create include/lib in prefix for oneapi packages (#37552) 2023-05-10 06:25:00 -04:00
Tamara Dahlgren
9a37c8fcb1 Stand-alone testing: make recipe support and processing spack-/pytest-like (#34236)
This is a refactor of Spack's stand-alone test process to be more spack- and pytest-like. 

It is more spack-like in that test parts are no longer "hidden" in a package's run_test()
method and pytest-like in that any package method whose name starts test_ 
(i.e., a "test" method) is a test part. We also support the ability to embed test parts in a
test method when that makes sense.

Test methods are now implicit test parts. The docstring is the purpose for the test part. 
The name of the method is the name of the test part. The working directory is the active
spec's test stage directory. You can embed test parts using the test_part context manager.

Functionality added by this commit:
* Adds support for multiple test_* stand-alone package test methods, each of which is 
   an implicit test_part for execution and reporting purposes;
* Deprecates package use of run_test();
* Exposes some functionality from run_test() as optional helper methods;
* Adds a SkipTest exception that can be used to flag stand-alone tests as being skipped;
* Updates the packaging guide section on stand-alone tests to provide more examples;
* Restores the ability to run tests "inherited" from provided virtual packages;
* Prints the test log path (like we currently do for build log paths);
* Times and reports the post-install process (since it can include post-install tests);
* Corrects context-related error message to distinguish test recipes from build recipes.
2023-05-10 11:34:54 +02:00
Alec Scott
49677b9be5 squashfs-mount: add v0.4.0 (#37478) 2023-05-10 10:49:21 +02:00
Alec Scott
6fc44eb540 shared-mime-info: add v1.10 (#37477) 2023-05-10 10:49:00 +02:00
Alec Scott
234febe545 kinesis: add v2.4.8 (#37476) 2023-05-10 10:48:44 +02:00
Alec Scott
83a1245bfd unifdef: add v2.12 (#37456) 2023-05-10 10:48:20 +02:00
Alec Scott
241c37fcf7 conmon: add v2.1.7 (#37320) 2023-05-10 10:47:54 +02:00
Alec Scott
a8114ec52c runc: add v1.1.6 (#37308) 2023-05-10 10:47:44 +02:00
Manuela Kuhn
f92b5d586f py-datalad: add 0.18.3 (#37411)
* py-datalad: add 0.18.3

* [@spackbot] updating style on behalf of manuelakuhn

* Remove metadata variant

* Fix dependencies

* Remove redundant version restriction
2023-05-10 03:57:59 -04:00
Alec Scott
492d68c339 r-knitr: add v1.42 (#37203) 2023-05-09 17:43:58 -05:00
Alec Scott
2dcc55d6c5 ssht: add v1.5.2 (#37542) 2023-05-09 11:37:40 -07:00
eugeneswalker
dc897535df py-loguru: add v0.2.5, v0.3.0 (#37574)
* py-loguru: add v0.2.5

* py-loguru: add v0.3.0
2023-05-09 11:16:02 -07:00
kwryankrattiger
45e1d3498c CI: Backwards compatibility requires script override behavior (#37015) 2023-05-09 10:42:06 -06:00
eugeneswalker
af0f094292 memkind: parallel = false (#37566) 2023-05-09 09:04:54 -07:00
Alec Scott
44b51acb7b z-checker: add v0.9.0 (#37534) 2023-05-09 06:52:43 -07:00
eugeneswalker
13dd05e5ec hip: get_paths for hipify-clang (#37559)
* hip: get_paths for hipify-clang

* fix: need to actually use get_paths now to get hipify-clang path

* set hipify-clang path differentluy for external vs spack-installed case

* [@spackbot] updating style on behalf of eugeneswalker
2023-05-09 06:51:04 -07:00
Massimiliano Culpo
89520467e0 Use single quotes to inline manifest in Dockerfiles (#37571)
fixes #22341

Using double quotes creates issues with shell variable substitutions,
in particular when the manifest has "definitions:" in it. Use single
quotes instead.
2023-05-09 13:20:25 +02:00
Harmen Stoppels
9e1440ec7b spack view copy: relocate symlinks (#32306) 2023-05-09 12:17:16 +02:00
Alec Scott
71cd94e524 gh: add conflict for v2.28.0 and macos (#37563) 2023-05-09 08:55:54 +02:00
Alec Scott
ba696de71b breseq: add v0.38.1 (#37535) 2023-05-08 14:39:45 -07:00
Alec Scott
06b63cfce3 exiv2: add v0.27.6 (#37536) 2023-05-08 14:25:11 -07:00
Alec Scott
5be1e6e852 hazelcast: add v5.2.3 (#37537) 2023-05-08 14:22:46 -07:00
Alec Scott
e651c2b122 libjpeg-turbo: add v2.1.5 (#37539) 2023-05-08 14:19:24 -07:00
Alec Scott
ec2a4869ef mlst: add v2.23.0 (#37540) 2023-05-08 14:03:57 -07:00
Alec Scott
082fb1f6e9 scitokens-cpp: add v1.0.1 (#37541) 2023-05-08 14:00:33 -07:00
Alec Scott
95a65e85df delta: add v2.3.0 (#37545) 2023-05-08 13:46:08 -07:00
Alec Scott
d9e7aa4253 fd-find: add v8.7.0 (#37547) 2023-05-08 13:43:13 -07:00
Alec Scott
5578209117 druid: add v1.2.8 (#37546) 2023-05-08 13:42:10 -07:00
Alec Scott
b013a2de50 fd-find: add v8.7.0 (#37547) 2023-05-08 13:28:50 -07:00
Mark W. Krentel
d1c722a49c hpcviewer: add version 2023.04 (#37556) 2023-05-08 12:30:10 -07:00
eugeneswalker
3446feff70 use latest trilinos for +cuda variants (#37164) 2023-05-08 12:29:54 -07:00
eugeneswalker
41afeacaba new package: psalg (#37357)
* new package: psalg

* use new maintainer syntax

Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>

---------

Co-authored-by: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>
2023-05-08 12:26:19 -07:00
1120 changed files with 13580 additions and 5529 deletions

View File

@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2 - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # @v2 - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # @v2
with: with:
python-version: ${{inputs.python_version}} python-version: ${{inputs.python_version}}
- name: Install Python packages - name: Install Python packages
@@ -38,7 +38,7 @@ jobs:
run: | run: |
. share/spack/setup-env.sh . share/spack/setup-env.sh
$(which spack) audit packages $(which spack) audit packages
- uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 # @v2.1.0 - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # @v2.1.0
if: ${{ inputs.with_coverage == 'true' }} if: ${{ inputs.with_coverage == 'true' }}
with: with:
flags: unittests,linux,audits flags: unittests,linux,audits

View File

@@ -0,0 +1,31 @@
name: Windows Paraview Nightly
on:
schedule:
- cron: '0 2 * * *' # Run at 2 am
defaults:
run:
shell:
powershell Invoke-Expression -Command "./share/spack/qa/windows_test_setup.ps1"; {0}
jobs:
build-paraview-deps:
runs-on: windows-latest
steps:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
with:
fetch-depth: 0
- uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0
with:
python-version: 3.9
- name: Install Python packages
run: |
python -m pip install --upgrade pip six pywin32 setuptools coverage
- name: Build Test
run: |
spack compiler find
spack external find cmake ninja win-sdk win-wdk wgl msmpi
spack -d install -y --cdash-upload-url https://cdash.spack.io/submit.php?project=Spack+on+Windows --cdash-track Nightly --only dependencies paraview
exit 0

View File

@@ -50,7 +50,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2 - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # @v2 - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # @v2
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Install System packages - name: Install System packages
@@ -87,7 +87,7 @@ jobs:
UNIT_TEST_COVERAGE: ${{ matrix.python-version == '3.11' }} UNIT_TEST_COVERAGE: ${{ matrix.python-version == '3.11' }}
run: | run: |
share/spack/qa/run-unit-tests share/spack/qa/run-unit-tests
- uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
with: with:
flags: unittests,linux,${{ matrix.concretizer }} flags: unittests,linux,${{ matrix.concretizer }}
# Test shell integration # Test shell integration
@@ -97,7 +97,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2 - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # @v2 - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # @v2
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install System packages - name: Install System packages
@@ -118,7 +118,7 @@ jobs:
COVERAGE: true COVERAGE: true
run: | run: |
share/spack/qa/run-shell-tests share/spack/qa/run-shell-tests
- uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
with: with:
flags: shelltests,linux flags: shelltests,linux
@@ -137,6 +137,7 @@ jobs:
- name: Setup repo and non-root user - name: Setup repo and non-root user
run: | run: |
git --version git --version
git config --global --add safe.directory /__w/spack/spack
git fetch --unshallow git fetch --unshallow
. .github/workflows/setup_git.sh . .github/workflows/setup_git.sh
useradd spack-test useradd spack-test
@@ -154,7 +155,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2 - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # @v2 - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # @v2
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install System packages - name: Install System packages
@@ -175,7 +176,7 @@ jobs:
SPACK_TEST_SOLVER: clingo SPACK_TEST_SOLVER: clingo
run: | run: |
share/spack/qa/run-unit-tests share/spack/qa/run-unit-tests
- uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 # @v2.1.0 - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # @v2.1.0
with: with:
flags: unittests,linux,clingo flags: unittests,linux,clingo
# Run unit tests on MacOS # Run unit tests on MacOS
@@ -188,7 +189,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2 - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # @v2 - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # @v2
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Install Python packages - name: Install Python packages
@@ -210,6 +211,6 @@ jobs:
$(which spack) solve zlib $(which spack) solve zlib
common_args=(--dist loadfile --tx '4*popen//python=./bin/spack-tmpconfig python -u ./bin/spack python' -x) common_args=(--dist loadfile --tx '4*popen//python=./bin/spack-tmpconfig python -u ./bin/spack python' -x)
$(which spack) unit-test --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml "${common_args[@]}" $(which spack) unit-test --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml "${common_args[@]}"
- uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
with: with:
flags: unittests,macos flags: unittests,macos

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2 - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # @v2 - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # @v2
with: with:
python-version: '3.11' python-version: '3.11'
cache: 'pip' cache: 'pip'
@@ -38,7 +38,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2 - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # @v2
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # @v2 - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # @v2
with: with:
python-version: '3.11' python-version: '3.11'
cache: 'pip' cache: 'pip'
@@ -72,6 +72,7 @@ jobs:
- name: Setup repo and non-root user - name: Setup repo and non-root user
run: | run: |
git --version git --version
git config --global --add safe.directory /__w/spack/spack
git fetch --unshallow git fetch --unshallow
. .github/workflows/setup_git.sh . .github/workflows/setup_git.sh
useradd spack-test useradd spack-test

View File

@@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0
with: with:
python-version: 3.9 python-version: 3.9
- name: Install Python packages - name: Install Python packages
@@ -33,7 +33,7 @@ jobs:
./share/spack/qa/validate_last_exit.ps1 ./share/spack/qa/validate_last_exit.ps1
coverage combine -a coverage combine -a
coverage xml coverage xml
- uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
with: with:
flags: unittests,windows flags: unittests,windows
unit-tests-cmd: unit-tests-cmd:
@@ -42,7 +42,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0
with: with:
python-version: 3.9 python-version: 3.9
- name: Install Python packages - name: Install Python packages
@@ -57,7 +57,7 @@ jobs:
./share/spack/qa/validate_last_exit.ps1 ./share/spack/qa/validate_last_exit.ps1
coverage combine -a coverage combine -a
coverage xml coverage xml
- uses: codecov/codecov-action@894ff025c7b54547a9a2a1e9f228beae737ad3c2 - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
with: with:
flags: unittests,windows flags: unittests,windows
build-abseil: build-abseil:
@@ -66,7 +66,7 @@ jobs:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0
with: with:
python-version: 3.9 python-version: 3.9
- name: Install Python packages - name: Install Python packages

View File

@@ -1,3 +1,221 @@
# v0.20.0 (2023-05-21)
`v0.20.0` is a major feature release.
## Features in this release
1. **`requires()` directive and enhanced package requirements**
We've added some more enhancements to requirements in Spack (#36286).
There is a new `requires()` directive for packages. `requires()` is the opposite of
`conflicts()`. You can use it to impose constraints on this package when certain
conditions are met:
```python
requires(
"%apple-clang",
when="platform=darwin",
msg="This package builds only with clang on macOS"
)
```
More on this in [the docs](
https://spack.rtfd.io/en/latest/packaging_guide.html#conflicts-and-requirements).
You can also now add a `when:` clause to `requires:` in your `packages.yaml`
configuration or in an environment:
```yaml
packages:
openmpi:
require:
- any_of: ["%gcc"]
when: "@:4.1.4"
message: "Only OpenMPI 4.1.5 and up can build with fancy compilers"
```
More details can be found [here](
https://spack.readthedocs.io/en/latest/build_settings.html#package-requirements)
2. **Exact versions**
Spack did not previously have a way to distinguish a version if it was a prefix of
some other version. For example, `@3.2` would match `3.2`, `3.2.1`, `3.2.2`, etc. You
can now match *exactly* `3.2` with `@=3.2`. This is useful, for example, if you need
to patch *only* the `3.2` version of a package. The new syntax is described in [the docs](
https://spack.readthedocs.io/en/latest/basic_usage.html#version-specifier).
Generally, when writing packages, you should prefer to use ranges like `@3.2` over
the specific versions, as this allows the concretizer more leeway when selecting
versions of dependencies. More details and recommendations are in the [packaging guide](
https://spack.readthedocs.io/en/latest/packaging_guide.html#ranges-versus-specific-versions).
See #36273 for full details on the version refactor.
3. **New testing interface**
Writing package tests is now much simpler with a new [test interface](
https://spack.readthedocs.io/en/latest/packaging_guide.html#stand-alone-tests).
Writing a test is now as easy as adding a method that starts with `test_`:
```python
class MyPackage(Package):
...
def test_always_fails(self):
"""use assert to always fail"""
assert False
def test_example(self):
"""run installed example"""
example = which(self.prefix.bin.example)
example()
```
You can use Python's native `assert` statement to implement your checks -- no more
need to fiddle with `run_test` or other test framework methods. Spack will
introspect the class and run `test_*` methods when you run `spack test`,
4. **More stable concretization**
* Now, `spack concretize` will *only* concretize the new portions of the environment
and will not change existing parts of an environment unless you specify `--force`.
This has always been true for `unify:false`, but not for `unify:true` and
`unify:when_possible` environments. Now it is true for all of them (#37438, #37681).
* The concretizer has a new `--reuse-deps` argument that *only* reuses dependencies.
That is, it will always treat the *roots* of your environment as it would with
`--fresh`. This allows you to upgrade just the roots of your environment while
keeping everything else stable (#30990).
5. **Weekly develop snapshot releases**
Since last year, we have maintained a buildcache of `develop` at
https://binaries.spack.io/develop, but the cache can grow to contain so many builds
as to be unwieldy. When we get a stable `develop` build, we snapshot the release and
add a corresponding tag the Spack repository. So, you can use a stack from a specific
day. There are now tags in the spack repository like:
* `develop-2023-05-14`
* `develop-2023-05-18`
that correspond to build caches like:
* https://binaries.spack.io/develop-2023-05-14/e4s
* https://binaries.spack.io/develop-2023-05-18/e4s
We plan to store these snapshot releases weekly.
6. **Specs in buildcaches can be referenced by hash.**
* Previously, you could run `spack buildcache list` and see the hashes in
buildcaches, but referring to them by hash would fail.
* You can now run commands like `spack spec` and `spack install` and refer to
buildcache hashes directly, e.g. `spack install /abc123` (#35042)
7. **New package and buildcache index websites**
Our public websites for searching packages have been completely revamped and updated.
You can check them out here:
* *Package Index*: https://packages.spack.io
* *Buildcache Index*: https://cache.spack.io
Both are searchable and more interactive than before. Currently major releases are
shown; UI for browsing `develop` snapshots is coming soon.
8. **Default CMake and Meson build types are now Release**
Spack has historically defaulted to building with optimization and debugging, but
packages like `llvm` can be enormous with debug turned on. Our default build type for
all Spack packages is now `Release` (#36679, #37436). This has a number of benefits:
* much smaller binaries;
* higher default optimization level; and
* defining `NDEBUG` disables assertions, which may lead to further speedups.
You can still get the old behavior back through requirements and package preferences.
## Other new commands and directives
* `spack checksum` can automatically add new versions to package (#24532)
* new command: `spack pkg grep` to easily search package files (#34388)
* New `maintainers` directive (#35083)
* Add `spack buildcache push` (alias to `buildcache create`) (#34861)
* Allow using `-j` to control the parallelism of concretization (#37608)
* Add `--exclude` option to 'spack external find' (#35013)
## Other new features of note
* editing: add higher-precedence `SPACK_EDITOR` environment variable
* Many YAML formatting improvements from updating `ruamel.yaml` to the latest version
supporting Python 3.6. (#31091, #24885, #37008).
* Requirements and preferences should not define (non-git) versions (#37687, #37747)
* Environments now store spack version/commit in `spack.lock` (#32801)
* User can specify the name of the `packages` subdirectory in repositories (#36643)
* Add container images supporting RHEL alternatives (#36713)
* make version(...) kwargs explicit (#36998)
## Notable refactors
* buildcache create: reproducible tarballs (#35623)
* Bootstrap most of Spack dependencies using environments (#34029)
* Split `satisfies(..., strict=True/False)` into two functions (#35681)
* spack install: simplify behavior when inside environments (#35206)
## Binary cache and stack updates
* Major simplification of CI boilerplate in stacks (#34272, #36045)
* Many improvements to our CI pipeline's reliability
## Removals, Deprecations, and disablements
* Module file generation is disabled by default; you'll need to enable it to use it (#37258)
* Support for Python 2 was deprecated in `v0.19.0` and has been removed. `v0.20.0` only
supports Python 3.6 and higher.
* Deprecated target names are no longer recognized by Spack. Use generic names instead:
* `graviton` is now `cortex_a72`
* `graviton2` is now `neoverse_n1`
* `graviton3` is now `neoverse_v1`
* `blacklist` and `whitelist` in module configuration were deprecated in `v0.19.0` and are
removed in this release. Use `exclude` and `include` instead.
* The `ignore=` parameter of the `extends()` directive has been removed. It was not used by
any builtin packages and is no longer needed to avoid conflicts in environment views (#35588).
* Support for the old YAML buildcache format has been removed. It was deprecated in `v0.19.0` (#34347).
* `spack find --bootstrap` has been removed. It was deprecated in `v0.19.0`. Use `spack
--bootstrap find` instead (#33964).
* `spack bootstrap trust` and `spack bootstrap untrust` are now removed, having been
deprecated in `v0.19.0`. Use `spack bootstrap enable` and `spack bootstrap disable`.
* The `--mirror-name`, `--mirror-url`, and `--directory` options to buildcache and
mirror commands were deprecated in `v0.19.0` and have now been removed. They have been
replaced by positional arguments (#37457).
* Deprecate `env:` as top level environment key (#37424)
* deprecate buildcache create --rel, buildcache install --allow-root (#37285)
* Support for very old perl-like spec format strings (e.g., `$_$@$%@+$+$=`) has been
removed (#37425). This was deprecated in in `v0.15` (#10556).
## Notable Bugfixes
* bugfix: don't fetch package metadata for unknown concrete specs (#36990)
* Improve package source code context display on error (#37655)
* Relax environment manifest filename requirements and lockfile identification criteria (#37413)
* `installer.py`: drop build edges of installed packages by default (#36707)
* Bugfix: package requirements with git commits (#35057, #36347)
* Package requirements: allow single specs in requirement lists (#36258)
* conditional variant values: allow boolean (#33939)
* spack uninstall: follow run/link edges on --dependents (#34058)
## Spack community stats
* 7,179 total packages, 499 new since `v0.19.0`
* 329 new Python packages
* 31 new R packages
* 336 people contributed to this release
* 317 committers to packages
* 62 committers to core
# v0.19.1 (2023-02-07) # v0.19.1 (2023-02-07)
### Spack Bugfixes ### Spack Bugfixes

View File

@@ -20,7 +20,7 @@ packages:
awk: [gawk] awk: [gawk]
blas: [openblas, amdblis] blas: [openblas, amdblis]
D: [ldc] D: [ldc]
daal: [intel-daal] daal: [intel-oneapi-daal]
elf: [elfutils] elf: [elfutils]
fftw-api: [fftw, amdfftw] fftw-api: [fftw, amdfftw]
flame: [libflame, amdlibflame] flame: [libflame, amdlibflame]
@@ -30,7 +30,7 @@ packages:
golang: [go, gcc] golang: [go, gcc]
go-or-gccgo-bootstrap: [go-bootstrap, gcc] go-or-gccgo-bootstrap: [go-bootstrap, gcc]
iconv: [libiconv] iconv: [libiconv]
ipp: [intel-ipp] ipp: [intel-oneapi-ipp]
java: [openjdk, jdk, ibm-java] java: [openjdk, jdk, ibm-java]
jpeg: [libjpeg-turbo, libjpeg] jpeg: [libjpeg-turbo, libjpeg]
lapack: [openblas, amdlibflame] lapack: [openblas, amdlibflame]
@@ -40,7 +40,7 @@ packages:
lua-lang: [lua, lua-luajit-openresty, lua-luajit] lua-lang: [lua, lua-luajit-openresty, lua-luajit]
luajit: [lua-luajit-openresty, lua-luajit] luajit: [lua-luajit-openresty, lua-luajit]
mariadb-client: [mariadb-c-client, mariadb] mariadb-client: [mariadb-c-client, mariadb]
mkl: [intel-mkl] mkl: [intel-oneapi-mkl]
mpe: [mpe2] mpe: [mpe2]
mpi: [openmpi, mpich] mpi: [openmpi, mpich]
mysql-client: [mysql, mariadb-c-client] mysql-client: [mysql, mariadb-c-client]

View File

@@ -217,6 +217,7 @@ def setup(sphinx):
# Spack classes that intersphinx is unable to resolve # Spack classes that intersphinx is unable to resolve
("py:class", "spack.version.StandardVersion"), ("py:class", "spack.version.StandardVersion"),
("py:class", "spack.spec.DependencySpec"), ("py:class", "spack.spec.DependencySpec"),
("py:class", "spack.install_test.Pb"),
] ]
# The reST default role (used for this markup: `text`) to use for all documents. # The reST default role (used for this markup: `text`) to use for all documents.

View File

@@ -143,6 +143,26 @@ The OS that are currently supported are summarized in the table below:
* - Amazon Linux 2 * - Amazon Linux 2
- ``amazonlinux:2`` - ``amazonlinux:2``
- ``spack/amazon-linux`` - ``spack/amazon-linux``
* - AlmaLinux 8
- ``almalinux:8``
- ``spack/almalinux8``
* - AlmaLinux 9
- ``almalinux:9``
- ``spack/almalinux9``
* - Rocky Linux 8
- ``rockylinux:8``
- ``spack/rockylinux8``
* - Rocky Linux 9
- ``rockylinux:9``
- ``spack/rockylinux9``
* - Fedora Linux 37
- ``fedora:37``
- ``spack/fedora37``
* - Fedora Linux 38
- ``fedora:38``
- ``spack/fedora38``
All the images are tagged with the corresponding release of Spack: All the images are tagged with the corresponding release of Spack:

View File

@@ -347,7 +347,7 @@ the Environment and then install the concretized specs.
(see :ref:`build-jobs`). To speed up environment builds further, independent (see :ref:`build-jobs`). To speed up environment builds further, independent
packages can be installed in parallel by launching more Spack instances. For packages can be installed in parallel by launching more Spack instances. For
example, the following will build at most four packages in parallel using example, the following will build at most four packages in parallel using
three background jobs: three background jobs:
.. code-block:: console .. code-block:: console
@@ -395,7 +395,7 @@ version (and other constraints) passed as the spec argument to the
For packages with ``git`` attributes, git branches, tags, and commits can For packages with ``git`` attributes, git branches, tags, and commits can
also be used as valid concrete versions (see :ref:`version-specifier`). also be used as valid concrete versions (see :ref:`version-specifier`).
This means that for a package ``foo``, ``spack develop foo@git.main`` will clone This means that for a package ``foo``, ``spack develop foo@git.main`` will clone
the ``main`` branch of the package, and ``spack install`` will install from the ``main`` branch of the package, and ``spack install`` will install from
that git clone if ``foo`` is in the environment. that git clone if ``foo`` is in the environment.
Further development on ``foo`` can be tested by reinstalling the environment, Further development on ``foo`` can be tested by reinstalling the environment,
@@ -589,10 +589,11 @@ user support groups providing a large software stack for their HPC center.
.. admonition:: Re-concretization of user specs .. admonition:: Re-concretization of user specs
When using *unified* concretization (when possible), the entire set of specs will be The ``spack concretize`` command without additional arguments will *not* change any
re-concretized after any addition of new user specs, to ensure that previously concretized specs. This may prevent it from finding a solution when using
the environment remains consistent / minimal. When instead unified concretization is ``unify: true``, and it may prevent it from finding a minimal solution when using
disabled, only the new specs will be concretized after any addition. ``unify: when_possible``. You can force Spack to ignore the existing concrete environment
with ``spack concretize -f``.
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
Spec Matrices Spec Matrices
@@ -1121,19 +1122,19 @@ index once every package is pushed. Note how this target uses the generated
SPACK ?= spack SPACK ?= spack
BUILDCACHE_DIR = $(CURDIR)/tarballs BUILDCACHE_DIR = $(CURDIR)/tarballs
.PHONY: all .PHONY: all
all: push all: push
include env.mk include env.mk
example/push/%: example/install/% example/push/%: example/install/%
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
$(info About to push $(SPEC) to a buildcache) $(info About to push $(SPEC) to a buildcache)
$(SPACK) -e . buildcache create --allow-root --only=package --directory $(BUILDCACHE_DIR) /$(HASH) $(SPACK) -e . buildcache create --allow-root --only=package --directory $(BUILDCACHE_DIR) /$(HASH)
@touch $@ @touch $@
push: $(addprefix example/push/,$(example/SPACK_PACKAGE_IDS)) push: $(addprefix example/push/,$(example/SPACK_PACKAGE_IDS))
$(info Updating the buildcache index) $(info Updating the buildcache index)
$(SPACK) -e . buildcache update-index --directory $(BUILDCACHE_DIR) $(SPACK) -e . buildcache update-index --directory $(BUILDCACHE_DIR)

View File

@@ -317,7 +317,7 @@ installed, but you know that new compilers have been added to your
.. code-block:: console .. code-block:: console
$ module load gcc-4.9.0 $ module load gcc/4.9.0
$ spack compiler find $ spack compiler find
==> Added 1 new compiler to ~/.spack/linux/compilers.yaml ==> Added 1 new compiler to ~/.spack/linux/compilers.yaml
gcc@4.9.0 gcc@4.9.0

View File

@@ -35,27 +35,27 @@ showing lots of installed packages:
$ module avail $ module avail
--------------------------------------------------------------- ~/spack/share/spack/modules/linux-ubuntu14-x86_64 --------------------------------------------------------------- --------------------------------------------------------------- ~/spack/share/spack/modules/linux-ubuntu14-x86_64 ---------------------------------------------------------------
autoconf-2.69-gcc-4.8-qextxkq hwloc-1.11.6-gcc-6.3.0-akcisez m4-1.4.18-gcc-4.8-ev2znoc openblas-0.2.19-gcc-6.3.0-dhkmed6 py-setuptools-34.2.0-gcc-6.3.0-fadur4s autoconf/2.69-gcc-4.8-qextxkq hwloc/1.11.6-gcc-6.3.0-akcisez m4/1.4.18-gcc-4.8-ev2znoc openblas/0.2.19-gcc-6.3.0-dhkmed6 py-setuptools/34.2.0-gcc-6.3.0-fadur4s
automake-1.15-gcc-4.8-maqvukj isl-0.18-gcc-4.8-afi6taq m4-1.4.18-gcc-6.3.0-uppywnz openmpi-2.1.0-gcc-6.3.0-go2s4z5 py-six-1.10.0-gcc-6.3.0-p4dhkaw automake/1.15-gcc-4.8-maqvukj isl/0.18-gcc-4.8-afi6taq m4/1.4.18-gcc-6.3.0-uppywnz openmpi/2.1.0-gcc-6.3.0-go2s4z5 py-six/1.10.0-gcc-6.3.0-p4dhkaw
binutils-2.28-gcc-4.8-5s7c6rs libiconv-1.15-gcc-4.8-at46wg3 mawk-1.3.4-gcc-4.8-acjez57 openssl-1.0.2k-gcc-4.8-dkls5tk python-2.7.13-gcc-6.3.0-tyehea7 binutils/2.28-gcc-4.8-5s7c6rs libiconv/1.15-gcc-4.8-at46wg3 mawk/1.3.4-gcc-4.8-acjez57 openssl/1.0.2k-gcc-4.8-dkls5tk python/2.7.13-gcc-6.3.0-tyehea7
bison-3.0.4-gcc-4.8-ek4luo5 libpciaccess-0.13.4-gcc-6.3.0-gmufnvh mawk-1.3.4-gcc-6.3.0-ostdoms openssl-1.0.2k-gcc-6.3.0-gxgr5or readline-7.0-gcc-4.8-xhufqhn bison/3.0.4-gcc-4.8-ek4luo5 libpciaccess/0.13.4-gcc-6.3.0-gmufnvh mawk/1.3.4-gcc-6.3.0-ostdoms openssl/1.0.2k-gcc-6.3.0-gxgr5or readline/7.0-gcc-4.8-xhufqhn
bzip2-1.0.6-gcc-4.8-iffrxzn libsigsegv-2.11-gcc-4.8-pp2cvte mpc-1.0.3-gcc-4.8-g5mztc5 pcre-8.40-gcc-4.8-r5pbrxb readline-7.0-gcc-6.3.0-zzcyicg bzip2/1.0.6-gcc-4.8-iffrxzn libsigsegv/2.11-gcc-4.8-pp2cvte mpc/1.0.3-gcc-4.8-g5mztc5 pcre/8.40-gcc-4.8-r5pbrxb readline/7.0-gcc-6.3.0-zzcyicg
bzip2-1.0.6-gcc-6.3.0-bequudr libsigsegv-2.11-gcc-6.3.0-7enifnh mpfr-3.1.5-gcc-4.8-o7xm7az perl-5.24.1-gcc-4.8-dg5j65u sqlite-3.8.5-gcc-6.3.0-6zoruzj bzip2/1.0.6-gcc-6.3.0-bequudr libsigsegv/2.11-gcc-6.3.0-7enifnh mpfr/3.1.5-gcc-4.8-o7xm7az perl/5.24.1-gcc-4.8-dg5j65u sqlite/3.8.5-gcc-6.3.0-6zoruzj
cmake-3.7.2-gcc-6.3.0-fowuuby libtool-2.4.6-gcc-4.8-7a523za mpich-3.2-gcc-6.3.0-dmvd3aw perl-5.24.1-gcc-6.3.0-6uzkpt6 tar-1.29-gcc-4.8-wse2ass cmake/3.7.2-gcc-6.3.0-fowuuby libtool/2.4.6-gcc-4.8-7a523za mpich/3.2-gcc-6.3.0-dmvd3aw perl/5.24.1-gcc-6.3.0-6uzkpt6 tar/1.29-gcc-4.8-wse2ass
curl-7.53.1-gcc-4.8-3fz46n6 libtool-2.4.6-gcc-6.3.0-n7zmbzt ncurses-6.0-gcc-4.8-dcpe7ia pkg-config-0.29.2-gcc-4.8-ib33t75 tcl-8.6.6-gcc-4.8-tfxzqbr curl/7.53.1-gcc-4.8-3fz46n6 libtool/2.4.6-gcc-6.3.0-n7zmbzt ncurses/6.0-gcc-4.8-dcpe7ia pkg-config/0.29.2-gcc-4.8-ib33t75 tcl/8.6.6-gcc-4.8-tfxzqbr
expat-2.2.0-gcc-4.8-mrv6bd4 libxml2-2.9.4-gcc-4.8-ryzxnsu ncurses-6.0-gcc-6.3.0-ucbhcdy pkg-config-0.29.2-gcc-6.3.0-jpgubk3 util-macros-1.19.1-gcc-6.3.0-xorz2x2 expat/2.2.0-gcc-4.8-mrv6bd4 libxml2/2.9.4-gcc-4.8-ryzxnsu ncurses/6.0-gcc-6.3.0-ucbhcdy pkg-config/0.29.2-gcc-6.3.0-jpgubk3 util-macros/1.19.1-gcc-6.3.0-xorz2x2
flex-2.6.3-gcc-4.8-yf345oo libxml2-2.9.4-gcc-6.3.0-rltzsdh netlib-lapack-3.6.1-gcc-6.3.0-js33dog py-appdirs-1.4.0-gcc-6.3.0-jxawmw7 xz-5.2.3-gcc-4.8-mew4log flex/2.6.3-gcc-4.8-yf345oo libxml2/2.9.4-gcc-6.3.0-rltzsdh netlib-lapack/3.6.1-gcc-6.3.0-js33dog py-appdirs/1.4.0-gcc-6.3.0-jxawmw7 xz/5.2.3-gcc-4.8-mew4log
gcc-6.3.0-gcc-4.8-24puqve lmod-7.4.1-gcc-4.8-je4srhr netlib-scalapack-2.0.2-gcc-6.3.0-5aidk4l py-numpy-1.12.0-gcc-6.3.0-oemmoeu xz-5.2.3-gcc-6.3.0-3vqeuvb gcc/6.3.0-gcc-4.8-24puqve lmod/7.4.1-gcc-4.8-je4srhr netlib-scalapack/2.0.2-gcc-6.3.0-5aidk4l py-numpy/1.12.0-gcc-6.3.0-oemmoeu xz/5.2.3-gcc-6.3.0-3vqeuvb
gettext-0.19.8.1-gcc-4.8-yymghlh lua-5.3.4-gcc-4.8-im75yaz netlib-scalapack-2.0.2-gcc-6.3.0-hjsemcn py-packaging-16.8-gcc-6.3.0-i2n3dtl zip-3.0-gcc-4.8-rwar22d gettext/0.19.8.1-gcc-4.8-yymghlh lua/5.3.4-gcc-4.8-im75yaz netlib-scalapack/2.0.2-gcc-6.3.0-hjsemcn py-packaging/16.8-gcc-6.3.0-i2n3dtl zip/3.0-gcc-4.8-rwar22d
gmp-6.1.2-gcc-4.8-5ub2wu5 lua-luafilesystem-1_6_3-gcc-4.8-wkey3nl netlib-scalapack-2.0.2-gcc-6.3.0-jva724b py-pyparsing-2.1.10-gcc-6.3.0-tbo6gmw zlib-1.2.11-gcc-4.8-pgxsxv7 gmp/6.1.2-gcc-4.8-5ub2wu5 lua-luafilesystem/1_6_3-gcc-4.8-wkey3nl netlib-scalapack/2.0.2-gcc-6.3.0-jva724b py-pyparsing/2.1.10-gcc-6.3.0-tbo6gmw zlib/1.2.11-gcc-4.8-pgxsxv7
help2man-1.47.4-gcc-4.8-kcnqmau lua-luaposix-33.4.0-gcc-4.8-mdod2ry netlib-scalapack-2.0.2-gcc-6.3.0-rgqfr6d py-scipy-0.19.0-gcc-6.3.0-kr7nat4 zlib-1.2.11-gcc-6.3.0-7cqp6cj help2man/1.47.4-gcc-4.8-kcnqmau lua-luaposix/33.4.0-gcc-4.8-mdod2ry netlib-scalapack/2.0.2-gcc-6.3.0-rgqfr6d py-scipy/0.19.0-gcc-6.3.0-kr7nat4 zlib/1.2.11-gcc-6.3.0-7cqp6cj
The names should look familiar, as they resemble the output from ``spack find``. The names should look familiar, as they resemble the output from ``spack find``.
For example, you could type the following command to load the ``cmake`` module: For example, you could type the following command to load the ``cmake`` module:
.. code-block:: console .. code-block:: console
$ module load cmake-3.7.2-gcc-6.3.0-fowuuby $ module load cmake/3.7.2-gcc-6.3.0-fowuuby
Neither of these is particularly pretty, easy to remember, or easy to Neither of these is particularly pretty, easy to remember, or easy to
type. Luckily, Spack offers many facilities for customizing the module type. Luckily, Spack offers many facilities for customizing the module
@@ -779,35 +779,35 @@ cut-and-pasted into a shell script. For example:
$ spack module tcl loads --dependencies py-numpy git $ spack module tcl loads --dependencies py-numpy git
# bzip2@1.0.6%gcc@4.9.3=linux-x86_64 # bzip2@1.0.6%gcc@4.9.3=linux-x86_64
module load bzip2-1.0.6-gcc-4.9.3-ktnrhkrmbbtlvnagfatrarzjojmkvzsx module load bzip2/1.0.6-gcc-4.9.3-ktnrhkrmbbtlvnagfatrarzjojmkvzsx
# ncurses@6.0%gcc@4.9.3=linux-x86_64 # ncurses@6.0%gcc@4.9.3=linux-x86_64
module load ncurses-6.0-gcc-4.9.3-kaazyneh3bjkfnalunchyqtygoe2mncv module load ncurses/6.0-gcc-4.9.3-kaazyneh3bjkfnalunchyqtygoe2mncv
# zlib@1.2.8%gcc@4.9.3=linux-x86_64 # zlib@1.2.8%gcc@4.9.3=linux-x86_64
module load zlib-1.2.8-gcc-4.9.3-v3ufwaahjnviyvgjcelo36nywx2ufj7z module load zlib/1.2.8-gcc-4.9.3-v3ufwaahjnviyvgjcelo36nywx2ufj7z
# sqlite@3.8.5%gcc@4.9.3=linux-x86_64 # sqlite@3.8.5%gcc@4.9.3=linux-x86_64
module load sqlite-3.8.5-gcc-4.9.3-a3eediswgd5f3rmto7g3szoew5nhehbr module load sqlite/3.8.5-gcc-4.9.3-a3eediswgd5f3rmto7g3szoew5nhehbr
# readline@6.3%gcc@4.9.3=linux-x86_64 # readline@6.3%gcc@4.9.3=linux-x86_64
module load readline-6.3-gcc-4.9.3-se6r3lsycrwxyhreg4lqirp6xixxejh3 module load readline/6.3-gcc-4.9.3-se6r3lsycrwxyhreg4lqirp6xixxejh3
# python@3.5.1%gcc@4.9.3=linux-x86_64 # python@3.5.1%gcc@4.9.3=linux-x86_64
module load python-3.5.1-gcc-4.9.3-5q5rsrtjld4u6jiicuvtnx52m7tfhegi module load python/3.5.1-gcc-4.9.3-5q5rsrtjld4u6jiicuvtnx52m7tfhegi
# py-setuptools@20.5%gcc@4.9.3=linux-x86_64 # py-setuptools@20.5%gcc@4.9.3=linux-x86_64
module load py-setuptools-20.5-gcc-4.9.3-4qr2suj6p6glepnedmwhl4f62x64wxw2 module load py-setuptools/20.5-gcc-4.9.3-4qr2suj6p6glepnedmwhl4f62x64wxw2
# py-nose@1.3.7%gcc@4.9.3=linux-x86_64 # py-nose@1.3.7%gcc@4.9.3=linux-x86_64
module load py-nose-1.3.7-gcc-4.9.3-pwhtjw2dvdvfzjwuuztkzr7b4l6zepli module load py-nose/1.3.7-gcc-4.9.3-pwhtjw2dvdvfzjwuuztkzr7b4l6zepli
# openblas@0.2.17%gcc@4.9.3+shared=linux-x86_64 # openblas@0.2.17%gcc@4.9.3+shared=linux-x86_64
module load openblas-0.2.17-gcc-4.9.3-pw6rmlom7apfsnjtzfttyayzc7nx5e7y module load openblas/0.2.17-gcc-4.9.3-pw6rmlom7apfsnjtzfttyayzc7nx5e7y
# py-numpy@1.11.0%gcc@4.9.3+blas+lapack=linux-x86_64 # py-numpy@1.11.0%gcc@4.9.3+blas+lapack=linux-x86_64
module load py-numpy-1.11.0-gcc-4.9.3-mulodttw5pcyjufva4htsktwty4qd52r module load py-numpy/1.11.0-gcc-4.9.3-mulodttw5pcyjufva4htsktwty4qd52r
# curl@7.47.1%gcc@4.9.3=linux-x86_64 # curl@7.47.1%gcc@4.9.3=linux-x86_64
module load curl-7.47.1-gcc-4.9.3-ohz3fwsepm3b462p5lnaquv7op7naqbi module load curl/7.47.1-gcc-4.9.3-ohz3fwsepm3b462p5lnaquv7op7naqbi
# autoconf@2.69%gcc@4.9.3=linux-x86_64 # autoconf@2.69%gcc@4.9.3=linux-x86_64
module load autoconf-2.69-gcc-4.9.3-bkibjqhgqm5e3o423ogfv2y3o6h2uoq4 module load autoconf/2.69-gcc-4.9.3-bkibjqhgqm5e3o423ogfv2y3o6h2uoq4
# cmake@3.5.0%gcc@4.9.3~doc+ncurses+openssl~qt=linux-x86_64 # cmake@3.5.0%gcc@4.9.3~doc+ncurses+openssl~qt=linux-x86_64
module load cmake-3.5.0-gcc-4.9.3-x7xnsklmgwla3ubfgzppamtbqk5rwn7t module load cmake/3.5.0-gcc-4.9.3-x7xnsklmgwla3ubfgzppamtbqk5rwn7t
# expat@2.1.0%gcc@4.9.3=linux-x86_64 # expat@2.1.0%gcc@4.9.3=linux-x86_64
module load expat-2.1.0-gcc-4.9.3-6pkz2ucnk2e62imwakejjvbv6egncppd module load expat/2.1.0-gcc-4.9.3-6pkz2ucnk2e62imwakejjvbv6egncppd
# git@2.8.0-rc2%gcc@4.9.3+curl+expat=linux-x86_64 # git@2.8.0-rc2%gcc@4.9.3+curl+expat=linux-x86_64
module load git-2.8.0-rc2-gcc-4.9.3-3bib4hqtnv5xjjoq5ugt3inblt4xrgkd module load git/2.8.0-rc2-gcc-4.9.3-3bib4hqtnv5xjjoq5ugt3inblt4xrgkd
The script may be further edited by removing unnecessary modules. The script may be further edited by removing unnecessary modules.
@@ -826,12 +826,12 @@ For example, consider the following on one system:
.. code-block:: console .. code-block:: console
$ module avail $ module avail
linux-SuSE11-x86_64/antlr-2.7.7-gcc-5.3.0-bdpl46y linux-SuSE11-x86_64/antlr/2.7.7-gcc-5.3.0-bdpl46y
$ spack module tcl loads antlr # WRONG! $ spack module tcl loads antlr # WRONG!
# antlr@2.7.7%gcc@5.3.0~csharp+cxx~java~python arch=linux-SuSE11-x86_64 # antlr@2.7.7%gcc@5.3.0~csharp+cxx~java~python arch=linux-SuSE11-x86_64
module load antlr-2.7.7-gcc-5.3.0-bdpl46y module load antlr/2.7.7-gcc-5.3.0-bdpl46y
$ spack module tcl loads --prefix linux-SuSE11-x86_64/ antlr $ spack module tcl loads --prefix linux-SuSE11-x86_64/ antlr
# antlr@2.7.7%gcc@5.3.0~csharp+cxx~java~python arch=linux-SuSE11-x86_64 # antlr@2.7.7%gcc@5.3.0~csharp+cxx~java~python arch=linux-SuSE11-x86_64
module load linux-SuSE11-x86_64/antlr-2.7.7-gcc-5.3.0-bdpl46y module load linux-SuSE11-x86_64/antlr/2.7.7-gcc-5.3.0-bdpl46y

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@
* Homepage: https://pypi.python.org/pypi/archspec * Homepage: https://pypi.python.org/pypi/archspec
* Usage: Labeling, comparison and detection of microarchitectures * Usage: Labeling, comparison and detection of microarchitectures
* Version: 0.2.0-dev (commit d02dadbac4fa8f3a60293c4fbfd59feadaf546dc) * Version: 0.2.1 (commit 9e1117bd8a2f0581bced161f2a2e8d6294d0300b)
astunparse astunparse
---------------- ----------------

View File

@@ -2083,18 +2083,28 @@
"compilers": { "compilers": {
"gcc": [ "gcc": [
{ {
"versions": "10.3:", "versions": "10.3:13.0",
"name": "znver3", "name": "znver3",
"flags": "-march={name} -mtune={name} -mavx512f -mavx512dq -mavx512ifma -mavx512cd -mavx512bw -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512vnni -mavx512bitalg" "flags": "-march={name} -mtune={name} -mavx512f -mavx512dq -mavx512ifma -mavx512cd -mavx512bw -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512vnni -mavx512bitalg"
},
{
"versions": "13.1:",
"name": "znver4",
"flags": "-march={name} -mtune={name}"
} }
], ],
"clang": [ "clang": [
{ {
"versions": "12.0:", "versions": "12.0:15.9",
"name": "znver3", "name": "znver3",
"flags": "-march={name} -mtune={name} -mavx512f -mavx512dq -mavx512ifma -mavx512cd -mavx512bw -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512vnni -mavx512bitalg" "flags": "-march={name} -mtune={name} -mavx512f -mavx512dq -mavx512ifma -mavx512cd -mavx512bw -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512vnni -mavx512bitalg"
},
{
"versions": "16.0:",
"name": "znver4",
"flags": "-march={name} -mtune={name}"
} }
], ],
"aocc": [ "aocc": [
{ {
"versions": "3.0:3.9", "versions": "3.0:3.9",
@@ -2793,7 +2803,7 @@
"flags" : "-march=armv8.2-a+fp16+dotprod+crypto -mtune=cortex-a72" "flags" : "-march=armv8.2-a+fp16+dotprod+crypto -mtune=cortex-a72"
}, },
{ {
"versions": "10.2", "versions": "10.2:10.2.99",
"flags" : "-mcpu=zeus" "flags" : "-mcpu=zeus"
}, },
{ {

View File

@@ -4,7 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
#: PEP440 canonical <major>.<minor>.<micro>.<devN> string #: PEP440 canonical <major>.<minor>.<micro>.<devN> string
__version__ = "0.20.0.dev0" __version__ = "0.21.0.dev0"
spack_version = __version__ spack_version = __version__

View File

@@ -289,9 +289,14 @@ def _check_build_test_callbacks(pkgs, error_cls):
pkg_cls = spack.repo.path.get_pkg_class(pkg_name) pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
test_callbacks = getattr(pkg_cls, "build_time_test_callbacks", None) test_callbacks = getattr(pkg_cls, "build_time_test_callbacks", None)
if test_callbacks and "test" in test_callbacks: # TODO (post-34236): "test*"->"test_*" once remove deprecated methods
msg = '{0} package contains "test" method in ' "build_time_test_callbacks" # TODO (post-34236): "test"->"test_" once remove deprecated methods
instr = 'Remove "test" from: [{0}]'.format(", ".join(test_callbacks)) has_test_method = test_callbacks and any([m.startswith("test") for m in test_callbacks])
if has_test_method:
msg = '{0} package contains "test*" method(s) in ' "build_time_test_callbacks"
instr = 'Remove all methods whose names start with "test" from: [{0}]'.format(
", ".join(test_callbacks)
)
errors.append(error_cls(msg.format(pkg_name), [instr])) errors.append(error_cls(msg.format(pkg_name), [instr]))
return errors return errors

View File

@@ -193,10 +193,17 @@ def _associate_built_specs_with_mirror(self, cache_key, mirror_url):
db_root_dir = os.path.join(tmpdir, "db_root") db_root_dir = os.path.join(tmpdir, "db_root")
db = spack_db.Database(None, db_dir=db_root_dir, enable_transaction_locking=False) db = spack_db.Database(None, db_dir=db_root_dir, enable_transaction_locking=False)
self._index_file_cache.init_entry(cache_key) try:
cache_path = self._index_file_cache.cache_path(cache_key) self._index_file_cache.init_entry(cache_key)
with self._index_file_cache.read_transaction(cache_key): cache_path = self._index_file_cache.cache_path(cache_key)
db._read_from_file(cache_path) with self._index_file_cache.read_transaction(cache_key):
db._read_from_file(cache_path)
except spack_db.InvalidDatabaseVersionError as e:
msg = (
f"you need a newer Spack version to read the buildcache index for the "
f"following mirror: '{mirror_url}'. {e.database_version_message}"
)
raise BuildcacheIndexError(msg) from e
spec_list = db.query_local(installed=False, in_buildcache=True) spec_list = db.query_local(installed=False, in_buildcache=True)
@@ -419,7 +426,7 @@ def update(self, with_cooldown=False):
self._write_local_index_cache() self._write_local_index_cache()
if all_methods_failed: if configured_mirror_urls and all_methods_failed:
raise FetchCacheError(fetch_errors) raise FetchCacheError(fetch_errors)
if fetch_errors: if fetch_errors:
tty.warn( tty.warn(
@@ -2408,6 +2415,10 @@ def __init__(self, all_architectures):
self.possible_specs = specs self.possible_specs = specs
def __call__(self, spec, **kwargs): def __call__(self, spec, **kwargs):
"""
Args:
spec (str): The spec being searched for in its string representation or hash.
"""
matches = [] matches = []
if spec.startswith("/"): if spec.startswith("/"):
# Matching a DAG hash # Matching a DAG hash
@@ -2429,6 +2440,10 @@ def __str__(self):
return "{}, due to: {}".format(self.args[0], self.args[1]) return "{}, due to: {}".format(self.args[0], self.args[1])
class BuildcacheIndexError(spack.error.SpackError):
"""Raised when a buildcache cannot be read for any reason"""
FetchIndexResult = collections.namedtuple("FetchIndexResult", "etag hash data fresh") FetchIndexResult = collections.namedtuple("FetchIndexResult", "etag hash data fresh")

View File

@@ -43,6 +43,7 @@
from typing import List, Tuple from typing import List, Tuple
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.filesystem import join_path
from llnl.util.lang import dedupe from llnl.util.lang import dedupe
from llnl.util.symlink import symlink from llnl.util.symlink import symlink
from llnl.util.tty.color import cescape, colorize from llnl.util.tty.color import cescape, colorize
@@ -53,7 +54,6 @@
import spack.build_systems.python import spack.build_systems.python
import spack.builder import spack.builder
import spack.config import spack.config
import spack.install_test
import spack.main import spack.main
import spack.package_base import spack.package_base
import spack.paths import spack.paths
@@ -66,6 +66,7 @@
import spack.util.path import spack.util.path
import spack.util.pattern import spack.util.pattern
from spack.error import NoHeadersError, NoLibrariesError from spack.error import NoHeadersError, NoLibrariesError
from spack.install_test import spack_install_test_log
from spack.installer import InstallError from spack.installer import InstallError
from spack.util.cpus import cpus_available from spack.util.cpus import cpus_available
from spack.util.environment import ( from spack.util.environment import (
@@ -588,7 +589,6 @@ def set_module_variables_for_package(pkg):
# TODO: make these build deps that can be installed if not found. # TODO: make these build deps that can be installed if not found.
m.make = MakeExecutable("make", jobs) m.make = MakeExecutable("make", jobs)
m.gmake = MakeExecutable("gmake", jobs)
m.ninja = MakeExecutable("ninja", jobs, supports_jobserver=False) m.ninja = MakeExecutable("ninja", jobs, supports_jobserver=False)
# TODO: johnwparent: add package or builder support to define these build tools # TODO: johnwparent: add package or builder support to define these build tools
# for now there is no entrypoint for builders to define these on their # for now there is no entrypoint for builders to define these on their
@@ -1075,19 +1075,18 @@ def _setup_pkg_and_run(
# 'pkg' is not defined yet # 'pkg' is not defined yet
pass pass
elif context == "test": elif context == "test":
logfile = os.path.join( logfile = os.path.join(pkg.test_suite.stage, pkg.test_suite.test_log_name(pkg.spec))
pkg.test_suite.stage, spack.install_test.TestSuite.test_log_name(pkg.spec)
)
error_msg = str(exc) error_msg = str(exc)
if isinstance(exc, (spack.multimethod.NoSuchMethodError, AttributeError)): if isinstance(exc, (spack.multimethod.NoSuchMethodError, AttributeError)):
process = "test the installation" if context == "test" else "build from sources"
error_msg = ( error_msg = (
"The '{}' package cannot find an attribute while trying to build " "The '{}' package cannot find an attribute while trying to {}. "
"from sources. This might be due to a change in Spack's package format " "This might be due to a change in Spack's package format "
"to support multiple build-systems for a single package. You can fix this " "to support multiple build-systems for a single package. You can fix this "
"by updating the build recipe, and you can also report the issue as a bug. " "by updating the {} recipe, and you can also report the issue as a bug. "
"More information at https://spack.readthedocs.io/en/latest/packaging_guide.html#installation-procedure" "More information at https://spack.readthedocs.io/en/latest/packaging_guide.html#installation-procedure"
).format(pkg.name) ).format(pkg.name, process, context)
error_msg = colorize("@*R{{{}}}".format(error_msg)) error_msg = colorize("@*R{{{}}}".format(error_msg))
error_msg = "{}\n\n{}".format(str(exc), error_msg) error_msg = "{}\n\n{}".format(str(exc), error_msg)
@@ -1216,6 +1215,9 @@ def child_fun():
return child_result return child_result
CONTEXT_BASES = (spack.package_base.PackageBase, spack.build_systems._checks.BaseBuilder)
def get_package_context(traceback, context=3): def get_package_context(traceback, context=3):
"""Return some context for an error message when the build fails. """Return some context for an error message when the build fails.
@@ -1244,32 +1246,38 @@ def make_stack(tb, stack=None):
stack = make_stack(traceback) stack = make_stack(traceback)
basenames = tuple(base.__name__ for base in CONTEXT_BASES)
for tb in stack: for tb in stack:
frame = tb.tb_frame frame = tb.tb_frame
if "self" in frame.f_locals: if "self" in frame.f_locals:
# Find the first proper subclass of PackageBase. # Find the first proper subclass of the PackageBase or BaseBuilder, but
# don't provide context if the code is actually in the base classes.
obj = frame.f_locals["self"] obj = frame.f_locals["self"]
if isinstance(obj, spack.package_base.PackageBase): func = getattr(obj, tb.tb_frame.f_code.co_name, "")
if func:
typename, *_ = func.__qualname__.partition(".")
if isinstance(obj, CONTEXT_BASES) and typename not in basenames:
break break
else: else:
return None return None
# We found obj, the Package implementation we care about. # We found obj, the Package implementation we care about.
# Point out the location in the install method where we failed. # Point out the location in the install method where we failed.
lines = [ filename = inspect.getfile(frame.f_code)
"{0}:{1:d}, in {2}:".format( lineno = frame.f_lineno
inspect.getfile(frame.f_code), if os.path.basename(filename) == "package.py":
frame.f_lineno - 1, # subtract 1 because f_lineno is 0-indexed # subtract 1 because we inject a magic import at the top of package files.
frame.f_code.co_name, # TODO: get rid of the magic import.
) lineno -= 1
]
lines = ["{0}:{1:d}, in {2}:".format(filename, lineno, frame.f_code.co_name)]
# Build a message showing context in the install method. # Build a message showing context in the install method.
sourcelines, start = inspect.getsourcelines(frame) sourcelines, start = inspect.getsourcelines(frame)
# Calculate lineno of the error relative to the start of the function. # Calculate lineno of the error relative to the start of the function.
# Subtract 1 because f_lineno is 0-indexed. fun_lineno = lineno - start
fun_lineno = frame.f_lineno - start - 1
start_ctx = max(0, fun_lineno - context) start_ctx = max(0, fun_lineno - context)
sourcelines = sourcelines[start_ctx : fun_lineno + context + 1] sourcelines = sourcelines[start_ctx : fun_lineno + context + 1]
@@ -1360,6 +1368,13 @@ def long_message(self):
out.write("See {0} log for details:\n".format(self.log_type)) out.write("See {0} log for details:\n".format(self.log_type))
out.write(" {0}\n".format(self.log_name)) out.write(" {0}\n".format(self.log_name))
# Also output the test log path IF it exists
if self.context != "test":
test_log = join_path(os.path.dirname(self.log_name), spack_install_test_log)
if os.path.isfile(test_log):
out.write("\nSee test log for details:\n")
out.write(" {0}\n".format(test_log))
return out.getvalue() return out.getvalue()
def __str__(self): def __str__(self):

View File

@@ -108,7 +108,10 @@ def execute_build_time_tests(builder: spack.builder.Builder):
builder: builder prescribing the test callbacks. The name of the callbacks is builder: builder prescribing the test callbacks. The name of the callbacks is
stored as a list of strings in the ``build_time_test_callbacks`` attribute. stored as a list of strings in the ``build_time_test_callbacks`` attribute.
""" """
builder.pkg.run_test_callbacks(builder, builder.build_time_test_callbacks, "build") if not builder.pkg.run_tests or not builder.build_time_test_callbacks:
return
builder.pkg.tester.phase_tests(builder, "build", builder.build_time_test_callbacks)
def execute_install_time_tests(builder: spack.builder.Builder): def execute_install_time_tests(builder: spack.builder.Builder):
@@ -118,7 +121,10 @@ def execute_install_time_tests(builder: spack.builder.Builder):
builder: builder prescribing the test callbacks. The name of the callbacks is builder: builder prescribing the test callbacks. The name of the callbacks is
stored as a list of strings in the ``install_time_test_callbacks`` attribute. stored as a list of strings in the ``install_time_test_callbacks`` attribute.
""" """
builder.pkg.run_test_callbacks(builder, builder.install_time_test_callbacks, "install") if not builder.pkg.run_tests or not builder.install_time_test_callbacks:
return
builder.pkg.tester.phase_tests(builder, "install", builder.install_time_test_callbacks)
class BaseBuilder(spack.builder.Builder): class BaseBuilder(spack.builder.Builder):

View File

@@ -2,6 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import collections.abc
import os import os
from typing import Tuple from typing import Tuple
@@ -13,21 +14,24 @@
from .cmake import CMakeBuilder, CMakePackage from .cmake import CMakeBuilder, CMakePackage
def cmake_cache_path(name, value, comment=""): def cmake_cache_path(name, value, comment="", force=False):
"""Generate a string for a cmake cache variable""" """Generate a string for a cmake cache variable"""
return 'set({0} "{1}" CACHE PATH "{2}")\n'.format(name, value, comment) force_str = " FORCE" if force else ""
return 'set({0} "{1}" CACHE PATH "{2}"{3})\n'.format(name, value, comment, force_str)
def cmake_cache_string(name, value, comment=""): def cmake_cache_string(name, value, comment="", force=False):
"""Generate a string for a cmake cache variable""" """Generate a string for a cmake cache variable"""
return 'set({0} "{1}" CACHE STRING "{2}")\n'.format(name, value, comment) force_str = " FORCE" if force else ""
return 'set({0} "{1}" CACHE STRING "{2}"{3})\n'.format(name, value, comment, force_str)
def cmake_cache_option(name, boolean_value, comment=""): def cmake_cache_option(name, boolean_value, comment="", force=False):
"""Generate a string for a cmake configuration option""" """Generate a string for a cmake configuration option"""
value = "ON" if boolean_value else "OFF" value = "ON" if boolean_value else "OFF"
return 'set({0} {1} CACHE BOOL "{2}")\n'.format(name, value, comment) force_str = " FORCE" if force else ""
return 'set({0} {1} CACHE BOOL "{2}"{3})\n'.format(name, value, comment, force_str)
class CachedCMakeBuilder(CMakeBuilder): class CachedCMakeBuilder(CMakeBuilder):
@@ -63,6 +67,34 @@ def cache_name(self):
def cache_path(self): def cache_path(self):
return os.path.join(self.pkg.stage.source_path, self.cache_name) return os.path.join(self.pkg.stage.source_path, self.cache_name)
# Implement a version of the define_from_variant for Cached packages
def define_cmake_cache_from_variant(self, cmake_var, variant=None, comment=""):
"""Return a Cached CMake field from the given variant's value.
See define_from_variant in lib/spack/spack/build_systems/cmake.py package
"""
if variant is None:
variant = cmake_var.lower()
if variant not in self.pkg.variants:
raise KeyError('"{0}" is not a variant of "{1}"'.format(variant, self.pkg.name))
if variant not in self.pkg.spec.variants:
return ""
value = self.pkg.spec.variants[variant].value
field = None
if isinstance(value, bool):
field = cmake_cache_option(cmake_var, value, comment)
else:
if isinstance(value, collections.abc.Sequence) and not isinstance(value, str):
value = ";".join(str(v) for v in value)
else:
value = str(value)
field = cmake_cache_string(cmake_var, value, comment)
return field
def initconfig_compiler_entries(self): def initconfig_compiler_entries(self):
# This will tell cmake to use the Spack compiler wrappers when run # This will tell cmake to use the Spack compiler wrappers when run
# through Spack, but use the underlying compiler when run outside of # through Spack, but use the underlying compiler when run outside of
@@ -130,6 +162,17 @@ def initconfig_compiler_entries(self):
libs_string = libs_format_string.format(lang) libs_string = libs_format_string.format(lang)
entries.append(cmake_cache_string(libs_string, libs_flags)) entries.append(cmake_cache_string(libs_string, libs_flags))
# Set the generator in the cached config
if self.spec.satisfies("generator=make"):
entries.append(cmake_cache_string("CMAKE_GENERATOR", "Unix Makefiles"))
if self.spec.satisfies("generator=ninja"):
entries.append(cmake_cache_string("CMAKE_GENERATOR", "Ninja"))
entries.append(
cmake_cache_string(
"CMAKE_MAKE_PROGRAM", "{0}/ninja".format(spec["ninja"].prefix.bin)
)
)
return entries return entries
def initconfig_mpi_entries(self): def initconfig_mpi_entries(self):
@@ -195,26 +238,57 @@ def initconfig_hardware_entries(self):
"#------------------{0}\n".format("-" * 60), "#------------------{0}\n".format("-" * 60),
] ]
# Provide standard CMake arguments for dependent CachedCMakePackages
if spec.satisfies("^cuda"): if spec.satisfies("^cuda"):
entries.append("#------------------{0}".format("-" * 30)) entries.append("#------------------{0}".format("-" * 30))
entries.append("# Cuda") entries.append("# Cuda")
entries.append("#------------------{0}\n".format("-" * 30)) entries.append("#------------------{0}\n".format("-" * 30))
cudatoolkitdir = spec["cuda"].prefix cudatoolkitdir = spec["cuda"].prefix
entries.append(cmake_cache_path("CUDA_TOOLKIT_ROOT_DIR", cudatoolkitdir)) entries.append(cmake_cache_path("CUDAToolkit_ROOT", cudatoolkitdir))
cudacompiler = "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" entries.append(cmake_cache_path("CMAKE_CUDA_COMPILER", "${CUDAToolkit_ROOT}/bin/nvcc"))
entries.append(cmake_cache_path("CMAKE_CUDA_COMPILER", cudacompiler))
entries.append(cmake_cache_path("CMAKE_CUDA_HOST_COMPILER", "${CMAKE_CXX_COMPILER}")) entries.append(cmake_cache_path("CMAKE_CUDA_HOST_COMPILER", "${CMAKE_CXX_COMPILER}"))
# Include the deprecated CUDA_TOOLKIT_ROOT_DIR for supporting BLT packages
entries.append(cmake_cache_path("CUDA_TOOLKIT_ROOT_DIR", cudatoolkitdir))
archs = spec.variants["cuda_arch"].value
if archs != "none":
arch_str = ";".join(archs)
entries.append(
cmake_cache_string("CMAKE_CUDA_ARCHITECTURES", "{0}".format(arch_str))
)
if "+rocm" in spec:
entries.append("#------------------{0}".format("-" * 30))
entries.append("# ROCm")
entries.append("#------------------{0}\n".format("-" * 30))
# Explicitly setting HIP_ROOT_DIR may be a patch that is no longer necessary
entries.append(cmake_cache_path("HIP_ROOT_DIR", "{0}".format(spec["hip"].prefix)))
entries.append(
cmake_cache_path("HIP_CXX_COMPILER", "{0}".format(self.spec["hip"].hipcc))
)
archs = self.spec.variants["amdgpu_target"].value
if archs != "none":
arch_str = ";".join(archs)
entries.append(
cmake_cache_string("CMAKE_HIP_ARCHITECTURES", "{0}".format(arch_str))
)
entries.append(cmake_cache_string("AMDGPU_TARGETS", "{0}".format(arch_str)))
entries.append(cmake_cache_string("GPU_TARGETS", "{0}".format(arch_str)))
return entries return entries
def std_initconfig_entries(self): def std_initconfig_entries(self):
cmake_prefix_path_env = os.environ["CMAKE_PREFIX_PATH"]
cmake_prefix_path = cmake_prefix_path_env.replace(os.pathsep, ";")
return [ return [
"#------------------{0}".format("-" * 60), "#------------------{0}".format("-" * 60),
"# !!!! This is a generated file, edit at own risk !!!!", "# !!!! This is a generated file, edit at own risk !!!!",
"#------------------{0}".format("-" * 60), "#------------------{0}".format("-" * 60),
"# CMake executable path: {0}".format(self.pkg.spec["cmake"].command.path), "# CMake executable path: {0}".format(self.pkg.spec["cmake"].command.path),
"#------------------{0}\n".format("-" * 60), "#------------------{0}\n".format("-" * 60),
cmake_cache_path("CMAKE_PREFIX_PATH", cmake_prefix_path),
] ]
def initconfig_package_entries(self): def initconfig_package_entries(self):

View File

@@ -137,11 +137,12 @@ def cuda_flags(arch_list):
conflicts("%gcc@11:", when="+cuda ^cuda@:11.4.0") conflicts("%gcc@11:", when="+cuda ^cuda@:11.4.0")
conflicts("%gcc@11.2:", when="+cuda ^cuda@:11.5") conflicts("%gcc@11.2:", when="+cuda ^cuda@:11.5")
conflicts("%gcc@12:", when="+cuda ^cuda@:11.8") conflicts("%gcc@12:", when="+cuda ^cuda@:11.8")
conflicts("%gcc@13:", when="+cuda ^cuda@:12.0") conflicts("%gcc@13:", when="+cuda ^cuda@:12.1")
conflicts("%clang@12:", when="+cuda ^cuda@:11.4.0") conflicts("%clang@12:", when="+cuda ^cuda@:11.4.0")
conflicts("%clang@13:", when="+cuda ^cuda@:11.5") conflicts("%clang@13:", when="+cuda ^cuda@:11.5")
conflicts("%clang@14:", when="+cuda ^cuda@:11.7") conflicts("%clang@14:", when="+cuda ^cuda@:11.7")
conflicts("%clang@15:", when="+cuda ^cuda@:12.0") conflicts("%clang@15:", when="+cuda ^cuda@:12.0")
conflicts("%clang@16:", when="+cuda ^cuda@:12.1")
# https://gist.github.com/ax3l/9489132#gistcomment-3860114 # https://gist.github.com/ax3l/9489132#gistcomment-3860114
conflicts("%gcc@10", when="+cuda ^cuda@:11.4.0") conflicts("%gcc@10", when="+cuda ^cuda@:11.4.0")

View File

@@ -4,13 +4,16 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Common utilities for managing intel oneapi packages.""" """Common utilities for managing intel oneapi packages."""
import getpass import getpass
import os
import platform import platform
import shutil import shutil
from os.path import basename, dirname, isdir from os.path import basename, dirname, isdir
from llnl.util.filesystem import find_headers, find_libraries, join_path from llnl.util.filesystem import find_headers, find_libraries, join_path
from llnl.util.link_tree import LinkTree
from spack.directives import conflicts, variant from spack.directives import conflicts, variant
from spack.package import mkdirp
from spack.util.environment import EnvironmentModifications from spack.util.environment import EnvironmentModifications
from spack.util.executable import Executable from spack.util.executable import Executable
@@ -125,6 +128,31 @@ def setup_run_environment(self, env):
) )
) )
def symlink_dir(self, src, dest):
# Taken from: https://github.com/spack/spack/pull/31285/files
# oneapi bin/lib directories are 2 or 3 levels below the
# prefix, but it is more typical to have them directly in the
# prefix. The location has changed over time. Rather than make
# every package that needs to know where include/lib are
# located be aware of this, put in symlinks to conform. This
# is good enough for some, but not all packages.
# If we symlink top-level directories directly, files won't
# show up in views Create real dirs and symlink files instead
# Create a real directory at dest
mkdirp(dest)
# Symlink all files in src to dest keeping directories as dirs
for entry in os.listdir(src):
src_path = join_path(src, entry)
dest_path = join_path(dest, entry)
if isdir(src_path) and os.access(src_path, os.X_OK):
link_tree = LinkTree(src_path)
link_tree.merge(dest_path)
else:
os.symlink(src_path, dest_path)
class IntelOneApiLibraryPackage(IntelOneApiPackage): class IntelOneApiLibraryPackage(IntelOneApiPackage):
"""Base class for Intel oneAPI library packages. """Base class for Intel oneAPI library packages.

View File

@@ -7,7 +7,7 @@
import llnl.util.lang as lang import llnl.util.lang as lang
from spack.directives import extends, maintainers from spack.directives import extends
from .generic import GenericBuilder, Package from .generic import GenericBuilder, Package
@@ -71,8 +71,6 @@ class RPackage(Package):
GenericBuilder = RBuilder GenericBuilder = RBuilder
maintainers("glennpj")
#: This attribute is used in UI queries that need to know the build #: This attribute is used in UI queries that need to know the build
#: system base class #: system base class
build_system_class = "RPackage" build_system_class = "RPackage"

View File

@@ -10,6 +10,7 @@
from llnl.util.filesystem import find, join_path, working_dir from llnl.util.filesystem import find, join_path, working_dir
import spack.builder import spack.builder
import spack.install_test
import spack.package_base import spack.package_base
from spack.directives import build_system, depends_on, extends from spack.directives import build_system, depends_on, extends
from spack.multimethod import when from spack.multimethod import when
@@ -30,8 +31,8 @@ class SIPPackage(spack.package_base.PackageBase):
#: Name of private sip module to install alongside package #: Name of private sip module to install alongside package
sip_module = "sip" sip_module = "sip"
#: Callback names for install-time test #: Callback names for install-time testing
install_time_test_callbacks = ["test"] install_time_test_callbacks = ["test_imports"]
#: Legacy buildsystem attribute used to deserialize and install old specs #: Legacy buildsystem attribute used to deserialize and install old specs
legacy_buildsystem = "sip" legacy_buildsystem = "sip"
@@ -87,18 +88,20 @@ def python(self, *args, **kwargs):
"""The python ``Executable``.""" """The python ``Executable``."""
inspect.getmodule(self).python(*args, **kwargs) inspect.getmodule(self).python(*args, **kwargs)
def test(self): def test_imports(self):
"""Attempts to import modules of the installed package.""" """Attempts to import modules of the installed package."""
# Make sure we are importing the installed modules, # Make sure we are importing the installed modules,
# not the ones in the source directory # not the ones in the source directory
python = inspect.getmodule(self).python
for module in self.import_modules: for module in self.import_modules:
self.run_test( with spack.install_test.test_part(
inspect.getmodule(self).python.path, self,
["-c", "import {0}".format(module)], "test_imports_{0}".format(module),
purpose="checking import of {0}".format(module), purpose="checking import of {0}".format(module),
work_dir="spack-test", work_dir="spack-test",
) ):
python("-c", "import {0}".format(module))
@spack.builder.builder("sip") @spack.builder.builder("sip")

View File

@@ -130,9 +130,11 @@ def __init__(self, wrapped_pkg_object, root_builder):
bases, bases,
{ {
"run_tests": property(lambda x: x.wrapped_package_object.run_tests), "run_tests": property(lambda x: x.wrapped_package_object.run_tests),
"test_log_file": property(lambda x: x.wrapped_package_object.test_log_file), "test_requires_compiler": property(
"test_failures": property(lambda x: x.wrapped_package_object.test_failures), lambda x: x.wrapped_package_object.test_requires_compiler
),
"test_suite": property(lambda x: x.wrapped_package_object.test_suite), "test_suite": property(lambda x: x.wrapped_package_object.test_suite),
"tester": property(lambda x: x.wrapped_package_object.tester),
}, },
) )
new_cls.__module__ = package_cls.__module__ new_cls.__module__ = package_cls.__module__

View File

@@ -531,7 +531,7 @@ def __init__(self, ci_config, phases, staged_phases):
""" """
self.ci_config = ci_config self.ci_config = ci_config
self.named_jobs = ["any", "build", "cleanup", "noop", "reindex", "signing"] self.named_jobs = ["any", "build", "copy", "cleanup", "noop", "reindex", "signing"]
self.ir = { self.ir = {
"jobs": {}, "jobs": {},
@@ -634,17 +634,13 @@ def generate_ir(self):
# Reindex script # Reindex script
{ {
"reindex-job": { "reindex-job": {
"script:": [ "script:": ["spack buildcache update-index --keys {index_target_mirror}"]
"spack buildcache update-index --keys --mirror-url {index_target_mirror}"
]
} }
}, },
# Cleanup script # Cleanup script
{ {
"cleanup-job": { "cleanup-job": {
"script:": [ "script:": ["spack -d mirror destroy {mirror_prefix}/$CI_PIPELINE_ID"]
"spack -d mirror destroy --mirror-url {mirror_prefix}/$CI_PIPELINE_ID"
]
} }
}, },
# Add signing job tags # Add signing job tags
@@ -760,6 +756,7 @@ def generate_gitlab_ci_yaml(
# Get the joined "ci" config with all of the current scopes resolved # Get the joined "ci" config with all of the current scopes resolved
ci_config = cfg.get("ci") ci_config = cfg.get("ci")
config_deprecated = False
if not ci_config: if not ci_config:
tty.warn("Environment does not have `ci` a configuration") tty.warn("Environment does not have `ci` a configuration")
gitlabci_config = yaml_root.get("gitlab-ci") gitlabci_config = yaml_root.get("gitlab-ci")
@@ -772,6 +769,7 @@ def generate_gitlab_ci_yaml(
) )
translate_deprecated_config(gitlabci_config) translate_deprecated_config(gitlabci_config)
ci_config = gitlabci_config ci_config = gitlabci_config
config_deprecated = True
# Default target is gitlab...and only target is gitlab # Default target is gitlab...and only target is gitlab
if not ci_config.get("target", "gitlab") == "gitlab": if not ci_config.get("target", "gitlab") == "gitlab":
@@ -835,6 +833,14 @@ def generate_gitlab_ci_yaml(
# Values: "spack_pull_request", "spack_protected_branch", or not set # Values: "spack_pull_request", "spack_protected_branch", or not set
spack_pipeline_type = os.environ.get("SPACK_PIPELINE_TYPE", None) spack_pipeline_type = os.environ.get("SPACK_PIPELINE_TYPE", None)
copy_only_pipeline = spack_pipeline_type == "spack_copy_only"
if copy_only_pipeline and config_deprecated:
tty.warn(
"SPACK_PIPELINE_TYPE=spack_copy_only is not supported when using\n",
"deprecated ci configuration, a no-op pipeline will be generated\n",
"instead.",
)
if "mirrors" not in yaml_root or len(yaml_root["mirrors"].values()) < 1: if "mirrors" not in yaml_root or len(yaml_root["mirrors"].values()) < 1:
tty.die("spack ci generate requires an env containing a mirror") tty.die("spack ci generate requires an env containing a mirror")
@@ -1089,7 +1095,7 @@ def generate_gitlab_ci_yaml(
raise AttributeError raise AttributeError
def main_script_replacements(cmd): def main_script_replacements(cmd):
return cmd.replace("{env_dir}", concrete_env_dir) return cmd.replace("{env_dir}", rel_concrete_env_dir)
job_object["script"] = _unpack_script( job_object["script"] = _unpack_script(
job_object["script"], op=main_script_replacements job_object["script"], op=main_script_replacements
@@ -1211,7 +1217,7 @@ def main_script_replacements(cmd):
).format(c_spec, release_spec) ).format(c_spec, release_spec)
tty.debug(debug_msg) tty.debug(debug_msg)
if prune_dag and not rebuild_spec: if prune_dag and not rebuild_spec and not copy_only_pipeline:
tty.debug( tty.debug(
"Pruning {0}/{1}, does not need rebuild.".format( "Pruning {0}/{1}, does not need rebuild.".format(
release_spec.name, release_spec.dag_hash() release_spec.name, release_spec.dag_hash()
@@ -1302,8 +1308,9 @@ def main_script_replacements(cmd):
max_length_needs = length_needs max_length_needs = length_needs
max_needs_job = job_name max_needs_job = job_name
output_object[job_name] = job_object if not copy_only_pipeline:
job_id += 1 output_object[job_name] = job_object
job_id += 1
if print_summary: if print_summary:
for phase in phases: for phase in phases:
@@ -1333,6 +1340,17 @@ def main_script_replacements(cmd):
"when": ["runner_system_failure", "stuck_or_timeout_failure", "script_failure"], "when": ["runner_system_failure", "stuck_or_timeout_failure", "script_failure"],
} }
if copy_only_pipeline and not config_deprecated:
stage_names.append("copy")
sync_job = copy.deepcopy(spack_ci_ir["jobs"]["copy"]["attributes"])
sync_job["stage"] = "copy"
if artifacts_root:
sync_job["needs"] = [
{"job": generate_job_name, "pipeline": "{0}".format(parent_pipeline_id)}
]
output_object["copy"] = sync_job
job_id += 1
if job_id > 0: if job_id > 0:
if temp_storage_url_prefix: if temp_storage_url_prefix:
# There were some rebuild jobs scheduled, so we will need to # There were some rebuild jobs scheduled, so we will need to
@@ -1466,12 +1484,18 @@ def main_script_replacements(cmd):
sorted_output = cinw.needs_to_dependencies(sorted_output) sorted_output = cinw.needs_to_dependencies(sorted_output)
else: else:
# No jobs were generated # No jobs were generated
tty.debug("No specs to rebuild, generating no-op job")
noop_job = spack_ci_ir["jobs"]["noop"]["attributes"] noop_job = spack_ci_ir["jobs"]["noop"]["attributes"]
noop_job["retry"] = service_job_retries noop_job["retry"] = service_job_retries
sorted_output = {"no-specs-to-rebuild": noop_job} if copy_only_pipeline and config_deprecated:
tty.debug("Generating no-op job as copy-only is unsupported here.")
noop_job["script"] = [
'echo "copy-only pipelines are not supported with deprecated ci configs"'
]
sorted_output = {"unsupported-copy": noop_job}
else:
tty.debug("No specs to rebuild, generating no-op job")
sorted_output = {"no-specs-to-rebuild": noop_job}
if known_broken_specs_encountered: if known_broken_specs_encountered:
tty.error("This pipeline generated hashes known to be broken on develop:") tty.error("This pipeline generated hashes known to be broken on develop:")
@@ -2456,7 +2480,16 @@ def populate_buildgroup(self, job_names):
msg = "Error response code ({0}) in populate_buildgroup".format(response_code) msg = "Error response code ({0}) in populate_buildgroup".format(response_code)
tty.warn(msg) tty.warn(msg)
def report_skipped(self, spec, directory_name, reason): def report_skipped(self, spec: spack.spec.Spec, report_dir: str, reason: Optional[str]):
"""Explicitly report skipping testing of a spec (e.g., it's CI
configuration identifies it as known to have broken tests or
the CI installation failed).
Args:
spec: spec being tested
report_dir: directory where the report will be written
reason: reason the test is being skipped
"""
configuration = CDashConfiguration( configuration = CDashConfiguration(
upload_url=self.upload_url, upload_url=self.upload_url,
packages=[spec.name], packages=[spec.name],
@@ -2466,7 +2499,7 @@ def report_skipped(self, spec, directory_name, reason):
track=None, track=None,
) )
reporter = CDash(configuration=configuration) reporter = CDash(configuration=configuration)
reporter.test_skipped_report(directory_name, spec, reason) reporter.test_skipped_report(report_dir, spec, reason)
def translate_deprecated_config(config): def translate_deprecated_config(config):
@@ -2481,12 +2514,14 @@ def translate_deprecated_config(config):
build_job["tags"] = config.pop("tags") build_job["tags"] = config.pop("tags")
if "variables" in config: if "variables" in config:
build_job["variables"] = config.pop("variables") build_job["variables"] = config.pop("variables")
# Scripts always override in old CI
if "before_script" in config: if "before_script" in config:
build_job["before_script"] = config.pop("before_script") build_job["before_script:"] = config.pop("before_script")
if "script" in config: if "script" in config:
build_job["script"] = config.pop("script") build_job["script:"] = config.pop("script")
if "after_script" in config: if "after_script" in config:
build_job["after_script"] = config.pop("after_script") build_job["after_script:"] = config.pop("after_script")
signing_job = None signing_job = None
if "signing-job-attributes" in config: if "signing-job-attributes" in config:
@@ -2510,8 +2545,25 @@ def translate_deprecated_config(config):
for section in mappings: for section in mappings:
submapping_section = {"match": section["match"]} submapping_section = {"match": section["match"]}
if "runner-attributes" in section: if "runner-attributes" in section:
submapping_section["build-job"] = section["runner-attributes"] remapped_attributes = {}
if match_behavior == "first":
for key, value in section["runner-attributes"].items():
# Scripts always override in old CI
if key == "script":
remapped_attributes["script:"] = value
elif key == "before_script":
remapped_attributes["before_script:"] = value
elif key == "after_script":
remapped_attributes["after_script:"] = value
else:
remapped_attributes[key] = value
else:
# Handle "merge" behavior be allowing scripts to merge in submapping section
remapped_attributes = section["runner-attributes"]
submapping_section["build-job"] = remapped_attributes
if "remove-attributes" in section: if "remove-attributes" in section:
# Old format only allowed tags in this section, so no extra checks are needed
submapping_section["build-job-remove"] = section["remove-attributes"] submapping_section["build-job-remove"] = section["remove-attributes"]
submapping.append(submapping_section) submapping.append(submapping_section)
pipeline_gen.append({"submapping": submapping, "match_behavior": match_behavior}) pipeline_gen.append({"submapping": submapping, "match_behavior": match_behavior})

View File

@@ -347,7 +347,7 @@ def iter_groups(specs, indent, all_headers):
spack.spec.architecture_color, spack.spec.architecture_color,
architecture if architecture else "no arch", architecture if architecture else "no arch",
spack.spec.compiler_color, spack.spec.compiler_color,
compiler if compiler else "no compiler", f"{compiler.display_str}" if compiler else "no compiler",
) )
# Sometimes we want to display specs that are not yet concretized. # Sometimes we want to display specs that are not yet concretized.

View File

@@ -98,7 +98,7 @@ def compiler_find(args):
config = spack.config.config config = spack.config.config
filename = config.get_config_filename(args.scope, "compilers") filename = config.get_config_filename(args.scope, "compilers")
tty.msg("Added %d new compiler%s to %s" % (n, s, filename)) tty.msg("Added %d new compiler%s to %s" % (n, s, filename))
colify(reversed(sorted(c.spec for c in new_compilers)), indent=4) colify(reversed(sorted(c.spec.display_str for c in new_compilers)), indent=4)
else: else:
tty.msg("Found no new compilers") tty.msg("Found no new compilers")
tty.msg("Compilers are defined in the following files:") tty.msg("Compilers are defined in the following files:")
@@ -112,13 +112,13 @@ def compiler_remove(args):
tty.die("No compilers match spec %s" % cspec) tty.die("No compilers match spec %s" % cspec)
elif not args.all and len(compilers) > 1: elif not args.all and len(compilers) > 1:
tty.error("Multiple compilers match spec %s. Choose one:" % cspec) tty.error("Multiple compilers match spec %s. Choose one:" % cspec)
colify(reversed(sorted([c.spec for c in compilers])), indent=4) colify(reversed(sorted([c.spec.display_str for c in compilers])), indent=4)
tty.msg("Or, use `spack compiler remove -a` to remove all of them.") tty.msg("Or, use `spack compiler remove -a` to remove all of them.")
sys.exit(1) sys.exit(1)
for compiler in compilers: for compiler in compilers:
spack.compilers.remove_compiler_from_config(compiler.spec, scope=args.scope) spack.compilers.remove_compiler_from_config(compiler.spec, scope=args.scope)
tty.msg("Removed compiler %s" % compiler.spec) tty.msg("Removed compiler %s" % compiler.spec.display_str)
def compiler_info(args): def compiler_info(args):
@@ -130,7 +130,7 @@ def compiler_info(args):
tty.die("No compilers match spec %s" % cspec) tty.die("No compilers match spec %s" % cspec)
else: else:
for c in compilers: for c in compilers:
print(str(c.spec) + ":") print(c.spec.display_str + ":")
print("\tpaths:") print("\tpaths:")
for cpath in ["cc", "cxx", "f77", "fc"]: for cpath in ["cc", "cxx", "f77", "fc"]:
print("\t\t%s = %s" % (cpath, getattr(c, cpath, None))) print("\t\t%s = %s" % (cpath, getattr(c, cpath, None)))
@@ -188,7 +188,7 @@ def compiler_list(args):
os_str += "-%s" % target os_str += "-%s" % target
cname = "%s{%s} %s" % (spack.spec.compiler_color, name, os_str) cname = "%s{%s} %s" % (spack.spec.compiler_color, name, os_str)
tty.hline(colorize(cname), char="-") tty.hline(colorize(cname), char="-")
colify(reversed(sorted(c.spec for c in compilers))) colify(reversed(sorted(c.spec.display_str for c in compilers)))
def compiler(parser, args): def compiler(parser, args):

View File

@@ -29,6 +29,7 @@ def setup_parser(subparser):
) )
spack.cmd.common.arguments.add_concretizer_args(subparser) spack.cmd.common.arguments.add_concretizer_args(subparser)
spack.cmd.common.arguments.add_common_arguments(subparser, ["jobs"])
def concretize(parser, args): def concretize(parser, args):

View File

@@ -302,7 +302,7 @@ def env_create(args):
# the environment should not include a view. # the environment should not include a view.
with_view = None with_view = None
_env_create( env = _env_create(
args.create_env, args.create_env,
init_file=args.envfile, init_file=args.envfile,
dir=args.dir, dir=args.dir,
@@ -310,6 +310,9 @@ def env_create(args):
keep_relative=args.keep_relative, keep_relative=args.keep_relative,
) )
# Generate views, only really useful for environments created from spack.lock files.
env.regenerate_views()
def _env_create(name_or_path, *, init_file=None, dir=False, with_view=None, keep_relative=False): def _env_create(name_or_path, *, init_file=None, dir=False, with_view=None, keep_relative=False):
"""Create a new environment, with an optional yaml description. """Create a new environment, with an optional yaml description.

View File

@@ -79,6 +79,12 @@ def setup_parser(subparser):
read_cray_manifest.add_argument( read_cray_manifest.add_argument(
"--directory", default=None, help="specify a directory storing a group of manifest files" "--directory", default=None, help="specify a directory storing a group of manifest files"
) )
read_cray_manifest.add_argument(
"--ignore-default-dir",
action="store_true",
default=False,
help="ignore the default directory of manifest files",
)
read_cray_manifest.add_argument( read_cray_manifest.add_argument(
"--dry-run", "--dry-run",
action="store_true", action="store_true",
@@ -177,11 +183,16 @@ def external_read_cray_manifest(args):
manifest_directory=args.directory, manifest_directory=args.directory,
dry_run=args.dry_run, dry_run=args.dry_run,
fail_on_error=args.fail_on_error, fail_on_error=args.fail_on_error,
ignore_default_dir=args.ignore_default_dir,
) )
def _collect_and_consume_cray_manifest_files( def _collect_and_consume_cray_manifest_files(
manifest_file=None, manifest_directory=None, dry_run=False, fail_on_error=False manifest_file=None,
manifest_directory=None,
dry_run=False,
fail_on_error=False,
ignore_default_dir=False,
): ):
manifest_files = [] manifest_files = []
if manifest_file: if manifest_file:
@@ -191,7 +202,7 @@ def _collect_and_consume_cray_manifest_files(
if manifest_directory: if manifest_directory:
manifest_dirs.append(manifest_directory) manifest_dirs.append(manifest_directory)
if os.path.isdir(cray_manifest.default_path): if not ignore_default_dir and os.path.isdir(cray_manifest.default_path):
tty.debug( tty.debug(
"Cray manifest path {0} exists: collecting all files to read.".format( "Cray manifest path {0} exists: collecting all files to read.".format(
cray_manifest.default_path cray_manifest.default_path

View File

@@ -5,7 +5,6 @@
from __future__ import print_function from __future__ import print_function
import inspect
import textwrap import textwrap
from itertools import zip_longest from itertools import zip_longest
@@ -15,9 +14,10 @@
import spack.cmd.common.arguments as arguments import spack.cmd.common.arguments as arguments
import spack.fetch_strategy as fs import spack.fetch_strategy as fs
import spack.install_test
import spack.repo import spack.repo
import spack.spec import spack.spec
from spack.package_base import has_test_method, preferred_version from spack.package_base import preferred_version
description = "get detailed information on a particular package" description = "get detailed information on a particular package"
section = "basic" section = "basic"
@@ -261,41 +261,7 @@ def print_tests(pkg):
# if it has been overridden and, therefore, assumed to be implemented. # if it has been overridden and, therefore, assumed to be implemented.
color.cprint("") color.cprint("")
color.cprint(section_title("Stand-Alone/Smoke Test Methods:")) color.cprint(section_title("Stand-Alone/Smoke Test Methods:"))
names = [] names = spack.install_test.test_function_names(pkg, add_virtuals=True)
pkg_cls = pkg if inspect.isclass(pkg) else pkg.__class__
if has_test_method(pkg_cls):
pkg_base = spack.package_base.PackageBase
test_pkgs = [
str(cls.test)
for cls in inspect.getmro(pkg_cls)
if issubclass(cls, pkg_base) and cls.test != pkg_base.test
]
test_pkgs = list(set(test_pkgs))
names.extend([(test.split()[1]).lower() for test in test_pkgs])
# TODO Refactor START
# Use code from package_base.py's test_process IF this functionality is
# accepted.
v_names = list(set([vspec.name for vspec in pkg.virtuals_provided]))
# hack for compilers that are not dependencies (yet)
# TODO: this all eventually goes away
c_names = ("gcc", "intel", "intel-parallel-studio", "pgi")
if pkg.name in c_names:
v_names.extend(["c", "cxx", "fortran"])
if pkg.spec.intersects("llvm+clang"):
v_names.extend(["c", "cxx"])
# TODO Refactor END
v_specs = [spack.spec.Spec(v_name) for v_name in v_names]
for v_spec in v_specs:
try:
pkg_cls = spack.repo.path.get_pkg_class(v_spec.name)
if has_test_method(pkg_cls):
names.append("{0}.test".format(pkg_cls.name.lower()))
except spack.repo.UnknownPackageError:
pass
if names: if names:
colify(sorted(names), indent=4) colify(sorted(names), indent=4)
else: else:

View File

@@ -76,6 +76,14 @@ def setup_parser(subparser):
help="location of the named or current environment", help="location of the named or current environment",
) )
subparser.add_argument(
"--first",
action="store_true",
default=False,
dest="find_first",
help="use the first match if multiple packages match the spec",
)
arguments.add_common_arguments(subparser, ["spec"]) arguments.add_common_arguments(subparser, ["spec"])
@@ -121,7 +129,7 @@ def location(parser, args):
# install_dir command matches against installed specs. # install_dir command matches against installed specs.
if args.install_dir: if args.install_dir:
env = ev.active_environment() env = ev.active_environment()
spec = spack.cmd.disambiguate_spec(specs[0], env) spec = spack.cmd.disambiguate_spec(specs[0], env, first=args.find_first)
print(spec.prefix) print(spec.prefix)
return return

View File

@@ -116,21 +116,23 @@ def one_spec_or_raise(specs):
def check_module_set_name(name): def check_module_set_name(name):
modules_config = spack.config.get("modules") modules = spack.config.get("modules")
valid_names = set( if name != "prefix_inspections" and name in modules:
[ return
key
for key, value in modules_config.items()
if isinstance(value, dict) and value.get("enable", [])
]
)
if "enable" in modules_config and modules_config["enable"]:
valid_names.add("default")
if name not in valid_names: names = [k for k in modules if k != "prefix_inspections"]
msg = "Cannot use invalid module set %s." % name
msg += " Valid module set names are %s" % list(valid_names) if not names:
raise spack.config.ConfigError(msg) raise spack.config.ConfigError(
f"Module set configuration is missing. Cannot use module set '{name}'"
)
pretty_names = "', '".join(names)
raise spack.config.ConfigError(
f"Cannot use invalid module set '{name}'.",
f"Valid module set names are: '{pretty_names}'.",
)
_missing_modules_warning = ( _missing_modules_warning = (

View File

@@ -140,12 +140,15 @@ def _process_result(result, show, required_format, kwargs):
def solve(parser, args): def solve(parser, args):
# these are the same options as `spack spec` # these are the same options as `spack spec`
name_fmt = "{namespace}.{name}" if args.namespaces else "{name}"
fmt = "{@versions}{%compiler}{compiler_flags}{variants}{arch=architecture}"
install_status_fn = spack.spec.Spec.install_status install_status_fn = spack.spec.Spec.install_status
fmt = spack.spec.display_format
if args.namespaces:
fmt = "{namespace}." + fmt
kwargs = { kwargs = {
"cover": args.cover, "cover": args.cover,
"format": name_fmt + fmt, "format": fmt,
"hashlen": None if args.very_long else 7, "hashlen": None if args.very_long else 7,
"show_types": args.types, "show_types": args.types,
"status_fn": install_status_fn if args.install_status else None, "status_fn": install_status_fn if args.install_status else None,

View File

@@ -80,12 +80,15 @@ def setup_parser(subparser):
def spec(parser, args): def spec(parser, args):
name_fmt = "{namespace}.{name}" if args.namespaces else "{name}"
fmt = "{@versions}{%compiler}{compiler_flags}{variants}{arch=architecture}"
install_status_fn = spack.spec.Spec.install_status install_status_fn = spack.spec.Spec.install_status
fmt = spack.spec.display_format
if args.namespaces:
fmt = "{namespace}." + fmt
tree_kwargs = { tree_kwargs = {
"cover": args.cover, "cover": args.cover,
"format": name_fmt + fmt, "format": fmt,
"hashlen": None if args.very_long else 7, "hashlen": None if args.very_long else 7,
"show_types": args.types, "show_types": args.types,
"status_fn": install_status_fn if args.install_status else None, "status_fn": install_status_fn if args.install_status else None,

View File

@@ -11,6 +11,7 @@
import re import re
import shutil import shutil
import sys import sys
from collections import Counter
from llnl.util import lang, tty from llnl.util import lang, tty
from llnl.util.tty import colify from llnl.util.tty import colify
@@ -236,9 +237,8 @@ def test_list(args):
tagged = set(spack.repo.path.packages_with_tags(*args.tag)) if args.tag else set() tagged = set(spack.repo.path.packages_with_tags(*args.tag)) if args.tag else set()
def has_test_and_tags(pkg_class): def has_test_and_tags(pkg_class):
return spack.package_base.has_test_method(pkg_class) and ( tests = spack.install_test.test_functions(pkg_class)
not args.tag or pkg_class.name in tagged return len(tests) and (not args.tag or pkg_class.name in tagged)
)
if args.list_all: if args.list_all:
report_packages = [ report_packages = [
@@ -358,18 +358,17 @@ def _report_suite_results(test_suite, args, constraints):
tty.msg("test specs:") tty.msg("test specs:")
failed, skipped, untested = 0, 0, 0 counts = Counter()
for pkg_id in test_specs: for pkg_id in test_specs:
if pkg_id in results: if pkg_id in results:
status = results[pkg_id] status = results[pkg_id]
if status == "FAILED": # Backward-compatibility: NO-TESTS => NO_TESTS
failed += 1 status = "NO_TESTS" if status == "NO-TESTS" else status
elif status == "NO-TESTS":
untested += 1
elif status == "SKIPPED":
skipped += 1
if args.failed and status != "FAILED": status = spack.install_test.TestStatus[status]
counts[status] += 1
if args.failed and status != spack.install_test.TestStatus.FAILED:
continue continue
msg = " {0} {1}".format(pkg_id, status) msg = " {0} {1}".format(pkg_id, status)
@@ -381,7 +380,7 @@ def _report_suite_results(test_suite, args, constraints):
msg += "\n{0}".format("".join(f.readlines())) msg += "\n{0}".format("".join(f.readlines()))
tty.msg(msg) tty.msg(msg)
spack.install_test.write_test_summary(failed, skipped, untested, len(test_specs)) spack.install_test.write_test_summary(counts)
else: else:
msg = "Test %s has no results.\n" % test_suite.name msg = "Test %s has no results.\n" % test_suite.name
msg += " Check if it is running with " msg += " Check if it is running with "

View File

@@ -25,7 +25,7 @@
# tutorial configuration parameters # tutorial configuration parameters
tutorial_branch = "releases/v0.19" tutorial_branch = "releases/v0.20"
tutorial_mirror = "file:///mirror" tutorial_mirror = "file:///mirror"
tutorial_key = os.path.join(spack.paths.share_path, "keys", "tutorial.pub") tutorial_key = os.path.join(spack.paths.share_path, "keys", "tutorial.pub")

View File

@@ -112,36 +112,26 @@ def _to_dict(compiler):
def get_compiler_config(scope=None, init_config=True): def get_compiler_config(scope=None, init_config=True):
"""Return the compiler configuration for the specified architecture.""" """Return the compiler configuration for the specified architecture."""
def init_compiler_config(): config = spack.config.get("compilers", scope=scope) or []
"""Compiler search used when Spack has no compilers.""" if config or not init_config:
compilers = find_compilers() return config
compilers_dict = []
for compiler in compilers:
compilers_dict.append(_to_dict(compiler))
spack.config.set("compilers", compilers_dict, scope=scope)
merged_config = spack.config.get("compilers")
if merged_config:
return config
_init_compiler_config(scope=scope)
config = spack.config.get("compilers", scope=scope) config = spack.config.get("compilers", scope=scope)
# Update the configuration if there are currently no compilers return config
# configured. Avoid updating automatically if there ARE site
# compilers configured but no user ones.
if not config and init_config: def _init_compiler_config(*, scope):
if scope is None: """Compiler search used when Spack has no compilers."""
# We know no compilers were configured in any scope. compilers = find_compilers()
init_compiler_config() compilers_dict = []
config = spack.config.get("compilers", scope=scope) for compiler in compilers:
elif scope == "user": compilers_dict.append(_to_dict(compiler))
# Check the site config and update the user config if spack.config.set("compilers", compilers_dict, scope=scope)
# nothing is configured at the site level.
site_config = spack.config.get("compilers", scope="site")
sys_config = spack.config.get("compilers", scope="system")
if not site_config and not sys_config:
init_compiler_config()
config = spack.config.get("compilers", scope=scope)
return config
elif config:
return config
else:
return [] # Return empty list which we will later append to.
def compiler_config_files(): def compiler_config_files():
@@ -187,7 +177,9 @@ def remove_compiler_from_config(compiler_spec, scope=None):
filtered_compiler_config = [ filtered_compiler_config = [
comp comp
for comp in compiler_config for comp in compiler_config
if spack.spec.CompilerSpec(comp["compiler"]["spec"]) != compiler_spec if not spack.spec.parse_with_version_concrete(
comp["compiler"]["spec"], compiler=True
).satisfies(compiler_spec)
] ]
# Update the cache for changes # Update the cache for changes
@@ -724,7 +716,7 @@ def make_compiler_list(detected_versions):
def _default_make_compilers(cmp_id, paths): def _default_make_compilers(cmp_id, paths):
operating_system, compiler_name, version = cmp_id operating_system, compiler_name, version = cmp_id
compiler_cls = spack.compilers.class_for_compiler_name(compiler_name) compiler_cls = spack.compilers.class_for_compiler_name(compiler_name)
spec = spack.spec.CompilerSpec(compiler_cls.name, version) spec = spack.spec.CompilerSpec(compiler_cls.name, f"={version}")
paths = [paths.get(x, None) for x in ("cc", "cxx", "f77", "fc")] paths = [paths.get(x, None) for x in ("cc", "cxx", "f77", "fc")]
# TODO: johnwparent - revist the following line as per discussion at: # TODO: johnwparent - revist the following line as per discussion at:
# https://github.com/spack/spack/pull/33385/files#r1040036318 # https://github.com/spack/spack/pull/33385/files#r1040036318
@@ -802,8 +794,10 @@ def name_matches(name, name_list):
toolchains.add(compiler_cls.__name__) toolchains.add(compiler_cls.__name__)
if len(toolchains) > 1: if len(toolchains) > 1:
if toolchains == set(["Clang", "AppleClang", "Aocc"]) or toolchains == set( if (
["Dpcpp", "Oneapi"] toolchains == set(["Clang", "AppleClang", "Aocc"])
# Msvc toolchain uses Intel ifx
or toolchains == set(["Msvc", "Dpcpp", "Oneapi"])
): ):
return False return False
tty.debug("[TOOLCHAINS] {0}".format(toolchains)) tty.debug("[TOOLCHAINS] {0}".format(toolchains))

View File

@@ -30,7 +30,7 @@
def get_valid_fortran_pth(comp_ver): def get_valid_fortran_pth(comp_ver):
cl_ver = str(comp_ver).split("@")[1] cl_ver = str(comp_ver)
sort_fn = lambda fc_ver: StrictVersion(fc_ver) sort_fn = lambda fc_ver: StrictVersion(fc_ver)
sort_fc_ver = sorted(list(avail_fc_version), key=sort_fn) sort_fc_ver = sorted(list(avail_fc_version), key=sort_fn)
for ver in sort_fc_ver: for ver in sort_fc_ver:
@@ -75,7 +75,7 @@ class Msvc(Compiler):
# file based on compiler executable path. # file based on compiler executable path.
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
new_pth = [pth if pth else get_valid_fortran_pth(args[0]) for pth in args[3]] new_pth = [pth if pth else get_valid_fortran_pth(args[0].version) for pth in args[3]]
args[3][:] = new_pth args[3][:] = new_pth
super(Msvc, self).__init__(*args, **kwargs) super(Msvc, self).__init__(*args, **kwargs)
if os.getenv("ONEAPI_ROOT"): if os.getenv("ONEAPI_ROOT"):
@@ -151,7 +151,11 @@ def setup_custom_environment(self, pkg, env):
arch = arch.replace("-", "_") arch = arch.replace("-", "_")
# vcvars can target specific sdk versions, force it to pick up concretized sdk # vcvars can target specific sdk versions, force it to pick up concretized sdk
# version, if needed by spec # version, if needed by spec
sdk_ver = "" if "win-sdk" not in pkg.spec else pkg.spec["win-sdk"].version.string + ".0" sdk_ver = (
""
if "win-sdk" not in pkg.spec or pkg.name == "win-sdk"
else pkg.spec["win-sdk"].version.string + ".0"
)
# provide vcvars with msvc version selected by concretization, # provide vcvars with msvc version selected by concretization,
# not whatever it happens to pick up on the system (highest available version) # not whatever it happens to pick up on the system (highest available version)
out = subprocess.check_output( # novermin out = subprocess.check_output( # novermin

View File

@@ -10,10 +10,12 @@
from typing import Optional from typing import Optional
import spack.environment as ev import spack.environment as ev
import spack.error
import spack.schema.env import spack.schema.env
import spack.tengine as tengine import spack.tengine as tengine
import spack.util.spack_yaml as syaml import spack.util.spack_yaml as syaml
from spack.container.images import (
from ..images import (
bootstrap_template_for, bootstrap_template_for,
build_info, build_info,
checkout_command, checkout_command,
@@ -205,12 +207,20 @@ def manifest(self):
@tengine.context_property @tengine.context_property
def os_packages_final(self): def os_packages_final(self):
"""Additional system packages that are needed at run-time.""" """Additional system packages that are needed at run-time."""
return self._os_packages_for_stage("final") try:
return self._os_packages_for_stage("final")
except Exception as e:
msg = f"an error occurred while rendering the 'final' stage of the image: {e}"
raise spack.error.SpackError(msg) from e
@tengine.context_property @tengine.context_property
def os_packages_build(self): def os_packages_build(self):
"""Additional system packages that are needed at build-time.""" """Additional system packages that are needed at build-time."""
return self._os_packages_for_stage("build") try:
return self._os_packages_for_stage("build")
except Exception as e:
msg = f"an error occurred while rendering the 'build' stage of the image: {e}"
raise spack.error.SpackError(msg) from e
@tengine.context_property @tengine.context_property
def os_package_update(self): def os_package_update(self):
@@ -243,13 +253,24 @@ def _package_info_from(self, package_list):
if image is None: if image is None:
os_pkg_manager = os_package_manager_for(image_config["os"]) os_pkg_manager = os_package_manager_for(image_config["os"])
else: else:
os_pkg_manager = self.container_config["os_packages"]["command"] os_pkg_manager = self._os_pkg_manager()
update, install, clean = commands_for(os_pkg_manager) update, install, clean = commands_for(os_pkg_manager)
Packages = collections.namedtuple("Packages", ["update", "install", "list", "clean"]) Packages = collections.namedtuple("Packages", ["update", "install", "list", "clean"])
return Packages(update=update, install=install, list=package_list, clean=clean) return Packages(update=update, install=install, list=package_list, clean=clean)
def _os_pkg_manager(self):
try:
os_pkg_manager = self.container_config["os_packages"]["command"]
except KeyError:
msg = (
"cannot determine the OS package manager to use.\n\n\tPlease add an "
"appropriate 'os_packages:command' entry to the spack.yaml manifest file\n"
)
raise spack.error.SpackError(msg)
return os_pkg_manager
@tengine.context_property @tengine.context_property
def extra_instructions(self): def extra_instructions(self):
Extras = collections.namedtuple("Extra", ["build", "final"]) Extras = collections.namedtuple("Extra", ["build", "final"])

View File

@@ -2,6 +2,8 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import shlex
import spack.tengine as tengine import spack.tengine as tengine
from . import PathContext, writer from . import PathContext, writer
@@ -17,14 +19,15 @@ class DockerContext(PathContext):
@tengine.context_property @tengine.context_property
def manifest(self): def manifest(self):
manifest_str = super(DockerContext, self).manifest manifest_str = super(DockerContext, self).manifest
# Docker doesn't support HEREDOC so we need to resort to # Docker doesn't support HEREDOC, so we need to resort to
# a horrible echo trick to have the manifest in the Dockerfile # a horrible echo trick to have the manifest in the Dockerfile
echoed_lines = [] echoed_lines = []
for idx, line in enumerate(manifest_str.split("\n")): for idx, line in enumerate(manifest_str.split("\n")):
quoted_line = shlex.quote(line)
if idx == 0: if idx == 0:
echoed_lines.append('&& (echo "' + line + '" \\') echoed_lines.append("&& (echo " + quoted_line + " \\")
continue continue
echoed_lines.append('&& echo "' + line + '" \\') echoed_lines.append("&& echo " + quoted_line + " \\")
echoed_lines[-1] = echoed_lines[-1].replace(" \\", ")") echoed_lines[-1] = echoed_lines[-1].replace(" \\", ")")

View File

@@ -48,7 +48,8 @@ def translated_compiler_name(manifest_compiler_name):
def compiler_from_entry(entry): def compiler_from_entry(entry):
compiler_name = translated_compiler_name(entry["name"]) compiler_name = translated_compiler_name(entry["name"])
paths = entry["executables"] paths = entry["executables"]
version = entry["version"] # to instantiate a compiler class we may need a concrete version:
version = "={}".format(entry["version"])
arch = entry["arch"] arch = entry["arch"]
operating_system = arch["os"] operating_system = arch["os"]
target = arch["target"] target = arch["target"]

View File

@@ -798,9 +798,8 @@ def check(cond, msg):
# TODO: better version checking semantics. # TODO: better version checking semantics.
version = vn.Version(db["version"]) version = vn.Version(db["version"])
spec_reader = reader(version)
if version > _db_version: if version > _db_version:
raise InvalidDatabaseVersionError(_db_version, version) raise InvalidDatabaseVersionError(self, _db_version, version)
elif version < _db_version: elif version < _db_version:
if not any(old == version and new == _db_version for old, new in _skip_reindex): if not any(old == version and new == _db_version for old, new in _skip_reindex):
tty.warn( tty.warn(
@@ -814,6 +813,8 @@ def check(cond, msg):
for k, v in self._data.items() for k, v in self._data.items()
) )
spec_reader = reader(version)
def invalid_record(hash_key, error): def invalid_record(hash_key, error):
return CorruptDatabaseError( return CorruptDatabaseError(
f"Invalid record in Spack database: hash: {hash_key}, cause: " f"Invalid record in Spack database: hash: {hash_key}, cause: "
@@ -1642,7 +1643,7 @@ class CorruptDatabaseError(SpackError):
class NonConcreteSpecAddError(SpackError): class NonConcreteSpecAddError(SpackError):
"""Raised when attemptint to add non-concrete spec to DB.""" """Raised when attempting to add non-concrete spec to DB."""
class MissingDependenciesError(SpackError): class MissingDependenciesError(SpackError):
@@ -1650,8 +1651,17 @@ class MissingDependenciesError(SpackError):
class InvalidDatabaseVersionError(SpackError): class InvalidDatabaseVersionError(SpackError):
def __init__(self, expected, found): """Exception raised when the database metadata is newer than current Spack."""
super(InvalidDatabaseVersionError, self).__init__(
"Expected database version %s but found version %s." % (expected, found), def __init__(self, database, expected, found):
"`spack reindex` may fix this, or you may need a newer " "Spack version.", self.expected = expected
self.found = found
msg = (
f"you need a newer Spack version to read the DB in '{database.root}'. "
f"{self.database_version_message}"
) )
super(InvalidDatabaseVersionError, self).__init__(msg)
@property
def database_version_message(self):
return f"The expected DB version is '{self.expected}', but '{self.found}' was found."

View File

@@ -218,8 +218,10 @@ def update_configuration(detected_packages, scope=None, buildable=True):
def _windows_drive(): def _windows_drive():
"""Return Windows drive string""" """Return Windows drive string extracted from PROGRAMFILES
return os.environ["HOMEDRIVE"] env var, which is garunteed to be defined for all logins"""
drive = re.match(r"([a-zA-Z]:)", os.environ["PROGRAMFILES"]).group(1)
return drive
class WindowsCompilerExternalPaths(object): class WindowsCompilerExternalPaths(object):

View File

@@ -16,18 +16,24 @@
The high-level format of a Spack lockfile hasn't changed much between versions, but the The high-level format of a Spack lockfile hasn't changed much between versions, but the
contents have. Lockfiles are JSON-formatted and their top-level sections are: contents have. Lockfiles are JSON-formatted and their top-level sections are:
1. ``_meta`` (object): this contains deatails about the file format, including: 1. ``_meta`` (object): this contains details about the file format, including:
* ``file-type``: always ``"spack-lockfile"`` * ``file-type``: always ``"spack-lockfile"``
* ``lockfile-version``: an integer representing the lockfile format version * ``lockfile-version``: an integer representing the lockfile format version
* ``specfile-version``: an integer representing the spec format version (since * ``specfile-version``: an integer representing the spec format version (since
``v0.17``) ``v0.17``)
2. ``roots`` (list): an ordered list of records representing the roots of the Spack 2. ``spack`` (object): optional, this identifies information about Spack
used to concretize the environment:
* ``type``: required, identifies form Spack version took (e.g., ``git``, ``release``)
* ``commit``: the commit if the version is from git
* ``version``: the Spack version
3. ``roots`` (list): an ordered list of records representing the roots of the Spack
environment. Each has two fields: environment. Each has two fields:
* ``hash``: a Spack spec hash uniquely identifying the concrete root spec * ``hash``: a Spack spec hash uniquely identifying the concrete root spec
* ``spec``: a string representation of the abstract spec that was concretized * ``spec``: a string representation of the abstract spec that was concretized
3. ``concrete_specs``: a dictionary containing the specs in the environment. 4. ``concrete_specs``: a dictionary containing the specs in the environment.
Compatibility Compatibility
------------- -------------
@@ -271,6 +277,8 @@
Dependencies are keyed by ``hash`` (DAG hash) as well. There are no more ``build_hash`` Dependencies are keyed by ``hash`` (DAG hash) as well. There are no more ``build_hash``
fields in the specs, and there are no more issues with lockfiles being able to store fields in the specs, and there are no more issues with lockfiles being able to store
multiple specs with the same DAG hash (because the DAG hash is now finer-grained). multiple specs with the same DAG hash (because the DAG hash is now finer-grained).
An optional ``spack`` property may be included to track version information, such as
the commit or version.
.. code-block:: json .. code-block:: json
@@ -278,8 +286,8 @@
{ {
"_meta": { "_meta": {
"file-type": "spack-lockfile", "file-type": "spack-lockfile",
"lockfile-version": 3, "lockfile-version": 4,
"specfile-version": 2 "specfile-version": 3
}, },
"roots": [ "roots": [
{ {
@@ -326,7 +334,6 @@
} }
} }
} }
""" """
from .environment import ( from .environment import (

View File

@@ -16,7 +16,7 @@
import urllib.parse import urllib.parse
import urllib.request import urllib.request
import warnings import warnings
from typing import Any, Dict, List, Optional, Union from typing import Any, Dict, List, Optional, Set, Tuple, Union
import llnl.util.filesystem as fs import llnl.util.filesystem as fs
import llnl.util.tty as tty import llnl.util.tty as tty
@@ -31,6 +31,7 @@
import spack.error import spack.error
import spack.hash_types as ht import spack.hash_types as ht
import spack.hooks import spack.hooks
import spack.main
import spack.paths import spack.paths
import spack.repo import spack.repo
import spack.schema.env import spack.schema.env
@@ -1118,9 +1119,9 @@ def add(self, user_spec, list_name=user_speclist_name):
raise SpackEnvironmentError(f"No list {list_name} exists in environment {self.name}") raise SpackEnvironmentError(f"No list {list_name} exists in environment {self.name}")
if list_name == user_speclist_name: if list_name == user_speclist_name:
if not spec.name: if spec.anonymous:
raise SpackEnvironmentError("cannot add anonymous specs to an environment") raise SpackEnvironmentError("cannot add anonymous specs to an environment")
elif not spack.repo.path.exists(spec.name): elif not spack.repo.path.exists(spec.name) and not spec.abstract_hash:
virtuals = spack.repo.path.provider_index.providers.keys() virtuals = spack.repo.path.provider_index.providers.keys()
if spec.name not in virtuals: if spec.name not in virtuals:
msg = "no such package: %s" % spec.name msg = "no such package: %s" % spec.name
@@ -1220,28 +1221,27 @@ def remove(self, query_spec, list_name=user_speclist_name, force=False):
old_specs = set(self.user_specs) old_specs = set(self.user_specs)
new_specs = set() new_specs = set()
for spec in matches: for spec in matches:
if spec in list_to_change: if spec not in list_to_change:
try: continue
list_to_change.remove(spec) try:
self.update_stale_references(list_name) list_to_change.remove(spec)
new_specs = set(self.user_specs) self.update_stale_references(list_name)
except spack.spec_list.SpecListError: new_specs = set(self.user_specs)
# define new specs list except spack.spec_list.SpecListError:
new_specs = set(self.user_specs) # define new specs list
msg = f"Spec '{spec}' is part of a spec matrix and " new_specs = set(self.user_specs)
msg += f"cannot be removed from list '{list_to_change}'." msg = f"Spec '{spec}' is part of a spec matrix and "
if force: msg += f"cannot be removed from list '{list_to_change}'."
msg += " It will be removed from the concrete specs." if force:
# Mock new specs, so we can remove this spec from concrete spec lists msg += " It will be removed from the concrete specs."
new_specs.remove(spec) # Mock new specs, so we can remove this spec from concrete spec lists
tty.warn(msg) new_specs.remove(spec)
tty.warn(msg)
else:
if list_name == user_speclist_name:
self.manifest.remove_user_spec(str(spec))
else: else:
if list_name == user_speclist_name: self.manifest.remove_definition(str(spec), list_name=list_name)
for user_spec in matches:
self.manifest.remove_user_spec(str(user_spec))
else:
for user_spec in matches:
self.manifest.remove_definition(str(user_spec), list_name=list_name)
# If force, update stale concretized specs # If force, update stale concretized specs
for spec in old_specs - new_specs: for spec in old_specs - new_specs:
@@ -1351,6 +1351,10 @@ def concretize(self, force=False, tests=False):
self.concretized_order = [] self.concretized_order = []
self.specs_by_hash = {} self.specs_by_hash = {}
# Remove concrete specs that no longer correlate to a user spec
for spec in set(self.concretized_user_specs) - set(self.user_specs):
self.deconcretize(spec)
# Pick the right concretization strategy # Pick the right concretization strategy
if self.unify == "when_possible": if self.unify == "when_possible":
return self._concretize_together_where_possible(tests=tests) return self._concretize_together_where_possible(tests=tests)
@@ -1364,67 +1368,120 @@ def concretize(self, force=False, tests=False):
msg = "concretization strategy not implemented [{0}]" msg = "concretization strategy not implemented [{0}]"
raise SpackEnvironmentError(msg.format(self.unify)) raise SpackEnvironmentError(msg.format(self.unify))
def _concretize_together_where_possible(self, tests=False): def deconcretize(self, spec):
# spec has to be a root of the environment
index = self.concretized_user_specs.index(spec)
dag_hash = self.concretized_order.pop(index)
del self.concretized_user_specs[index]
# If this was the only user spec that concretized to this concrete spec, remove it
if dag_hash not in self.concretized_order:
del self.specs_by_hash[dag_hash]
def _get_specs_to_concretize(
self,
) -> Tuple[Set[spack.spec.Spec], Set[spack.spec.Spec], List[spack.spec.Spec]]:
"""Compute specs to concretize for unify:true and unify:when_possible.
This includes new user specs and any already concretized specs.
Returns:
Tuple of new user specs, user specs to keep, and the specs to concretize.
"""
# Exit early if the set of concretized specs is the set of user specs
new_user_specs = set(self.user_specs) - set(self.concretized_user_specs)
kept_user_specs = set(self.user_specs) & set(self.concretized_user_specs)
if not new_user_specs:
return new_user_specs, kept_user_specs, []
concrete_specs_to_keep = [
concrete
for abstract, concrete in self.concretized_specs()
if abstract in kept_user_specs
]
specs_to_concretize = list(new_user_specs) + concrete_specs_to_keep
return new_user_specs, kept_user_specs, specs_to_concretize
def _concretize_together_where_possible(
self, tests: bool = False
) -> List[Tuple[spack.spec.Spec, spack.spec.Spec]]:
# Avoid cyclic dependency # Avoid cyclic dependency
import spack.solver.asp import spack.solver.asp
# Exit early if the set of concretized specs is the set of user specs # Exit early if the set of concretized specs is the set of user specs
user_specs_did_not_change = not bool( new_user_specs, _, specs_to_concretize = self._get_specs_to_concretize()
set(self.user_specs) - set(self.concretized_user_specs) if not new_user_specs:
)
if user_specs_did_not_change:
return [] return []
# Proceed with concretization old_concrete_to_abstract = {
concrete: abstract for (abstract, concrete) in self.concretized_specs()
}
self.concretized_user_specs = [] self.concretized_user_specs = []
self.concretized_order = [] self.concretized_order = []
self.specs_by_hash = {} self.specs_by_hash = {}
result_by_user_spec = {} result_by_user_spec = {}
solver = spack.solver.asp.Solver() solver = spack.solver.asp.Solver()
for result in solver.solve_in_rounds(self.user_specs, tests=tests): for result in solver.solve_in_rounds(specs_to_concretize, tests=tests):
result_by_user_spec.update(result.specs_by_input) result_by_user_spec.update(result.specs_by_input)
result = [] result = []
for abstract, concrete in sorted(result_by_user_spec.items()): for abstract, concrete in sorted(result_by_user_spec.items()):
# If the "abstract" spec is a concrete spec from the previous concretization
# translate it back to an abstract spec. Otherwise, keep the abstract spec
abstract = old_concrete_to_abstract.get(abstract, abstract)
if abstract in new_user_specs:
result.append((abstract, concrete))
self._add_concrete_spec(abstract, concrete) self._add_concrete_spec(abstract, concrete)
result.append((abstract, concrete))
return result return result
def _concretize_together(self, tests=False): def _concretize_together(
self, tests: bool = False
) -> List[Tuple[spack.spec.Spec, spack.spec.Spec]]:
"""Concretization strategy that concretizes all the specs """Concretization strategy that concretizes all the specs
in the same DAG. in the same DAG.
""" """
# Exit early if the set of concretized specs is the set of user specs # Exit early if the set of concretized specs is the set of user specs
user_specs_did_not_change = not bool( new_user_specs, kept_user_specs, specs_to_concretize = self._get_specs_to_concretize()
set(self.user_specs) - set(self.concretized_user_specs) if not new_user_specs:
)
if user_specs_did_not_change:
return [] return []
# Proceed with concretization
self.concretized_user_specs = [] self.concretized_user_specs = []
self.concretized_order = [] self.concretized_order = []
self.specs_by_hash = {} self.specs_by_hash = {}
try: try:
concrete_specs = spack.concretize.concretize_specs_together( concrete_specs: List[spack.spec.Spec] = spack.concretize.concretize_specs_together(
*self.user_specs, tests=tests *specs_to_concretize, tests=tests
) )
except spack.error.UnsatisfiableSpecError as e: except spack.error.UnsatisfiableSpecError as e:
# "Enhance" the error message for multiple root specs, suggest a less strict # "Enhance" the error message for multiple root specs, suggest a less strict
# form of concretization. # form of concretization.
if len(self.user_specs) > 1: if len(self.user_specs) > 1:
e.message += ". "
if kept_user_specs:
e.message += (
"Couldn't concretize without changing the existing environment. "
"If you are ok with changing it, try `spack concretize --force`. "
)
e.message += ( e.message += (
". Consider setting `concretizer:unify` to `when_possible` " "You could consider setting `concretizer:unify` to `when_possible` "
"or `false` to relax the concretizer strictness." "or `false` to allow multiple versions of some packages."
) )
raise raise
concretized_specs = [x for x in zip(self.user_specs, concrete_specs)] # set() | set() does not preserve ordering, even though sets are ordered
ordered_user_specs = list(new_user_specs) + list(kept_user_specs)
concretized_specs = [x for x in zip(ordered_user_specs, concrete_specs)]
for abstract, concrete in concretized_specs: for abstract, concrete in concretized_specs:
self._add_concrete_spec(abstract, concrete) self._add_concrete_spec(abstract, concrete)
return concretized_specs
# zip truncates the longer list, which is exactly what we want here
return list(zip(new_user_specs, concrete_specs))
def _concretize_separately(self, tests=False): def _concretize_separately(self, tests=False):
"""Concretization strategy that concretizes separately one """Concretization strategy that concretizes separately one
@@ -1475,7 +1532,10 @@ def _concretize_separately(self, tests=False):
# Solve the environment in parallel on Linux # Solve the environment in parallel on Linux
start = time.time() start = time.time()
max_processes = min(len(arguments), 16) # Number of specs # Cap on 16 cores max_processes = min(
len(arguments), # Number of specs
spack.config.get("config:build_jobs"), # Cap on build jobs
)
# TODO: revisit this print as soon as darwin is parallel too # TODO: revisit this print as soon as darwin is parallel too
msg = "Starting concretization" msg = "Starting concretization"
@@ -2069,6 +2129,14 @@ def _to_lockfile_dict(self):
hash_spec_list = zip(self.concretized_order, self.concretized_user_specs) hash_spec_list = zip(self.concretized_order, self.concretized_user_specs)
spack_dict = {"version": spack.spack_version}
spack_commit = spack.main.get_spack_commit()
if spack_commit:
spack_dict["type"] = "git"
spack_dict["commit"] = spack_commit
else:
spack_dict["type"] = "release"
# this is the lockfile we'll write out # this is the lockfile we'll write out
data = { data = {
# metadata about the format # metadata about the format
@@ -2077,6 +2145,8 @@ def _to_lockfile_dict(self):
"lockfile-version": lockfile_format_version, "lockfile-version": lockfile_format_version,
"specfile-version": spack.spec.SPECFILE_FORMAT_VERSION, "specfile-version": spack.spec.SPECFILE_FORMAT_VERSION,
}, },
# spack version information
"spack": spack_dict,
# users specs + hashes are the 'roots' of the environment # users specs + hashes are the 'roots' of the environment
"roots": [{"hash": h, "spec": str(s)} for h, s in hash_spec_list], "roots": [{"hash": h, "spec": str(s)} for h, s in hash_spec_list],
# Concrete specs by hash, including dependencies # Concrete specs by hash, including dependencies
@@ -2113,10 +2183,12 @@ def _read_lockfile_dict(self, d):
reader = READER_CLS[current_lockfile_format] reader = READER_CLS[current_lockfile_format]
except KeyError: except KeyError:
msg = ( msg = (
f"Spack {spack.__version__} cannot read environment lockfiles using the " f"Spack {spack.__version__} cannot read the lockfile '{self.lock_path}', using "
f"v{current_lockfile_format} format" f"the v{current_lockfile_format} format."
) )
raise RuntimeError(msg) if lockfile_format_version < current_lockfile_format:
msg += " You need to use a newer Spack version."
raise SpackEnvironmentError(msg)
# First pass: Put each spec in the map ignoring dependencies # First pass: Put each spec in the map ignoring dependencies
for lockfile_key, node_dict in json_specs_by_hash.items(): for lockfile_key, node_dict in json_specs_by_hash.items():
@@ -2308,6 +2380,7 @@ def display_specs(concretized_specs):
def _tree_to_display(spec): def _tree_to_display(spec):
return spec.tree( return spec.tree(
recurse_dependencies=True, recurse_dependencies=True,
format=spack.spec.display_format,
status_fn=spack.spec.Spec.install_status, status_fn=spack.spec.Spec.install_status,
hashlen=7, hashlen=7,
hashes=True, hashes=True,

View File

@@ -3,13 +3,14 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import collections
import functools as ft import functools as ft
import itertools import itertools
import os import os
import re import re
import shutil import shutil
import stat
import sys import sys
from typing import Optional
from llnl.util import tty from llnl.util import tty
from llnl.util.filesystem import ( from llnl.util.filesystem import (
@@ -32,12 +33,14 @@
import spack.config import spack.config
import spack.projections import spack.projections
import spack.relocate
import spack.schema.projections import spack.schema.projections
import spack.spec import spack.spec
import spack.store import spack.store
import spack.util.spack_json as s_json import spack.util.spack_json as s_json
import spack.util.spack_yaml as s_yaml import spack.util.spack_yaml as s_yaml
from spack.error import SpackError from spack.error import SpackError
from spack.hooks import sbang
__all__ = ["FilesystemView", "YamlFilesystemView"] __all__ = ["FilesystemView", "YamlFilesystemView"]
@@ -57,50 +60,47 @@ def view_hardlink(src, dst, **kwargs):
os.link(src, dst) os.link(src, dst)
def view_copy(src, dst, view, spec=None): def view_copy(src: str, dst: str, view, spec: Optional[spack.spec.Spec] = None):
""" """
Copy a file from src to dst. Copy a file from src to dst.
Use spec and view to generate relocations Use spec and view to generate relocations
""" """
shutil.copy2(src, dst) shutil.copy2(src, dst, follow_symlinks=False)
if spec and not spec.external:
# Not metadata, we have to relocate it
# Get information on where to relocate from/to # No need to relocate if no metadata or external.
if not spec or spec.external:
return
# This is vestigial code for the *old* location of sbang. Previously, # Order of this dict is somewhat irrelevant
# sbang was a bash script, and it lived in the spack prefix. It is prefix_to_projection = {
# now a POSIX script that lives in the install prefix. Old packages s.prefix: view.get_projection_for_spec(s)
# will have the old sbang location in their shebangs. for s in spec.traverse(root=True, order="breadth")
# TODO: Not sure which one to use... if not s.external
import spack.hooks.sbang as sbang }
# Break a package include cycle src_stat = os.lstat(src)
import spack.relocate
orig_sbang = "#!/bin/bash {0}/bin/sbang".format(spack.paths.spack_root) # TODO: change this into a bulk operation instead of a per-file operation
new_sbang = sbang.sbang_shebang_line()
prefix_to_projection = collections.OrderedDict( if stat.S_ISLNK(src_stat.st_mode):
{spec.prefix: view.get_projection_for_spec(spec)} spack.relocate.relocate_links(links=[dst], prefix_to_prefix=prefix_to_projection)
) elif spack.relocate.is_binary(dst):
spack.relocate.relocate_text_bin(binaries=[dst], prefixes=prefix_to_projection)
else:
prefix_to_projection[spack.store.layout.root] = view._root
for dep in spec.traverse(): # This is vestigial code for the *old* location of sbang.
if not dep.external: prefix_to_projection[
prefix_to_projection[dep.prefix] = view.get_projection_for_spec(dep) "#!/bin/bash {0}/bin/sbang".format(spack.paths.spack_root)
] = sbang.sbang_shebang_line()
if spack.relocate.is_binary(dst): spack.relocate.relocate_text(files=[dst], prefixes=prefix_to_projection)
spack.relocate.relocate_text_bin(binaries=[dst], prefixes=prefix_to_projection)
else: try:
prefix_to_projection[spack.store.layout.root] = view._root os.chown(dst, src_stat.st_uid, src_stat.st_gid)
prefix_to_projection[orig_sbang] = new_sbang except OSError:
spack.relocate.relocate_text(files=[dst], prefixes=prefix_to_projection) tty.debug("Can't change the permissions for %s" % dst)
try:
stat = os.stat(src)
os.chown(dst, stat.st_uid, stat.st_gid)
except OSError:
tty.debug("Can't change the permissions for %s" % dst)
def view_func_parser(parsed_name): def view_func_parser(parsed_name):

File diff suppressed because it is too large Load Diff

View File

@@ -278,6 +278,19 @@ def _print_installed_pkg(message):
print(colorize("@*g{[+]} ") + spack.util.path.debug_padded_filter(message)) print(colorize("@*g{[+]} ") + spack.util.path.debug_padded_filter(message))
def print_install_test_log(pkg: "spack.package_base.PackageBase"):
"""Output install test log file path but only if have test failures.
Args:
pkg: instance of the package under test
"""
if not pkg.run_tests or not (pkg.tester and pkg.tester.test_failures):
# The tests were not run or there were no test failures
return
pkg.tester.print_log_path()
def _print_timer(pre, pkg_id, timer): def _print_timer(pre, pkg_id, timer):
phases = ["{}: {}.".format(p.capitalize(), _hms(timer.duration(p))) for p in timer.phases] phases = ["{}: {}.".format(p.capitalize(), _hms(timer.duration(p))) for p in timer.phases]
phases.append("Total: {}".format(_hms(timer.duration()))) phases.append("Total: {}".format(_hms(timer.duration())))
@@ -536,6 +549,25 @@ def install_msg(name, pid):
return pre + colorize("@*{Installing} @*g{%s}" % name) return pre + colorize("@*{Installing} @*g{%s}" % name)
def archive_install_logs(pkg, phase_log_dir):
"""
Copy install logs to their destination directory(ies)
Args:
pkg (spack.package_base.PackageBase): the package that was built and installed
phase_log_dir (str): path to the archive directory
"""
# Archive the whole stdout + stderr for the package
fs.install(pkg.log_path, pkg.install_log_path)
# Archive all phase log paths
for phase_log in pkg.phase_log_files:
log_file = os.path.basename(phase_log)
fs.install(phase_log, os.path.join(phase_log_dir, log_file))
# Archive the install-phase test log, if present
pkg.archive_install_test_log()
def log(pkg): def log(pkg):
""" """
Copy provenance into the install directory on success Copy provenance into the install directory on success
@@ -553,22 +585,11 @@ def log(pkg):
# FIXME : this potentially catches too many things... # FIXME : this potentially catches too many things...
tty.debug(e) tty.debug(e)
# Archive the whole stdout + stderr for the package archive_install_logs(pkg, os.path.dirname(packages_dir))
fs.install(pkg.log_path, pkg.install_log_path)
# Archive all phase log paths
for phase_log in pkg.phase_log_files:
log_file = os.path.basename(phase_log)
log_file = os.path.join(os.path.dirname(packages_dir), log_file)
fs.install(phase_log, log_file)
# Archive the environment modifications for the build. # Archive the environment modifications for the build.
fs.install(pkg.env_mods_path, pkg.install_env_path) fs.install(pkg.env_mods_path, pkg.install_env_path)
# Archive the install-phase test log, if present
if pkg.test_install_log_path and os.path.exists(pkg.test_install_log_path):
fs.install(pkg.test_install_log_path, pkg.install_test_install_log_path)
if os.path.exists(pkg.configure_args_path): if os.path.exists(pkg.configure_args_path):
# Archive the args used for the build # Archive the args used for the build
fs.install(pkg.configure_args_path, pkg.install_configure_args_path) fs.install(pkg.configure_args_path, pkg.install_configure_args_path)
@@ -1932,14 +1953,17 @@ def run(self):
self._real_install() self._real_install()
# Run post install hooks before build stage is removed.
self.timer.start("post-install")
spack.hooks.post_install(self.pkg.spec, self.explicit)
self.timer.stop("post-install")
# Stop the timer and save results # Stop the timer and save results
self.timer.stop() self.timer.stop()
with open(self.pkg.times_log_path, "w") as timelog: with open(self.pkg.times_log_path, "w") as timelog:
self.timer.write_json(timelog) self.timer.write_json(timelog)
# Run post install hooks before build stage is removed. print_install_test_log(self.pkg)
spack.hooks.post_install(self.pkg.spec, self.explicit)
_print_timer(pre=self.pre, pkg_id=self.pkg_id, timer=self.timer) _print_timer(pre=self.pre, pkg_id=self.pkg_id, timer=self.timer)
_print_installed_pkg(self.pkg.prefix) _print_installed_pkg(self.pkg.prefix)

View File

@@ -126,6 +126,36 @@ def add_all_commands(parser):
parser.add_command(cmd) parser.add_command(cmd)
def get_spack_commit():
"""Get the Spack git commit sha.
Returns:
(str or None) the commit sha if available, otherwise None
"""
git_path = os.path.join(spack.paths.prefix, ".git")
if not os.path.exists(git_path):
return None
git = spack.util.git.git()
if not git:
return None
rev = git(
"-C",
spack.paths.prefix,
"rev-parse",
"HEAD",
output=str,
error=os.devnull,
fail_on_error=False,
)
if git.returncode != 0:
return None
match = re.match(r"[a-f\d]{7,}$", rev)
return match.group(0) if match else None
def get_version(): def get_version():
"""Get a descriptive version of this instance of Spack. """Get a descriptive version of this instance of Spack.
@@ -134,25 +164,9 @@ def get_version():
The commit sha is only added when available. The commit sha is only added when available.
""" """
version = spack.spack_version version = spack.spack_version
git_path = os.path.join(spack.paths.prefix, ".git") commit = get_spack_commit()
if os.path.exists(git_path): if commit:
git = spack.util.git.git() version += " ({0})".format(commit)
if not git:
return version
rev = git(
"-C",
spack.paths.prefix,
"rev-parse",
"HEAD",
output=str,
error=os.devnull,
fail_on_error=False,
)
if git.returncode != 0:
return version
match = re.match(r"[a-f\d]{7,}$", rev)
if match:
version += " ({0})".format(match.group(0))
return version return version

View File

@@ -170,17 +170,10 @@ def merge_config_rules(configuration, spec):
Returns: Returns:
dict: actions to be taken on the spec passed as an argument dict: actions to be taken on the spec passed as an argument
""" """
# Get the top-level configuration for the module type we are using
module_specific_configuration = copy.deepcopy(configuration)
# Construct a dictionary with the actions we need to perform on the spec
# passed as a parameter
# The keyword 'all' is always evaluated first, all the others are # The keyword 'all' is always evaluated first, all the others are
# evaluated in order of appearance in the module file # evaluated in order of appearance in the module file
spec_configuration = module_specific_configuration.pop("all", {}) spec_configuration = copy.deepcopy(configuration.get("all", {}))
for constraint, action in module_specific_configuration.items(): for constraint, action in configuration.items():
if spec.satisfies(constraint): if spec.satisfies(constraint):
if hasattr(constraint, "override") and constraint.override: if hasattr(constraint, "override") and constraint.override:
spec_configuration = {} spec_configuration = {}
@@ -200,14 +193,14 @@ def merge_config_rules(configuration, spec):
# configuration # configuration
# Hash length in module files # Hash length in module files
hash_length = module_specific_configuration.get("hash_length", 7) hash_length = configuration.get("hash_length", 7)
spec_configuration["hash_length"] = hash_length spec_configuration["hash_length"] = hash_length
verbose = module_specific_configuration.get("verbose", False) verbose = configuration.get("verbose", False)
spec_configuration["verbose"] = verbose spec_configuration["verbose"] = verbose
# module defaults per-package # module defaults per-package
defaults = module_specific_configuration.get("defaults", []) defaults = configuration.get("defaults", [])
spec_configuration["defaults"] = defaults spec_configuration["defaults"] = defaults
return spec_configuration return spec_configuration
@@ -400,7 +393,7 @@ class BaseConfiguration(object):
querying easier. It needs to be sub-classed for specific module types. querying easier. It needs to be sub-classed for specific module types.
""" """
default_projections = {"all": "{name}-{version}-{compiler.name}-{compiler.version}"} default_projections = {"all": "{name}/{version}-{compiler.name}-{compiler.version}"}
def __init__(self, spec, module_set_name, explicit=None): def __init__(self, spec, module_set_name, explicit=None):
# Module where type(self) is defined # Module where type(self) is defined

View File

@@ -7,7 +7,7 @@
import itertools import itertools
import os.path import os.path
import posixpath import posixpath
from typing import Any, Dict from typing import Any, Dict, List
import llnl.util.lang as lang import llnl.util.lang as lang
@@ -56,7 +56,7 @@ def make_context(spec, module_set_name, explicit):
return LmodContext(conf) return LmodContext(conf)
def guess_core_compilers(name, store=False): def guess_core_compilers(name, store=False) -> List[spack.spec.CompilerSpec]:
"""Guesses the list of core compilers installed in the system. """Guesses the list of core compilers installed in the system.
Args: Args:
@@ -64,21 +64,19 @@ def guess_core_compilers(name, store=False):
modules.yaml configuration file modules.yaml configuration file
Returns: Returns:
List of core compilers, if found, or None List of found core compilers
""" """
core_compilers = [] core_compilers = []
for compiler_config in spack.compilers.all_compilers_config(): for compiler in spack.compilers.all_compilers():
try: try:
compiler = compiler_config["compiler"]
# A compiler is considered to be a core compiler if any of the # A compiler is considered to be a core compiler if any of the
# C, C++ or Fortran compilers reside in a system directory # C, C++ or Fortran compilers reside in a system directory
is_system_compiler = any( is_system_compiler = any(
os.path.dirname(x) in spack.util.environment.SYSTEM_DIRS os.path.dirname(getattr(compiler, x, "")) in spack.util.environment.SYSTEM_DIRS
for x in compiler["paths"].values() for x in ("cc", "cxx", "f77", "fc")
if x is not None
) )
if is_system_compiler: if is_system_compiler:
core_compilers.append(str(compiler["spec"])) core_compilers.append(compiler.spec)
except (KeyError, TypeError, AttributeError): except (KeyError, TypeError, AttributeError):
continue continue
@@ -89,10 +87,10 @@ def guess_core_compilers(name, store=False):
modules_cfg = spack.config.get( modules_cfg = spack.config.get(
"modules:" + name, {}, scope=spack.config.default_modify_scope() "modules:" + name, {}, scope=spack.config.default_modify_scope()
) )
modules_cfg.setdefault("lmod", {})["core_compilers"] = core_compilers modules_cfg.setdefault("lmod", {})["core_compilers"] = [str(x) for x in core_compilers]
spack.config.set("modules:" + name, modules_cfg, scope=spack.config.default_modify_scope()) spack.config.set("modules:" + name, modules_cfg, scope=spack.config.default_modify_scope())
return core_compilers or None return core_compilers
class LmodConfiguration(BaseConfiguration): class LmodConfiguration(BaseConfiguration):
@@ -104,7 +102,7 @@ class LmodConfiguration(BaseConfiguration):
default_projections = {"all": posixpath.join("{name}", "{version}")} default_projections = {"all": posixpath.join("{name}", "{version}")}
@property @property
def core_compilers(self): def core_compilers(self) -> List[spack.spec.CompilerSpec]:
"""Returns the list of "Core" compilers """Returns the list of "Core" compilers
Raises: Raises:
@@ -112,14 +110,18 @@ def core_compilers(self):
specified in the configuration file or the sequence specified in the configuration file or the sequence
is empty is empty
""" """
value = configuration(self.name).get("core_compilers") or guess_core_compilers( compilers = [
self.name, store=True spack.spec.CompilerSpec(c) for c in configuration(self.name).get("core_compilers", [])
) ]
if not value: if not compilers:
compilers = guess_core_compilers(self.name, store=True)
if not compilers:
msg = 'the key "core_compilers" must be set in modules.yaml' msg = 'the key "core_compilers" must be set in modules.yaml'
raise CoreCompilersNotFoundError(msg) raise CoreCompilersNotFoundError(msg)
return value
return compilers
@property @property
def core_specs(self): def core_specs(self):
@@ -132,6 +134,7 @@ def filter_hierarchy_specs(self):
return configuration(self.name).get("filter_hierarchy_specs", {}) return configuration(self.name).get("filter_hierarchy_specs", {})
@property @property
@lang.memoized
def hierarchy_tokens(self): def hierarchy_tokens(self):
"""Returns the list of tokens that are part of the modulefile """Returns the list of tokens that are part of the modulefile
hierarchy. 'compiler' is always present. hierarchy. 'compiler' is always present.
@@ -156,6 +159,7 @@ def hierarchy_tokens(self):
return tokens return tokens
@property @property
@lang.memoized
def requires(self): def requires(self):
"""Returns a dictionary mapping all the requirements of this spec """Returns a dictionary mapping all the requirements of this spec
to the actual provider. 'compiler' is always present among the to the actual provider. 'compiler' is always present among the
@@ -197,11 +201,11 @@ def provides(self):
# If it is in the list of supported compilers family -> compiler # If it is in the list of supported compilers family -> compiler
if self.spec.name in spack.compilers.supported_compilers(): if self.spec.name in spack.compilers.supported_compilers():
provides["compiler"] = spack.spec.CompilerSpec(self.spec.format("{name}{@version}")) provides["compiler"] = spack.spec.CompilerSpec(self.spec.format("{name}{@versions}"))
elif self.spec.name in spack.compilers.package_name_to_compiler_name: elif self.spec.name in spack.compilers.package_name_to_compiler_name:
# If it is the package for a supported compiler, but of a different name # If it is the package for a supported compiler, but of a different name
cname = spack.compilers.package_name_to_compiler_name[self.spec.name] cname = spack.compilers.package_name_to_compiler_name[self.spec.name]
provides["compiler"] = spack.spec.CompilerSpec("%s@%s" % (cname, self.spec.version)) provides["compiler"] = spack.spec.CompilerSpec(cname, self.spec.versions)
# All the other tokens in the hierarchy must be virtual dependencies # All the other tokens in the hierarchy must be virtual dependencies
for x in self.hierarchy_tokens: for x in self.hierarchy_tokens:
@@ -222,6 +226,7 @@ def available(self):
return available return available
@property @property
@lang.memoized
def missing(self): def missing(self):
"""Returns the list of tokens that are not available.""" """Returns the list of tokens that are not available."""
return [x for x in self.hierarchy_tokens if x not in self.available] return [x for x in self.hierarchy_tokens if x not in self.available]
@@ -283,16 +288,18 @@ def token_to_path(self, name, value):
# If we are dealing with a core compiler, return 'Core' # If we are dealing with a core compiler, return 'Core'
core_compilers = self.conf.core_compilers core_compilers = self.conf.core_compilers
if name == "compiler" and str(value) in core_compilers: if name == "compiler" and any(
spack.spec.CompilerSpec(value).satisfies(c) for c in core_compilers
):
return "Core" return "Core"
# CompilerSpec does not have an hash, as we are not allowed to # CompilerSpec does not have a hash, as we are not allowed to
# use different flavors of the same compiler # use different flavors of the same compiler
if name == "compiler": if name == "compiler":
return path_part_fmt.format(token=value) return path_part_fmt.format(token=value)
# In case the hierarchy token refers to a virtual provider # In case the hierarchy token refers to a virtual provider
# we need to append an hash to the version to distinguish # we need to append a hash to the version to distinguish
# among flavors of the same library (e.g. openblas~openmp vs. # among flavors of the same library (e.g. openblas~openmp vs.
# openblas+openmp) # openblas+openmp)
path = path_part_fmt.format(token=value) path = path_part_fmt.format(token=value)
@@ -313,6 +320,7 @@ def available_path_parts(self):
return parts return parts
@property @property
@lang.memoized
def unlocked_paths(self): def unlocked_paths(self):
"""Returns a dictionary mapping conditions to a list of unlocked """Returns a dictionary mapping conditions to a list of unlocked
paths. paths.
@@ -424,6 +432,7 @@ def missing(self):
return self.conf.missing return self.conf.missing
@tengine.context_property @tengine.context_property
@lang.memoized
def unlocked_paths(self): def unlocked_paths(self):
"""Returns the list of paths that are unlocked unconditionally.""" """Returns the list of paths that are unlocked unconditionally."""
layout = make_layout(self.spec, self.conf.name, self.conf.explicit) layout = make_layout(self.spec, self.conf.name, self.conf.explicit)

View File

@@ -161,7 +161,7 @@ def make_compilers(self, compiler_id, paths):
compilers = [] compilers = []
for v in compiler_id.version: for v in compiler_id.version:
comp = cmp_cls( comp = cmp_cls(
spack.spec.CompilerSpec(name + "@" + v), spack.spec.CompilerSpec(name + "@=" + v),
self, self,
"any", "any",
["cc", "CC", "ftn"], ["cc", "CC", "ftn"],

View File

@@ -69,7 +69,15 @@
from spack.builder import run_after, run_before from spack.builder import run_after, run_before
from spack.dependency import all_deptypes from spack.dependency import all_deptypes
from spack.directives import * from spack.directives import *
from spack.install_test import get_escaped_text_output from spack.install_test import (
SkipTest,
cache_extra_test_sources,
check_outputs,
find_required_file,
get_escaped_text_output,
install_test_root,
test_part,
)
from spack.installer import ( from spack.installer import (
ExternalPackageError, ExternalPackageError,
InstallError, InstallError,
@@ -100,6 +108,5 @@
# These are just here for editor support; they will be replaced when the build env # These are just here for editor support; they will be replaced when the build env
# is set up. # is set up.
make = MakeExecutable("make", jobs=1) make = MakeExecutable("make", jobs=1)
gmake = MakeExecutable("gmake", jobs=1)
ninja = MakeExecutable("ninja", jobs=1) ninja = MakeExecutable("ninja", jobs=1)
configure = Executable(join_path(".", "configure")) configure = Executable(join_path(".", "configure"))

View File

@@ -25,13 +25,12 @@
import textwrap import textwrap
import time import time
import traceback import traceback
import types
import warnings import warnings
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type, TypeVar
import llnl.util.filesystem as fsys import llnl.util.filesystem as fsys
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.lang import classproperty, memoized, nullcontext from llnl.util.lang import classproperty, memoized
from llnl.util.link_tree import LinkTree from llnl.util.link_tree import LinkTree
import spack.compilers import spack.compilers
@@ -55,12 +54,18 @@
import spack.util.path import spack.util.path
import spack.util.web import spack.util.web
from spack.filesystem_view import YamlFilesystemView from spack.filesystem_view import YamlFilesystemView
from spack.install_test import TestFailure, TestSuite from spack.install_test import (
PackageTest,
TestFailure,
TestStatus,
TestSuite,
cache_extra_test_sources,
install_test_root,
)
from spack.installer import InstallError, PackageInstaller from spack.installer import InstallError, PackageInstaller
from spack.stage import ResourceStage, Stage, StageComposite, compute_stage_name from spack.stage import ResourceStage, Stage, StageComposite, compute_stage_name
from spack.util.executable import ProcessError, which from spack.util.executable import ProcessError, which
from spack.util.package_hash import package_hash from spack.util.package_hash import package_hash
from spack.util.prefix import Prefix
from spack.util.web import FetchError from spack.util.web import FetchError
from spack.version import GitVersion, StandardVersion, Version from spack.version import GitVersion, StandardVersion, Version
@@ -73,24 +78,21 @@
_ALLOWED_URL_SCHEMES = ["http", "https", "ftp", "file", "git"] _ALLOWED_URL_SCHEMES = ["http", "https", "ftp", "file", "git"]
# Filename for the Spack build/install log. #: Filename for the Spack build/install log.
_spack_build_logfile = "spack-build-out.txt" _spack_build_logfile = "spack-build-out.txt"
# Filename for the Spack build/install environment file. #: Filename for the Spack build/install environment file.
_spack_build_envfile = "spack-build-env.txt" _spack_build_envfile = "spack-build-env.txt"
# Filename for the Spack build/install environment modifications file. #: Filename for the Spack build/install environment modifications file.
_spack_build_envmodsfile = "spack-build-env-mods.txt" _spack_build_envmodsfile = "spack-build-env-mods.txt"
# Filename for the Spack install phase-time test log. #: Filename for the Spack configure args file.
_spack_install_test_log = "install-time-test-log.txt"
# Filename of json with total build and phase times (seconds)
_spack_times_log = "install_times.json"
# Filename for the Spack configure args file.
_spack_configure_argsfile = "spack-configure-args.txt" _spack_configure_argsfile = "spack-configure-args.txt"
#: Filename of json with total build and phase times (seconds)
spack_times_log = "install_times.json"
def deprecated_version(pkg, version): def deprecated_version(pkg, version):
"""Return True if the version is deprecated, False otherwise. """Return True if the version is deprecated, False otherwise.
@@ -181,8 +183,7 @@ class DetectablePackageMeta(object):
def __init__(cls, name, bases, attr_dict): def __init__(cls, name, bases, attr_dict):
if hasattr(cls, "executables") and hasattr(cls, "libraries"): if hasattr(cls, "executables") and hasattr(cls, "libraries"):
msg = "a package can have either an 'executables' or 'libraries' attribute" msg = "a package can have either an 'executables' or 'libraries' attribute"
msg += " [package '{0.name}' defines both]" raise spack.error.SpackError(f"{msg} [package '{name}' defines both]")
raise spack.error.SpackError(msg.format(cls))
# On windows, extend the list of regular expressions to look for # On windows, extend the list of regular expressions to look for
# filenames ending with ".exe" # filenames ending with ".exe"
@@ -423,17 +424,7 @@ def remove_files_from_view(self, view, merge_map):
view.remove_files(merge_map.values()) view.remove_files(merge_map.values())
def test_log_pathname(test_stage, spec): Pb = TypeVar("Pb", bound="PackageBase")
"""Build the pathname of the test log file
Args:
test_stage (str): path to the test stage directory
spec (spack.spec.Spec): instance of the spec under test
Returns:
(str): the pathname of the test log file
"""
return os.path.join(test_stage, "test-{0}-out.txt".format(TestSuite.test_pkg_id(spec)))
class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta): class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta):
@@ -638,19 +629,13 @@ class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta):
"tags", "tags",
] ]
#: Boolean. If set to ``True``, the smoke/install test requires a compiler. #: Set to ``True`` to indicate the stand-alone test requires a compiler.
#: This is currently used by smoke tests to ensure a compiler is available #: It is used to ensure a compiler and build dependencies like 'cmake'
#: to build a custom test code. #: are available to build a custom test code.
test_requires_compiler = False test_requires_compiler: bool = False
#: List of test failures encountered during a smoke/install test run. #: TestSuite instance used to manage stand-alone tests for 1+ specs.
test_failures = None test_suite: Optional["TestSuite"] = None
#: TestSuite instance used to manage smoke/install tests for one or more specs.
test_suite = None
#: Path to the log file used for tests
test_log_file = None
def __init__(self, spec): def __init__(self, spec):
# this determines how the package should be built. # this determines how the package should be built.
@@ -672,6 +657,7 @@ def __init__(self, spec):
# init internal variables # init internal variables
self._stage = None self._stage = None
self._fetcher = None self._fetcher = None
self._tester: Optional["PackageTest"] = None
# Set up timing variables # Set up timing variables
self._fetch_time = 0.0 self._fetch_time = 0.0
@@ -736,9 +722,9 @@ def possible_dependencies(
for name, conditions in cls.dependencies.items(): for name, conditions in cls.dependencies.items():
# check whether this dependency could be of the type asked for # check whether this dependency could be of the type asked for
types = [dep.type for cond, dep in conditions.items()] deptypes = [dep.type for cond, dep in conditions.items()]
types = set.union(*types) deptypes = set.union(*deptypes)
if not any(d in types for d in deptype): if not any(d in deptypes for d in deptype):
continue continue
# expand virtuals if enabled, otherwise just stop at virtuals # expand virtuals if enabled, otherwise just stop at virtuals
@@ -1148,30 +1134,41 @@ def configure_args_path(self):
"""Return the configure args file path associated with staging.""" """Return the configure args file path associated with staging."""
return os.path.join(self.stage.path, _spack_configure_argsfile) return os.path.join(self.stage.path, _spack_configure_argsfile)
@property
def test_install_log_path(self):
"""Return the install phase-time test log file path, if set."""
return getattr(self, "test_log_file", None)
@property
def install_test_install_log_path(self):
"""Return the install location for the install phase-time test log."""
return fsys.join_path(self.metadata_dir, _spack_install_test_log)
@property @property
def times_log_path(self): def times_log_path(self):
"""Return the times log json file.""" """Return the times log json file."""
return os.path.join(self.metadata_dir, _spack_times_log) return os.path.join(self.metadata_dir, spack_times_log)
@property @property
def install_configure_args_path(self): def install_configure_args_path(self):
"""Return the configure args file path on successful installation.""" """Return the configure args file path on successful installation."""
return os.path.join(self.metadata_dir, _spack_configure_argsfile) return os.path.join(self.metadata_dir, _spack_configure_argsfile)
# TODO (post-34236): Update tests and all packages that use this as a
# TODO (post-34236): package method to the function already available
# TODO (post-34236): to packages. Once done, remove this property.
@property @property
def install_test_root(self): def install_test_root(self):
"""Return the install test root directory.""" """Return the install test root directory."""
return os.path.join(self.metadata_dir, "test") tty.warn(
"The 'pkg.install_test_root' property is deprecated with removal "
"expected v0.21. Use 'install_test_root(pkg)' instead."
)
return install_test_root(self)
def archive_install_test_log(self):
"""Archive the install-phase test log, if present."""
if getattr(self, "tester", None):
self.tester.archive_install_test_log(self.metadata_dir)
@property
def tester(self):
if not self.spec.versions.concrete:
raise ValueError("Cannot retrieve tester for package without concrete version.")
if not self._tester:
self._tester = PackageTest(self)
return self._tester
@property @property
def installed(self): def installed(self):
@@ -1208,7 +1205,7 @@ def _make_fetcher(self):
@property @property
def fetcher(self): def fetcher(self):
if not self.spec.versions.concrete: if not self.spec.versions.concrete:
raise ValueError("Cannot retrieve fetcher for" " package without concrete version.") raise ValueError("Cannot retrieve fetcher for package without concrete version.")
if not self._fetcher: if not self._fetcher:
self._fetcher = self._make_fetcher() self._fetcher = self._make_fetcher()
return self._fetcher return self._fetcher
@@ -1842,6 +1839,9 @@ def do_install(self, **kwargs):
builder = PackageInstaller([(self, kwargs)]) builder = PackageInstaller([(self, kwargs)])
builder.install() builder.install()
# TODO (post-34236): Update tests and all packages that use this as a
# TODO (post-34236): package method to the routine made available to
# TODO (post-34236): packages. Once done, remove this method.
def cache_extra_test_sources(self, srcs): def cache_extra_test_sources(self, srcs):
"""Copy relative source paths to the corresponding install test subdir """Copy relative source paths to the corresponding install test subdir
@@ -1856,45 +1856,13 @@ def cache_extra_test_sources(self, srcs):
be copied to the corresponding location(s) under the install be copied to the corresponding location(s) under the install
testing directory. testing directory.
""" """
paths = [srcs] if isinstance(srcs, str) else srcs msg = (
"'pkg.cache_extra_test_sources(srcs) is deprecated with removal "
for path in paths: "expected in v0.21. Use 'cache_extra_test_sources(pkg, srcs)' "
src_path = os.path.join(self.stage.source_path, path) "instead."
dest_path = os.path.join(self.install_test_root, path) )
if os.path.isdir(src_path): warnings.warn(msg)
fsys.install_tree(src_path, dest_path) cache_extra_test_sources(self, srcs)
else:
fsys.mkdirp(os.path.dirname(dest_path))
fsys.copy(src_path, dest_path)
@contextlib.contextmanager
def _setup_test(self, verbose, externals):
self.test_failures = []
if self.test_suite:
self.test_log_file = self.test_suite.log_file_for_spec(self.spec)
self.tested_file = self.test_suite.tested_file_for_spec(self.spec)
pkg_id = self.test_suite.test_pkg_id(self.spec)
else:
self.test_log_file = fsys.join_path(self.stage.path, _spack_install_test_log)
self.test_suite = TestSuite([self.spec])
self.test_suite.stage = self.stage.path
pkg_id = self.spec.format("{name}-{version}-{hash:7}")
fsys.touch(self.test_log_file) # Otherwise log_parse complains
with tty.log.log_output(self.test_log_file, verbose) as logger:
with logger.force_echo():
tty.msg("Testing package {0}".format(pkg_id))
# use debug print levels for log file to record commands
old_debug = tty.is_debug()
tty.set_debug(True)
try:
yield logger
finally:
# reset debug level
tty.set_debug(old_debug)
def do_test(self, dirty=False, externals=False): def do_test(self, dirty=False, externals=False):
if self.test_requires_compiler: if self.test_requires_compiler:
@@ -1909,15 +1877,31 @@ def do_test(self, dirty=False, externals=False):
) )
return return
kwargs = {"dirty": dirty, "fake": False, "context": "test", "externals": externals} kwargs = {
if tty.is_verbose(): "dirty": dirty,
kwargs["verbose"] = True "fake": False,
spack.build_environment.start_build_process(self, test_process, kwargs) "context": "test",
"externals": externals,
"verbose": tty.is_verbose(),
}
self.tester.stand_alone_tests(kwargs)
# TODO (post-34236): Remove this deprecated method when eliminate test,
# TODO (post-34236): run_test, etc.
@property
def _test_deprecated_warning(self):
alt = f"Use any name starting with 'test_' instead in {self.spec.name}."
return f"The 'test' method is deprecated. {alt}"
# TODO (post-34236): Remove this deprecated method when eliminate test,
# TODO (post-34236): run_test, etc.
def test(self): def test(self):
# Defer tests to virtual and concrete packages # Defer tests to virtual and concrete packages
pass warnings.warn(self._test_deprecated_warning)
# TODO (post-34236): Remove this deprecated method when eliminate test,
# TODO (post-34236): run_test, etc.
def run_test( def run_test(
self, self,
exe, exe,
@@ -1925,7 +1909,7 @@ def run_test(
expected=[], expected=[],
status=0, status=0,
installed=False, installed=False,
purpose="", purpose=None,
skip_missing=False, skip_missing=False,
work_dir=None, work_dir=None,
): ):
@@ -1947,22 +1931,56 @@ def run_test(
in the install prefix bin directory or the provided work_dir in the install prefix bin directory or the provided work_dir
work_dir (str or None): path to the smoke test directory work_dir (str or None): path to the smoke test directory
""" """
def test_title(purpose, test_name):
if not purpose:
return f"test: {test_name}: execute {test_name}"
match = re.search(r"test: ([^:]*): (.*)", purpose)
if match:
# The test title has all the expected parts
return purpose
match = re.search(r"test: (.*)", purpose)
if match:
reason = match.group(1)
return f"test: {test_name}: {reason}"
return f"test: {test_name}: {purpose}"
base_exe = os.path.basename(exe)
alternate = f"Use 'test_part' instead for {self.spec.name} to process {base_exe}."
warnings.warn(f"The 'run_test' method is deprecated. {alternate}")
extra = re.compile(r"[\s,\- ]")
details = (
[extra.sub("", options)]
if isinstance(options, str)
else [extra.sub("", os.path.basename(opt)) for opt in options]
)
details = "_".join([""] + details) if details else ""
test_name = f"test_{base_exe}{details}"
tty.info(test_title(purpose, test_name), format="g")
wdir = "." if work_dir is None else work_dir wdir = "." if work_dir is None else work_dir
with fsys.working_dir(wdir, create=True): with fsys.working_dir(wdir, create=True):
try: try:
runner = which(exe) runner = which(exe)
if runner is None and skip_missing: if runner is None and skip_missing:
self.tester.status(test_name, TestStatus.SKIPPED, f"{exe} is missing")
return return
assert runner is not None, "Failed to find executable '{0}'".format(exe) assert runner is not None, f"Failed to find executable '{exe}'"
self._run_test_helper(runner, options, expected, status, installed, purpose) self._run_test_helper(runner, options, expected, status, installed, purpose)
print("PASSED") self.tester.status(test_name, TestStatus.PASSED, None)
return True return True
except BaseException as e: except (AssertionError, BaseException) as e:
# print a summary of the error to the log file # print a summary of the error to the log file
# so that cdash and junit reporters know about it # so that cdash and junit reporters know about it
exc_type, _, tb = sys.exc_info() exc_type, _, tb = sys.exc_info()
print("FAILED: {0}".format(e))
self.tester.status(test_name, TestStatus.FAILED, str(e))
import traceback import traceback
# remove the current call frame to exclude the extract_stack # remove the current call frame to exclude the extract_stack
@@ -1991,7 +2009,7 @@ def run_test(
if exc_type is spack.util.executable.ProcessError: if exc_type is spack.util.executable.ProcessError:
out = io.StringIO() out = io.StringIO()
spack.build_environment.write_log_summary( spack.build_environment.write_log_summary(
out, "test", self.test_log_file, last=1 out, "test", self.tester.test_log_file, last=1
) )
m = out.getvalue() m = out.getvalue()
else: else:
@@ -1999,7 +2017,8 @@ def run_test(
# stack instead of from traceback. # stack instead of from traceback.
# The traceback is truncated here, so we can't use it to # The traceback is truncated here, so we can't use it to
# traverse the stack. # traverse the stack.
m = "\n".join(spack.build_environment.get_package_context(tb)) context = spack.build_environment.get_package_context(tb)
m = "\n".join(context) if context else ""
exc = e # e is deleted after this block exc = e # e is deleted after this block
@@ -2007,28 +2026,27 @@ def run_test(
if spack.config.get("config:fail_fast", False): if spack.config.get("config:fail_fast", False):
raise TestFailure([(exc, m)]) raise TestFailure([(exc, m)])
else: else:
self.test_failures.append((exc, m)) self.tester.add_failure(exc, m)
return False return False
# TODO (post-34236): Remove this deprecated method when eliminate test,
# TODO (post-34236): run_test, etc.
def _run_test_helper(self, runner, options, expected, status, installed, purpose): def _run_test_helper(self, runner, options, expected, status, installed, purpose):
status = [status] if isinstance(status, int) else status status = [status] if isinstance(status, int) else status
expected = [expected] if isinstance(expected, str) else expected expected = [expected] if isinstance(expected, str) else expected
options = [options] if isinstance(options, str) else options options = [options] if isinstance(options, str) else options
if purpose:
tty.msg(purpose)
else:
tty.debug("test: {0}: expect command status in {1}".format(runner.name, status))
if installed: if installed:
msg = "Executable '{0}' expected in prefix".format(runner.name) msg = f"Executable '{runner.name}' expected in prefix, "
msg += ", found in {0} instead".format(runner.path) msg += f"found in {runner.path} instead"
assert runner.path.startswith(self.spec.prefix), msg assert runner.path.startswith(self.spec.prefix), msg
tty.msg(f"Expecting return code in {status}")
try: try:
output = runner(*options, output=str.split, error=str.split) output = runner(*options, output=str.split, error=str.split)
assert 0 in status, "Expected {0} execution to fail".format(runner.name) assert 0 in status, f"Expected {runner.name} execution to fail"
except ProcessError as err: except ProcessError as err:
output = str(err) output = str(err)
match = re.search(r"exited with status ([0-9]+)", output) match = re.search(r"exited with status ([0-9]+)", output)
@@ -2037,8 +2055,8 @@ def _run_test_helper(self, runner, options, expected, status, installed, purpose
for check in expected: for check in expected:
cmd = " ".join([runner.name] + options) cmd = " ".join([runner.name] + options)
msg = "Expected '{0}' to match output of `{1}`".format(check, cmd) msg = f"Expected '{check}' to match output of `{cmd}`"
msg += "\n\nOutput: {0}".format(output) msg += f"\n\nOutput: {output}"
assert re.search(check, output), msg assert re.search(check, output), msg
def unit_test_check(self): def unit_test_check(self):
@@ -2068,21 +2086,23 @@ def build_log_path(self):
return self.install_log_path if self.spec.installed else self.log_path return self.install_log_path if self.spec.installed else self.log_path
@classmethod @classmethod
def inject_flags(cls: Type, name: str, flags: Iterable[str]) -> FLAG_HANDLER_RETURN_TYPE: def inject_flags(cls: Type[Pb], name: str, flags: Iterable[str]) -> FLAG_HANDLER_RETURN_TYPE:
""" """
flag_handler that injects all flags through the compiler wrapper. flag_handler that injects all flags through the compiler wrapper.
""" """
return flags, None, None return flags, None, None
@classmethod @classmethod
def env_flags(cls: Type, name: str, flags: Iterable[str]): def env_flags(cls: Type[Pb], name: str, flags: Iterable[str]) -> FLAG_HANDLER_RETURN_TYPE:
""" """
flag_handler that adds all flags to canonical environment variables. flag_handler that adds all flags to canonical environment variables.
""" """
return None, flags, None return None, flags, None
@classmethod @classmethod
def build_system_flags(cls: Type, name: str, flags: Iterable[str]) -> FLAG_HANDLER_RETURN_TYPE: def build_system_flags(
cls: Type[Pb], name: str, flags: Iterable[str]
) -> FLAG_HANDLER_RETURN_TYPE:
""" """
flag_handler that passes flags to the build system arguments. Any flag_handler that passes flags to the build system arguments. Any
package using `build_system_flags` must also implement package using `build_system_flags` must also implement
@@ -2170,7 +2190,7 @@ def flag_handler(self) -> FLAG_HANDLER_TYPE:
return self._flag_handler return self._flag_handler
@flag_handler.setter @flag_handler.setter
def flag_handler(self, var: FLAG_HANDLER_TYPE): def flag_handler(self, var: FLAG_HANDLER_TYPE) -> None:
self._flag_handler = var self._flag_handler = var
# The flag handler method is called for each of the allowed compiler flags. # The flag handler method is called for each of the allowed compiler flags.
@@ -2417,165 +2437,6 @@ def rpath_args(self):
def builder(self): def builder(self):
return spack.builder.create(self) return spack.builder.create(self)
@staticmethod
def run_test_callbacks(builder, method_names, callback_type="install"):
"""Tries to call all of the listed methods, returning immediately
if the list is None."""
if not builder.pkg.run_tests or method_names is None:
return
fail_fast = spack.config.get("config:fail_fast", False)
with builder.pkg._setup_test(verbose=False, externals=False) as logger:
# Report running each of the methods in the build log
print_test_message(logger, "Running {0}-time tests".format(callback_type), True)
builder.pkg.test_suite.current_test_spec = builder.pkg.spec
builder.pkg.test_suite.current_base_spec = builder.pkg.spec
if "test" in method_names:
_copy_cached_test_files(builder.pkg, builder.pkg.spec)
for name in method_names:
try:
fn = getattr(builder, name)
msg = "RUN-TESTS: {0}-time tests [{1}]".format(callback_type, name)
print_test_message(logger, msg, True)
fn()
except AttributeError as e:
msg = "RUN-TESTS: method not implemented [{0}]".format(name)
print_test_message(logger, msg, True)
builder.pkg.test_failures.append((e, msg))
if fail_fast:
break
# Raise any collected failures here
if builder.pkg.test_failures:
raise TestFailure(builder.pkg.test_failures)
def has_test_method(pkg):
"""Determine if the package defines its own stand-alone test method.
Args:
pkg (str): the package being checked
Returns:
(bool): ``True`` if the package overrides the default method; else
``False``
"""
if not inspect.isclass(pkg):
tty.die("{0}: is not a class, it is {1}".format(pkg, type(pkg)))
return (issubclass(pkg, PackageBase) and pkg.test != PackageBase.test) or (
isinstance(pkg, PackageBase) and pkg.test.__func__ != PackageBase.test
)
def print_test_message(logger, msg, verbose):
if verbose:
with logger.force_echo():
tty.msg(msg)
else:
tty.msg(msg)
def _copy_cached_test_files(pkg, spec):
"""Copy any cached stand-alone test-related files."""
# copy installed test sources cache into test cache dir
if spec.concrete:
cache_source = spec.package.install_test_root
cache_dir = pkg.test_suite.current_test_cache_dir
if os.path.isdir(cache_source) and not os.path.exists(cache_dir):
fsys.install_tree(cache_source, cache_dir)
# copy test data into test data dir
data_source = Prefix(spec.package.package_dir).test
data_dir = pkg.test_suite.current_test_data_dir
if os.path.isdir(data_source) and not os.path.exists(data_dir):
# We assume data dir is used read-only
# maybe enforce this later
shutil.copytree(data_source, data_dir)
def test_process(pkg, kwargs):
verbose = kwargs.get("verbose", False)
externals = kwargs.get("externals", False)
with pkg._setup_test(verbose, externals) as logger:
if pkg.spec.external and not externals:
print_test_message(logger, "Skipped tests for external package", verbose)
return
if not pkg.spec.installed:
print_test_message(logger, "Skipped not installed package", verbose)
return
# run test methods from the package and all virtuals it
# provides virtuals have to be deduped by name
v_names = list(set([vspec.name for vspec in pkg.virtuals_provided]))
# hack for compilers that are not dependencies (yet)
# TODO: this all eventually goes away
c_names = ("gcc", "intel", "intel-parallel-studio", "pgi")
if pkg.name in c_names:
v_names.extend(["c", "cxx", "fortran"])
if pkg.spec.satisfies("llvm+clang"):
v_names.extend(["c", "cxx"])
test_specs = [pkg.spec] + [spack.spec.Spec(v_name) for v_name in sorted(v_names)]
ran_actual_test_function = False
try:
with fsys.working_dir(pkg.test_suite.test_dir_for_spec(pkg.spec)):
for spec in test_specs:
pkg.test_suite.current_test_spec = spec
# Fail gracefully if a virtual has no package/tests
try:
spec_pkg = spec.package
except spack.repo.UnknownPackageError:
continue
_copy_cached_test_files(pkg, spec)
# grab the function for each method so we can call
# it with the package
test_fn = spec_pkg.__class__.test
if not isinstance(test_fn, types.FunctionType):
test_fn = test_fn.__func__
# Skip any test methods consisting solely of 'pass'
# since they do not contribute to package testing.
source = (inspect.getsource(test_fn)).splitlines()[1:]
lines = (ln.strip() for ln in source)
statements = [ln for ln in lines if not ln.startswith("#")]
if len(statements) > 0 and statements[0] == "pass":
continue
# Run the tests
ran_actual_test_function = True
context = logger.force_echo if verbose else nullcontext
with context():
test_fn(pkg)
# If fail-fast was on, we error out above
# If we collect errors, raise them in batch here
if pkg.test_failures:
raise TestFailure(pkg.test_failures)
finally:
# flag the package as having been tested (i.e., ran one or more
# non-pass-only methods
if ran_actual_test_function:
fsys.touch(pkg.tested_file)
# log one more test message to provide a completion timestamp
# for CDash reporting
tty.msg("Completed testing")
else:
print_test_message(logger, "No tests to run", verbose)
inject_flags = PackageBase.inject_flags inject_flags = PackageBase.inject_flags
env_flags = PackageBase.env_flags env_flags = PackageBase.env_flags
@@ -2663,16 +2524,6 @@ def __init__(self, message, long_msg=None):
super(PackageError, self).__init__(message, long_msg) super(PackageError, self).__init__(message, long_msg)
class PackageVersionError(PackageError):
"""Raised when a version URL cannot automatically be determined."""
def __init__(self, version):
super(PackageVersionError, self).__init__(
"Cannot determine a URL automatically for version %s" % version,
"Please provide a url for this version in the package.py file.",
)
class NoURLError(PackageError): class NoURLError(PackageError):
"""Raised when someone tries to build a URL for a package with no URLs.""" """Raised when someone tries to build a URL for a package with no URLs."""

View File

@@ -241,6 +241,9 @@ def accept(self, kind: TokenType):
return True return True
return False return False
def expect(self, *kinds: TokenType):
return self.next_token and self.next_token.kind in kinds
class SpecParser: class SpecParser:
"""Parse text into specs""" """Parse text into specs"""
@@ -257,7 +260,9 @@ def tokens(self) -> List[Token]:
""" """
return list(filter(lambda x: x.kind != TokenType.WS, tokenize(self.literal_str))) return list(filter(lambda x: x.kind != TokenType.WS, tokenize(self.literal_str)))
def next_spec(self, initial_spec: Optional[spack.spec.Spec] = None) -> spack.spec.Spec: def next_spec(
self, initial_spec: Optional[spack.spec.Spec] = None
) -> Optional[spack.spec.Spec]:
"""Return the next spec parsed from text. """Return the next spec parsed from text.
Args: Args:
@@ -267,13 +272,16 @@ def next_spec(self, initial_spec: Optional[spack.spec.Spec] = None) -> spack.spe
Return Return
The spec that was parsed The spec that was parsed
""" """
if not self.ctx.next_token:
return initial_spec
initial_spec = initial_spec or spack.spec.Spec() initial_spec = initial_spec or spack.spec.Spec()
root_spec = SpecNodeParser(self.ctx).parse(initial_spec) root_spec = SpecNodeParser(self.ctx).parse(initial_spec)
while True: while True:
if self.ctx.accept(TokenType.DEPENDENCY): if self.ctx.accept(TokenType.DEPENDENCY):
dependency = SpecNodeParser(self.ctx).parse(spack.spec.Spec()) dependency = SpecNodeParser(self.ctx).parse()
if dependency == spack.spec.Spec(): if dependency is None:
msg = ( msg = (
"this dependency sigil needs to be followed by a package name " "this dependency sigil needs to be followed by a package name "
"or a node attribute (version, variant, etc.)" "or a node attribute (version, variant, etc.)"
@@ -292,7 +300,7 @@ def next_spec(self, initial_spec: Optional[spack.spec.Spec] = None) -> spack.spe
def all_specs(self) -> List[spack.spec.Spec]: def all_specs(self) -> List[spack.spec.Spec]:
"""Return all the specs that remain to be parsed""" """Return all the specs that remain to be parsed"""
return list(iter(self.next_spec, spack.spec.Spec())) return list(iter(self.next_spec, None))
class SpecNodeParser: class SpecNodeParser:
@@ -306,7 +314,7 @@ def __init__(self, ctx):
self.has_version = False self.has_version = False
self.has_hash = False self.has_hash = False
def parse(self, initial_spec: spack.spec.Spec) -> spack.spec.Spec: def parse(self, initial_spec: Optional[spack.spec.Spec] = None) -> Optional[spack.spec.Spec]:
"""Parse a single spec node from a stream of tokens """Parse a single spec node from a stream of tokens
Args: Args:
@@ -315,7 +323,10 @@ def parse(self, initial_spec: spack.spec.Spec) -> spack.spec.Spec:
Return Return
The object passed as argument The object passed as argument
""" """
import spack.environment # Needed to retrieve by hash if not self.ctx.next_token or self.ctx.expect(TokenType.DEPENDENCY):
return initial_spec
initial_spec = initial_spec or spack.spec.Spec()
# If we start with a package name we have a named spec, we cannot # If we start with a package name we have a named spec, we cannot
# accept another package name afterwards in a node # accept another package name afterwards in a node
@@ -390,27 +401,11 @@ def parse(self, initial_spec: spack.spec.Spec) -> spack.spec.Spec:
name = name.strip("'\" ") name = name.strip("'\" ")
value = value.strip("'\" ") value = value.strip("'\" ")
initial_spec._add_flag(name, value, propagate=True) initial_spec._add_flag(name, value, propagate=True)
elif not self.has_hash and self.ctx.accept(TokenType.DAG_HASH): elif self.ctx.expect(TokenType.DAG_HASH):
dag_hash = self.ctx.current_token.value[1:] if initial_spec.abstract_hash:
matches = [] break
active_env = spack.environment.active_environment() self.ctx.accept(TokenType.DAG_HASH)
if active_env: initial_spec.abstract_hash = self.ctx.current_token.value[1:]
matches = active_env.get_by_hash(dag_hash)
if not matches:
matches = spack.store.db.get_by_hash(dag_hash)
if not matches:
raise spack.spec.NoSuchHashError(dag_hash)
if len(matches) != 1:
raise spack.spec.AmbiguousHashError(
f"Multiple packages specify hash beginning '{dag_hash}'.", *matches
)
spec_by_hash = matches[0]
if not spec_by_hash.satisfies(initial_spec):
raise spack.spec.InvalidHashError(initial_spec, spec_by_hash.dag_hash())
initial_spec._dup(spec_by_hash)
self.has_hash = True
else: else:
break break
@@ -488,6 +483,11 @@ def parse_one_or_raise(
message += color.colorize(f"@*r{{{underline}}}") message += color.colorize(f"@*r{{{underline}}}")
raise ValueError(message) raise ValueError(message)
if result is None:
message = "a single spec was requested, but none was parsed:"
message += f"\n{text}"
raise ValueError(message)
return result return result

View File

@@ -37,7 +37,9 @@
def slingshot_network(): def slingshot_network():
return os.path.exists("/opt/cray/pe") and os.path.exists("/lib64/libcxi.so") return os.path.exists("/opt/cray/pe") and (
os.path.exists("/lib64/libcxi.so") or os.path.exists("/usr/lib64/libcxi.so")
)
def _target_name_from_craype_target_name(name): def _target_name_from_craype_target_name(name):

View File

@@ -6,7 +6,6 @@
import itertools import itertools
import os import os
import re import re
import shutil
from collections import OrderedDict from collections import OrderedDict
import macholib.mach_o import macholib.mach_o
@@ -356,13 +355,7 @@ def _set_elf_rpaths(target, rpaths):
# Join the paths using ':' as a separator # Join the paths using ':' as a separator
rpaths_str = ":".join(rpaths) rpaths_str = ":".join(rpaths)
# If we're relocating patchelf itself, make a copy and use it patchelf, output = executable.Executable(_patchelf()), None
bak_path = None
if target.endswith("/bin/patchelf"):
bak_path = target + ".bak"
shutil.copy(target, bak_path)
patchelf, output = executable.Executable(bak_path or _patchelf()), None
try: try:
# TODO: revisit the use of --force-rpath as it might be conditional # TODO: revisit the use of --force-rpath as it might be conditional
# TODO: if we want to support setting RUNPATH from binary packages # TODO: if we want to support setting RUNPATH from binary packages
@@ -371,9 +364,6 @@ def _set_elf_rpaths(target, rpaths):
except executable.ProcessError as e: except executable.ProcessError as e:
msg = "patchelf --force-rpath --set-rpath {0} failed with error {1}" msg = "patchelf --force-rpath --set-rpath {0} failed with error {1}"
tty.warn(msg.format(target, e)) tty.warn(msg.format(target, e))
finally:
if bak_path and os.path.exists(bak_path):
os.remove(bak_path)
return output return output

View File

@@ -1063,14 +1063,21 @@ def dump_provenance(self, spec, path):
"Repository %s does not contain package %s." % (self.namespace, spec.fullname) "Repository %s does not contain package %s." % (self.namespace, spec.fullname)
) )
# Install patch files needed by the package. package_path = self.filename_for_package_name(spec.name)
if not os.path.exists(package_path):
# Spec has no files (e.g., package, patches) to copy
tty.debug(f"{spec.name} does not have a package to dump")
return
# Install patch files needed by the (concrete) package.
fs.mkdirp(path) fs.mkdirp(path)
for patch in itertools.chain.from_iterable(spec.package.patches.values()): if spec.concrete:
if patch.path: for patch in itertools.chain.from_iterable(spec.package.patches.values()):
if os.path.exists(patch.path): if patch.path:
fs.install(patch.path, path) if os.path.exists(patch.path):
else: fs.install(patch.path, path)
tty.warn("Patch file did not exist: %s" % patch.path) else:
tty.warn("Patch file did not exist: %s" % patch.path)
# Install the package.py file itself. # Install the package.py file itself.
fs.install(self.filename_for_package_name(spec.name), path) fs.install(self.filename_for_package_name(spec.name), path)
@@ -1232,7 +1239,10 @@ def get_pkg_class(self, pkg_name):
try: try:
module = importlib.import_module(fullname) module = importlib.import_module(fullname)
except ImportError: except ImportError:
raise UnknownPackageError(pkg_name) raise UnknownPackageError(fullname)
except Exception as e:
msg = f"cannot load package '{pkg_name}' from the '{self.namespace}' repository: {e}"
raise RepoError(msg) from e
cls = getattr(module, class_name) cls = getattr(module, class_name)
if not inspect.isclass(cls): if not inspect.isclass(cls):

View File

@@ -133,8 +133,9 @@ def wrapper(instance, *args, **kwargs):
# Everything else is an error (the installation # Everything else is an error (the installation
# failed outside of the child process) # failed outside of the child process)
package["result"] = "error" package["result"] = "error"
package["stdout"] = self.fetch_log(pkg)
package["message"] = str(exc) or "Unknown error" package["message"] = str(exc) or "Unknown error"
package["stdout"] = self.fetch_log(pkg)
package["stdout"] += package["message"]
package["exception"] = traceback.format_exc() package["exception"] = traceback.format_exc()
raise raise

View File

@@ -12,7 +12,7 @@
import socket import socket
import time import time
import xml.sax.saxutils import xml.sax.saxutils
from typing import Dict from typing import Dict, Optional
from urllib.parse import urlencode from urllib.parse import urlencode
from urllib.request import HTTPHandler, Request, build_opener from urllib.request import HTTPHandler, Request, build_opener
@@ -113,14 +113,14 @@ def report_build_name(self, pkg_name):
else self.base_buildname else self.base_buildname
) )
def build_report_for_package(self, directory_name, package, duration): def build_report_for_package(self, report_dir, package, duration):
if "stdout" not in package: if "stdout" not in package:
# Skip reporting on packages that did not generate any output. # Skip reporting on packages that do not generate output.
return return
self.current_package_name = package["name"] self.current_package_name = package["name"]
self.buildname = self.report_build_name(self.current_package_name) self.buildname = self.report_build_name(self.current_package_name)
report_data = self.initialize_report(directory_name) report_data = self.initialize_report(report_dir)
for phase in CDASH_PHASES: for phase in CDASH_PHASES:
report_data[phase] = {} report_data[phase] = {}
report_data[phase]["loglines"] = [] report_data[phase]["loglines"] = []
@@ -215,7 +215,7 @@ def clean_log_event(event):
report_file_name = package["name"] + "_" + report_name report_file_name = package["name"] + "_" + report_name
else: else:
report_file_name = report_name report_file_name = report_name
phase_report = os.path.join(directory_name, report_file_name) phase_report = os.path.join(report_dir, report_file_name)
with codecs.open(phase_report, "w", "utf-8") as f: with codecs.open(phase_report, "w", "utf-8") as f:
env = spack.tengine.make_environment() env = spack.tengine.make_environment()
@@ -231,7 +231,7 @@ def clean_log_event(event):
f.write(t.render(report_data)) f.write(t.render(report_data))
self.upload(phase_report) self.upload(phase_report)
def build_report(self, directory_name, specs): def build_report(self, report_dir, specs):
# Do an initial scan to determine if we are generating reports for more # Do an initial scan to determine if we are generating reports for more
# than one package. When we're only reporting on a single package we # than one package. When we're only reporting on a single package we
# do not explicitly include the package's name in the CDash build name. # do not explicitly include the package's name in the CDash build name.
@@ -260,7 +260,7 @@ def build_report(self, directory_name, specs):
if "time" in spec: if "time" in spec:
duration = int(spec["time"]) duration = int(spec["time"])
for package in spec["packages"]: for package in spec["packages"]:
self.build_report_for_package(directory_name, package, duration) self.build_report_for_package(report_dir, package, duration)
self.finalize_report() self.finalize_report()
def extract_standalone_test_data(self, package, phases, report_data): def extract_standalone_test_data(self, package, phases, report_data):
@@ -273,13 +273,13 @@ def extract_standalone_test_data(self, package, phases, report_data):
testing["generator"] = self.generator testing["generator"] = self.generator
testing["parts"] = extract_test_parts(package["name"], package["stdout"].splitlines()) testing["parts"] = extract_test_parts(package["name"], package["stdout"].splitlines())
def report_test_data(self, directory_name, package, phases, report_data): def report_test_data(self, report_dir, package, phases, report_data):
"""Generate and upload the test report(s) for the package.""" """Generate and upload the test report(s) for the package."""
for phase in phases: for phase in phases:
# Write the report. # Write the report.
report_name = phase.capitalize() + ".xml" report_name = phase.capitalize() + ".xml"
report_file_name = package["name"] + "_" + report_name report_file_name = "_".join([package["name"], package["id"], report_name])
phase_report = os.path.join(directory_name, report_file_name) phase_report = os.path.join(report_dir, report_file_name)
with codecs.open(phase_report, "w", "utf-8") as f: with codecs.open(phase_report, "w", "utf-8") as f:
env = spack.tengine.make_environment() env = spack.tengine.make_environment()
@@ -297,7 +297,7 @@ def report_test_data(self, directory_name, package, phases, report_data):
tty.debug("Preparing to upload {0}".format(phase_report)) tty.debug("Preparing to upload {0}".format(phase_report))
self.upload(phase_report) self.upload(phase_report)
def test_report_for_package(self, directory_name, package, duration): def test_report_for_package(self, report_dir, package, duration):
if "stdout" not in package: if "stdout" not in package:
# Skip reporting on packages that did not generate any output. # Skip reporting on packages that did not generate any output.
tty.debug("Skipping report for {0}: No generated output".format(package["name"])) tty.debug("Skipping report for {0}: No generated output".format(package["name"]))
@@ -311,14 +311,14 @@ def test_report_for_package(self, directory_name, package, duration):
self.buildname = self.report_build_name(self.current_package_name) self.buildname = self.report_build_name(self.current_package_name)
self.starttime = self.endtime - duration self.starttime = self.endtime - duration
report_data = self.initialize_report(directory_name) report_data = self.initialize_report(report_dir)
report_data["hostname"] = socket.gethostname() report_data["hostname"] = socket.gethostname()
phases = ["testing"] phases = ["testing"]
self.extract_standalone_test_data(package, phases, report_data) self.extract_standalone_test_data(package, phases, report_data)
self.report_test_data(directory_name, package, phases, report_data) self.report_test_data(report_dir, package, phases, report_data)
def test_report(self, directory_name, specs): def test_report(self, report_dir, specs):
"""Generate reports for each package in each spec.""" """Generate reports for each package in each spec."""
tty.debug("Processing test report") tty.debug("Processing test report")
for spec in specs: for spec in specs:
@@ -326,21 +326,33 @@ def test_report(self, directory_name, specs):
if "time" in spec: if "time" in spec:
duration = int(spec["time"]) duration = int(spec["time"])
for package in spec["packages"]: for package in spec["packages"]:
self.test_report_for_package(directory_name, package, duration) self.test_report_for_package(report_dir, package, duration)
self.finalize_report() self.finalize_report()
def test_skipped_report(self, directory_name, spec, reason=None): def test_skipped_report(
self, report_dir: str, spec: spack.spec.Spec, reason: Optional[str] = None
):
"""Explicitly report spec as being skipped (e.g., CI).
Examples are the installation failed or the package is known to have
broken tests.
Args:
report_dir: directory where the report is to be written
spec: spec being tested
reason: optional reason the test is being skipped
"""
output = "Skipped {0} package".format(spec.name) output = "Skipped {0} package".format(spec.name)
if reason: if reason:
output += "\n{0}".format(reason) output += "\n{0}".format(reason)
package = {"name": spec.name, "id": spec.dag_hash(), "result": "skipped", "stdout": output} package = {"name": spec.name, "id": spec.dag_hash(), "result": "skipped", "stdout": output}
self.test_report_for_package(directory_name, package, duration=0.0) self.test_report_for_package(report_dir, package, duration=0.0)
def concretization_report(self, directory_name, msg): def concretization_report(self, report_dir, msg):
self.buildname = self.base_buildname self.buildname = self.base_buildname
report_data = self.initialize_report(directory_name) report_data = self.initialize_report(report_dir)
report_data["update"] = {} report_data["update"] = {}
report_data["update"]["starttime"] = self.endtime report_data["update"]["starttime"] = self.endtime
report_data["update"]["endtime"] = self.endtime report_data["update"]["endtime"] = self.endtime
@@ -350,7 +362,7 @@ def concretization_report(self, directory_name, msg):
env = spack.tengine.make_environment() env = spack.tengine.make_environment()
update_template = posixpath.join(self.template_dir, "Update.xml") update_template = posixpath.join(self.template_dir, "Update.xml")
t = env.get_template(update_template) t = env.get_template(update_template)
output_filename = os.path.join(directory_name, "Update.xml") output_filename = os.path.join(report_dir, "Update.xml")
with open(output_filename, "w") as f: with open(output_filename, "w") as f:
f.write(t.render(report_data)) f.write(t.render(report_data))
# We don't have a current package when reporting on concretization # We don't have a current package when reporting on concretization
@@ -360,9 +372,9 @@ def concretization_report(self, directory_name, msg):
self.success = False self.success = False
self.finalize_report() self.finalize_report()
def initialize_report(self, directory_name): def initialize_report(self, report_dir):
if not os.path.exists(directory_name): if not os.path.exists(report_dir):
os.mkdir(directory_name) os.mkdir(report_dir)
report_data = {} report_data = {}
report_data["buildname"] = self.buildname report_data["buildname"] = self.buildname
report_data["buildstamp"] = self.buildstamp report_data["buildstamp"] = self.buildstamp

View File

@@ -9,17 +9,23 @@
import llnl.util.tty as tty import llnl.util.tty as tty
from spack.install_test import TestStatus
# The keys here represent the only recognized (ctest/cdash) status values # The keys here represent the only recognized (ctest/cdash) status values
completed = {"failed": "Completed", "passed": "Completed", "notrun": "No tests to run"} completed = {
"failed": "Completed",
"passed": "Completed",
"skipped": "Completed",
"notrun": "No tests to run",
}
log_regexp = re.compile(r"^==> \[([0-9:.\-]*)(?:, [0-9]*)?\] (.*)") log_regexp = re.compile(r"^==> \[([0-9:.\-]*)(?:, [0-9]*)?\] (.*)")
returns_regexp = re.compile(r"\[([0-9 ,]*)\]") returns_regexp = re.compile(r"\[([0-9 ,]*)\]")
skip_msgs = ["Testing package", "Results for", "Detected the following"] skip_msgs = ["Testing package", "Results for", "Detected the following", "Warning:"]
skip_regexps = [re.compile(r"{0}".format(msg)) for msg in skip_msgs] skip_regexps = [re.compile(r"{0}".format(msg)) for msg in skip_msgs]
status_values = ["FAILED", "PASSED", "NO-TESTS"] status_regexps = [re.compile(r"^({0})".format(str(stat))) for stat in TestStatus]
status_regexps = [re.compile(r"^({0})".format(stat)) for stat in status_values]
def add_part_output(part, line): def add_part_output(part, line):
@@ -36,12 +42,14 @@ def elapsed(current, previous):
return diff.total_seconds() return diff.total_seconds()
# TODO (post-34236): Should remove with deprecated test methods since don't
# TODO (post-34236): have an XFAIL mechanism with the new test_part() approach.
def expected_failure(line): def expected_failure(line):
if not line: if not line:
return False return False
match = returns_regexp.search(line) match = returns_regexp.search(line)
xfail = "0" not in match.group(0) if match else False xfail = "0" not in match.group(1) if match else False
return xfail return xfail
@@ -54,12 +62,12 @@ def new_part():
"name": None, "name": None,
"loglines": [], "loglines": [],
"output": None, "output": None,
"status": "passed", "status": None,
} }
# TODO (post-34236): Remove this when remove deprecated methods
def part_name(source): def part_name(source):
# TODO: Should be passed the package prefix and only remove it
elements = [] elements = []
for e in source.replace("'", "").split(" "): for e in source.replace("'", "").split(" "):
elements.append(os.path.basename(e) if os.sep in e else e) elements.append(os.path.basename(e) if os.sep in e else e)
@@ -73,10 +81,14 @@ def process_part_end(part, curr_time, last_time):
stat = part["status"] stat = part["status"]
if stat in completed: if stat in completed:
# TODO (post-34236): remove the expected failure mapping when
# TODO (post-34236): remove deprecated test methods.
if stat == "passed" and expected_failure(part["desc"]): if stat == "passed" and expected_failure(part["desc"]):
part["completed"] = "Expected to fail" part["completed"] = "Expected to fail"
elif part["completed"] == "Unknown": elif part["completed"] == "Unknown":
part["completed"] = completed[stat] part["completed"] = completed[stat]
elif stat is None or stat == "unknown":
part["status"] = "passed"
part["output"] = "\n".join(part["loglines"]) part["output"] = "\n".join(part["loglines"])
@@ -96,16 +108,16 @@ def status(line):
match = regex.search(line) match = regex.search(line)
if match: if match:
stat = match.group(0) stat = match.group(0)
stat = "notrun" if stat == "NO-TESTS" else stat stat = "notrun" if stat == "NO_TESTS" else stat
return stat.lower() return stat.lower()
def extract_test_parts(default_name, outputs): def extract_test_parts(default_name, outputs):
parts = [] parts = []
part = {} part = {}
testdesc = ""
last_time = None last_time = None
curr_time = None curr_time = None
for line in outputs: for line in outputs:
line = line.strip() line = line.strip()
if not line: if not line:
@@ -115,12 +127,16 @@ def extract_test_parts(default_name, outputs):
if skip(line): if skip(line):
continue continue
# Skipped tests start with "Skipped" and end with "package" # The spec was explicitly reported as skipped (e.g., installation
# failed, package known to have failing tests, won't test external
# package).
if line.startswith("Skipped") and line.endswith("package"): if line.startswith("Skipped") and line.endswith("package"):
stat = "skipped"
part = new_part() part = new_part()
part["command"] = "Not Applicable" part["command"] = "Not Applicable"
part["completed"] = line part["completed"] = completed[stat]
part["elapsed"] = 0.0 part["elapsed"] = 0.0
part["loglines"].append(line)
part["name"] = default_name part["name"] = default_name
part["status"] = "notrun" part["status"] = "notrun"
parts.append(part) parts.append(part)
@@ -137,40 +153,53 @@ def extract_test_parts(default_name, outputs):
if msg.startswith("Installing"): if msg.startswith("Installing"):
continue continue
# New command means the start of a new test part # TODO (post-34236): Remove this check when remove run_test(),
if msg.startswith("'") and msg.endswith("'"): # TODO (post-34236): etc. since no longer supporting expected
# TODO (post-34236): failures.
if msg.startswith("Expecting return code"):
if part:
part["desc"] += f"; {msg}"
continue
# Terminate without further parsing if no more test messages
if "Completed testing" in msg:
# Process last lingering part IF it didn't generate status
process_part_end(part, curr_time, last_time)
return parts
# New test parts start "test: <name>: <desc>".
if msg.startswith("test: "):
# Update the last part processed # Update the last part processed
process_part_end(part, curr_time, last_time) process_part_end(part, curr_time, last_time)
part = new_part() part = new_part()
part["command"] = msg desc = msg.split(":")
part["name"] = part_name(msg) part["name"] = desc[1].strip()
part["desc"] = ":".join(desc[2:]).strip()
parts.append(part) parts.append(part)
# Save off the optional test description if it was # There is no guarantee of a 1-to-1 mapping of a test part and
# tty.debuged *prior to* the command and reset # a (single) command (or executable) since the introduction of
if testdesc: # PR 34236.
part["desc"] = testdesc #
testdesc = "" # Note that tests where the package does not save the output
# (e.g., output=str.split, error=str.split) will not have
# a command printed to the test log.
elif msg.startswith("'") and msg.endswith("'"):
if part:
if part["command"]:
part["command"] += "; " + msg.replace("'", "")
else:
part["command"] = msg.replace("'", "")
else:
part = new_part()
part["command"] = msg.replace("'", "")
else: else:
# Update the last part processed since a new log message # Update the last part processed since a new log message
# means a non-test action # means a non-test action
process_part_end(part, curr_time, last_time) process_part_end(part, curr_time, last_time)
if testdesc:
# We had a test description but no command so treat
# as a new part (e.g., some import tests)
part = new_part()
part["name"] = "_".join(testdesc.split())
part["command"] = "unknown"
part["desc"] = testdesc
parts.append(part)
process_part_end(part, curr_time, curr_time)
# Assuming this is a description for the next test part
testdesc = msg
else: else:
tty.debug("Did not recognize test output '{0}'".format(line)) tty.debug("Did not recognize test output '{0}'".format(line))
@@ -197,12 +226,14 @@ def extract_test_parts(default_name, outputs):
# If no parts, create a skeleton to flag that the tests are not run # If no parts, create a skeleton to flag that the tests are not run
if not parts: if not parts:
part = new_part() part = new_part()
stat = "notrun" stat = "failed" if outputs[0].startswith("Cannot open log") else "notrun"
part["command"] = "Not Applicable"
part["command"] = "unknown"
part["completed"] = completed[stat] part["completed"] = completed[stat]
part["elapsed"] = 0.0 part["elapsed"] = 0.0
part["name"] = default_name part["name"] = default_name
part["status"] = stat part["status"] = stat
part["output"] = "\n".join(outputs)
parts.append(part) parts.append(part)
return parts return parts

View File

@@ -89,6 +89,11 @@
"additionalProperties": False, "additionalProperties": False,
"properties": {"build-job": attributes_schema, "build-job-remove": attributes_schema}, "properties": {"build-job": attributes_schema, "build-job-remove": attributes_schema},
}, },
{
"type": "object",
"additionalProperties": False,
"properties": {"copy-job": attributes_schema, "copy-job-remove": attributes_schema},
},
{ {
"type": "object", "type": "object",
"additionalProperties": False, "additionalProperties": False,

View File

@@ -614,6 +614,23 @@ def multiple_values_error(self, attribute, pkg):
def no_value_error(self, attribute, pkg): def no_value_error(self, attribute, pkg):
return f'Cannot select a single "{attribute}" for package "{pkg}"' return f'Cannot select a single "{attribute}" for package "{pkg}"'
def _get_cause_tree(self, cause, conditions, condition_causes, literals, indent=" "):
parents = [c for e, c in condition_causes if e == cause]
local = "required because %s " % conditions[cause]
return [indent + local] + [
c
for parent in parents
for c in self._get_cause_tree(
parent, conditions, condition_causes, literals, indent=indent + " "
)
]
def get_cause_tree(self, cause):
conditions = dict(extract_args(self.model, "condition"))
condition_causes = list(extract_args(self.model, "condition_cause"))
return self._get_cause_tree(cause, conditions, condition_causes, [])
def handle_error(self, msg, *args): def handle_error(self, msg, *args):
"""Handle an error state derived by the solver.""" """Handle an error state derived by the solver."""
if msg == "multiple_values_error": if msg == "multiple_values_error":
@@ -622,14 +639,28 @@ def handle_error(self, msg, *args):
if msg == "no_value_error": if msg == "no_value_error":
return self.no_value_error(*args) return self.no_value_error(*args)
try:
idx = args.index("startcauses")
except ValueError:
msg_args = args
cause_args = []
else:
msg_args = args[:idx]
cause_args = args[idx + 1 :]
msg = msg.format(*msg_args)
# For variant formatting, we sometimes have to construct specs # For variant formatting, we sometimes have to construct specs
# to format values properly. Find/replace all occurances of # to format values properly. Find/replace all occurances of
# Spec(...) with the string representation of the spec mentioned # Spec(...) with the string representation of the spec mentioned
msg = msg.format(*args)
specs_to_construct = re.findall(r"Spec\(([^)]*)\)", msg) specs_to_construct = re.findall(r"Spec\(([^)]*)\)", msg)
for spec_str in specs_to_construct: for spec_str in specs_to_construct:
msg = msg.replace("Spec(%s)" % spec_str, str(spack.spec.Spec(spec_str))) msg = msg.replace("Spec(%s)" % spec_str, str(spack.spec.Spec(spec_str)))
for cause in set(cause_args):
for c in self.get_cause_tree(cause):
msg += f"\n{c}"
return msg return msg
def message(self, errors) -> str: def message(self, errors) -> str:
@@ -775,6 +806,8 @@ def visit(node):
self.control.load(os.path.join(parent_dir, "concretize.lp")) self.control.load(os.path.join(parent_dir, "concretize.lp"))
self.control.load(os.path.join(parent_dir, "os_compatibility.lp")) self.control.load(os.path.join(parent_dir, "os_compatibility.lp"))
self.control.load(os.path.join(parent_dir, "display.lp")) self.control.load(os.path.join(parent_dir, "display.lp"))
if spack.error.debug:
self.control.load(os.path.join(parent_dir, "causation.lp"))
timer.stop("load") timer.stop("load")
# Grounding is the first step in the solve -- it turns our facts # Grounding is the first step in the solve -- it turns our facts
@@ -835,7 +868,13 @@ def on_model(model):
# print any unknown functions in the model # print any unknown functions in the model
for sym in best_model: for sym in best_model:
if sym.name not in ("attr", "error", "opt_criterion"): if sym.name not in (
"attr",
"error",
"opt_criterion",
"condition",
"condition_cause",
):
tty.debug( tty.debug(
"UNKNOWN SYMBOL: %s(%s)" % (sym.name, ", ".join(stringify(sym.arguments))) "UNKNOWN SYMBOL: %s(%s)" % (sym.name, ", ".join(stringify(sym.arguments)))
) )
@@ -861,9 +900,9 @@ class SpackSolverSetup(object):
def __init__(self, tests=False): def __init__(self, tests=False):
self.gen = None # set by setup() self.gen = None # set by setup()
self.declared_versions = {} self.declared_versions = collections.defaultdict(list)
self.possible_versions = {} self.possible_versions = collections.defaultdict(set)
self.deprecated_versions = {} self.deprecated_versions = collections.defaultdict(set)
self.possible_virtuals = None self.possible_virtuals = None
self.possible_compilers = [] self.possible_compilers = []
@@ -1266,7 +1305,11 @@ def package_provider_rules(self, pkg):
for when in whens: for when in whens:
msg = "%s provides %s when %s" % (pkg.name, provided, when) msg = "%s provides %s when %s" % (pkg.name, provided, when)
condition_id = self.condition(when, provided, pkg.name, msg) condition_id = self.condition(when, provided, pkg.name, msg)
self.gen.fact(fn.provider_condition(condition_id, when.name, provided.name)) self.gen.fact(
fn.imposed_constraint(
condition_id, "virtual_condition_holds", pkg.name, provided.name
)
)
self.gen.newline() self.gen.newline()
def package_dependencies_rules(self, pkg): def package_dependencies_rules(self, pkg):
@@ -1287,16 +1330,25 @@ def package_dependencies_rules(self, pkg):
if not deptypes: if not deptypes:
continue continue
msg = "%s depends on %s" % (pkg.name, dep.spec.name) msg = "%s depends on %s" % (pkg.name, dep.spec)
if cond != spack.spec.Spec(): if cond != spack.spec.Spec():
msg += " when %s" % cond msg += " when %s" % cond
condition_id = self.condition(cond, dep.spec, pkg.name, msg) condition_id = self.condition(cond, dep.spec, pkg.name, msg)
self.gen.fact(fn.dependency_condition(condition_id, pkg.name, dep.spec.name)) self.gen.fact(fn.condition_requirement(condition_id, "spack_installed", pkg.name))
for t in sorted(deptypes): for t in sorted(deptypes):
# there is a declared dependency of type t # there is a declared dependency of type t
self.gen.fact(fn.dependency_type(condition_id, t)) self.gen.fact(
fn.imposed_constraint(
condition_id, "dependency_holds", pkg.name, dep.spec.name, t
)
)
self.gen.fact(
fn.imposed_constraint(
condition_id, "virtual_node" if dep.spec.virtual else "node", dep.spec.name
)
)
self.gen.newline() self.gen.newline()
@@ -1450,7 +1502,11 @@ def external_packages(self):
for local_idx, spec in enumerate(external_specs): for local_idx, spec in enumerate(external_specs):
msg = "%s available as external when satisfying %s" % (spec.name, spec) msg = "%s available as external when satisfying %s" % (spec.name, spec)
condition_id = self.condition(spec, msg=msg) condition_id = self.condition(spec, msg=msg)
self.gen.fact(fn.possible_external(condition_id, pkg_name, local_idx)) self.gen.fact(
fn.imposed_constraint(
condition_id, "external_conditions_hold", pkg_name, local_idx
)
)
self.possible_versions[spec.name].add(spec.version) self.possible_versions[spec.name].add(spec.version)
self.gen.newline() self.gen.newline()
@@ -1669,9 +1725,34 @@ class Body(object):
if concrete_build_deps or dtype != "build": if concrete_build_deps or dtype != "build":
clauses.append(fn.attr("depends_on", spec.name, dep.name, dtype)) clauses.append(fn.attr("depends_on", spec.name, dep.name, dtype))
# Ensure Spack will not coconcretize this with another provider # TODO: We have to look up info from package.py here, but we'd
# for the same virtual # TODO: like to avoid this entirely. We should not need to look
for virtual in dep.package.virtuals_provided: # TODO: up potentially wrong info if we have virtual edge info.
try:
try:
pkg = dep.package
except spack.repo.UnknownNamespaceError:
# Try to look up the package of the same name and use its
# providers. This is as good as we can do without edge info.
pkg_class = spack.repo.path.get_pkg_class(dep.name)
spec = spack.spec.Spec(f"{dep.name}@{dep.version}")
pkg = pkg_class(spec)
virtuals = pkg.virtuals_provided
except spack.repo.UnknownPackageError:
# Skip virtual node constriants for renamed/deleted packages,
# so their binaries can still be installed.
# NOTE: with current specs (which lack edge attributes) this
# can allow concretizations with two providers, but it's unlikely.
continue
# Don't concretize with two providers of the same virtual.
# See above for exception for unknown packages.
# TODO: we will eventually record provider information on edges,
# TODO: which avoids the need for the package lookup above.
for virtual in virtuals:
clauses.append(fn.attr("virtual_node", virtual.name)) clauses.append(fn.attr("virtual_node", virtual.name))
clauses.append(fn.provider(dep.name, virtual.name)) clauses.append(fn.provider(dep.name, virtual.name))
@@ -1697,10 +1778,6 @@ class Body(object):
def build_version_dict(self, possible_pkgs): def build_version_dict(self, possible_pkgs):
"""Declare any versions in specs not declared in packages.""" """Declare any versions in specs not declared in packages."""
self.declared_versions = collections.defaultdict(list)
self.possible_versions = collections.defaultdict(set)
self.deprecated_versions = collections.defaultdict(set)
packages_yaml = spack.config.get("packages") packages_yaml = spack.config.get("packages")
packages_yaml = _normalize_packages_yaml(packages_yaml) packages_yaml = _normalize_packages_yaml(packages_yaml)
for pkg_name in possible_pkgs: for pkg_name in possible_pkgs:
@@ -1734,13 +1811,47 @@ def key_fn(item):
# All the preferred version from packages.yaml, versions in external # All the preferred version from packages.yaml, versions in external
# specs will be computed later # specs will be computed later
version_preferences = packages_yaml.get(pkg_name, {}).get("version", []) version_preferences = packages_yaml.get(pkg_name, {}).get("version", [])
for idx, v in enumerate(version_preferences): version_defs = []
# v can be a string so force it into an actual version for comparisons pkg_class = spack.repo.path.get_pkg_class(pkg_name)
ver = vn.Version(v) for vstr in version_preferences:
v = vn.ver(vstr)
if isinstance(v, vn.GitVersion):
version_defs.append(v)
else:
satisfying_versions = self._check_for_defined_matching_versions(pkg_class, v)
# Amongst all defined versions satisfying this specific
# preference, the highest-numbered version is the
# most-preferred: therefore sort satisfying versions
# from greatest to least
version_defs.extend(sorted(satisfying_versions, reverse=True))
for weight, vdef in enumerate(llnl.util.lang.dedupe(version_defs)):
self.declared_versions[pkg_name].append( self.declared_versions[pkg_name].append(
DeclaredVersion(version=ver, idx=idx, origin=Provenance.PACKAGES_YAML) DeclaredVersion(version=vdef, idx=weight, origin=Provenance.PACKAGES_YAML)
) )
self.possible_versions[pkg_name].add(ver) self.possible_versions[pkg_name].add(vdef)
def _check_for_defined_matching_versions(self, pkg_class, v):
"""Given a version specification (which may be a concrete version,
range, etc.), determine if any package.py version declarations
or externals define a version which satisfies it.
This is primarily for determining whether a version request (e.g.
version preferences, which should not themselves define versions)
refers to a defined version.
This function raises an exception if no satisfying versions are
found.
"""
pkg_name = pkg_class.name
satisfying_versions = list(x for x in pkg_class.versions if x.satisfies(v))
satisfying_versions.extend(x for x in self.possible_versions[pkg_name] if x.satisfies(v))
if not satisfying_versions:
raise spack.config.ConfigError(
"Preference for version {0} does not match any version"
" defined for {1} (in its package.py or any external)".format(str(v), pkg_name)
)
return satisfying_versions
def add_concrete_versions_from_specs(self, specs, origin): def add_concrete_versions_from_specs(self, specs, origin):
"""Add concrete versions to possible versions from lists of CLI/dev specs.""" """Add concrete versions to possible versions from lists of CLI/dev specs."""
@@ -2173,14 +2284,6 @@ def setup(self, driver, specs, reuse=None):
# get possible compilers # get possible compilers
self.possible_compilers = self.generate_possible_compilers(specs) self.possible_compilers = self.generate_possible_compilers(specs)
# traverse all specs and packages to build dict of possible versions
self.build_version_dict(possible)
self.add_concrete_versions_from_specs(specs, Provenance.SPEC)
self.add_concrete_versions_from_specs(dev_specs, Provenance.DEV_SPEC)
req_version_specs = _get_versioned_specs_from_pkg_requirements()
self.add_concrete_versions_from_specs(req_version_specs, Provenance.PACKAGE_REQUIREMENT)
self.gen.h1("Concrete input spec definitions") self.gen.h1("Concrete input spec definitions")
self.define_concrete_input_specs(specs, possible) self.define_concrete_input_specs(specs, possible)
@@ -2208,6 +2311,14 @@ def setup(self, driver, specs, reuse=None):
self.provider_requirements() self.provider_requirements()
self.external_packages() self.external_packages()
# traverse all specs and packages to build dict of possible versions
self.build_version_dict(possible)
self.add_concrete_versions_from_specs(specs, Provenance.SPEC)
self.add_concrete_versions_from_specs(dev_specs, Provenance.DEV_SPEC)
req_version_specs = self._get_versioned_specs_from_pkg_requirements()
self.add_concrete_versions_from_specs(req_version_specs, Provenance.PACKAGE_REQUIREMENT)
self.gen.h1("Package Constraints") self.gen.h1("Package Constraints")
for pkg in sorted(self.pkgs): for pkg in sorted(self.pkgs):
self.gen.h2("Package rules: %s" % pkg) self.gen.h2("Package rules: %s" % pkg)
@@ -2239,70 +2350,106 @@ def setup(self, driver, specs, reuse=None):
self.define_target_constraints() self.define_target_constraints()
def literal_specs(self, specs): def literal_specs(self, specs):
for idx, spec in enumerate(specs): for spec in specs:
self.gen.h2("Spec: %s" % str(spec)) self.gen.h2("Spec: %s" % str(spec))
self.gen.fact(fn.literal(idx))
self.gen.fact(fn.literal(idx, "virtual_root" if spec.virtual else "root", spec.name)) # cannot use self.condition because it requires condition requirements
condition_id = next(self._condition_id_counter)
self.gen.fact(fn.condition(condition_id, "%s is provided as input spec" % spec))
self.gen.fact(fn.literal(condition_id))
self.gen.fact(fn.condition_requirement(condition_id, "literal_solved", condition_id))
self.gen.fact(
fn.imposed_constraint(
condition_id, "virtual_root" if spec.virtual else "root", spec.name
)
)
for clause in self.spec_clauses(spec): for clause in self.spec_clauses(spec):
self.gen.fact(fn.literal(idx, *clause.args)) self.gen.fact(fn.imposed_constraint(condition_id, *clause.args))
if clause.args[0] == "variant_set": if clause.args[0] == "variant_set":
self.gen.fact( self.gen.fact(
fn.literal(idx, "variant_default_value_from_cli", *clause.args[1:]) fn.imposed_constraint(
condition_id, "variant_default_value_from_cli", *clause.args[1:]
)
) )
if self.concretize_everything: if self.concretize_everything:
self.gen.fact(fn.concretize_everything()) self.gen.fact(fn.concretize_everything())
def _get_versioned_specs_from_pkg_requirements(self):
"""If package requirements mention versions that are not mentioned
elsewhere, then we need to collect those to mark them as possible
versions.
"""
req_version_specs = list()
config = spack.config.get("packages")
for pkg_name, d in config.items():
if pkg_name == "all":
continue
if "require" in d:
req_version_specs.extend(self._specs_from_requires(pkg_name, d["require"]))
return req_version_specs
def _get_versioned_specs_from_pkg_requirements(): def _specs_from_requires(self, pkg_name, section):
"""If package requirements mention versions that are not mentioned """Collect specs from requirements which define versions (i.e. those that
elsewhere, then we need to collect those to mark them as possible have a concrete version). Requirements can define *new* versions if
versions. they are included as part of an equivalence (hash=number) but not
""" otherwise.
req_version_specs = list() """
config = spack.config.get("packages") if isinstance(section, str):
for pkg_name, d in config.items(): spec = spack.spec.Spec(section)
if pkg_name == "all":
continue
if "require" in d:
req_version_specs.extend(_specs_from_requires(pkg_name, d["require"]))
return req_version_specs
def _specs_from_requires(pkg_name, section):
if isinstance(section, str):
spec = spack.spec.Spec(section)
if not spec.name:
spec.name = pkg_name
extracted_specs = [spec]
else:
spec_strs = []
for spec_group in section:
if isinstance(spec_group, str):
spec_strs.append(spec_group)
else:
# Otherwise it is an object. The object can contain a single
# "spec" constraint, or a list of them with "any_of" or
# "one_of" policy.
if "spec" in spec_group:
new_constraints = [spec_group["spec"]]
else:
key = "one_of" if "one_of" in spec_group else "any_of"
new_constraints = spec_group[key]
spec_strs.extend(new_constraints)
extracted_specs = []
for spec_str in spec_strs:
spec = spack.spec.Spec(spec_str)
if not spec.name: if not spec.name:
spec.name = pkg_name spec.name = pkg_name
extracted_specs.append(spec) extracted_specs = [spec]
else:
spec_strs = []
for spec_group in section:
if isinstance(spec_group, str):
spec_strs.append(spec_group)
else:
# Otherwise it is an object. The object can contain a single
# "spec" constraint, or a list of them with "any_of" or
# "one_of" policy.
if "spec" in spec_group:
new_constraints = [spec_group["spec"]]
else:
key = "one_of" if "one_of" in spec_group else "any_of"
new_constraints = spec_group[key]
spec_strs.extend(new_constraints)
version_specs = [x for x in extracted_specs if x.versions.concrete] extracted_specs = []
for spec in version_specs: for spec_str in spec_strs:
spec.attach_git_version_lookup() spec = spack.spec.Spec(spec_str)
return version_specs if not spec.name:
spec.name = pkg_name
extracted_specs.append(spec)
version_specs = []
for spec in extracted_specs:
if spec.versions.concrete:
# Note: this includes git versions
version_specs.append(spec)
continue
# Prefer spec's name if it exists, in case the spec is
# requiring a specific implementation inside of a virtual section
# e.g. packages:mpi:require:openmpi@4.0.1
pkg_class = spack.repo.path.get_pkg_class(spec.name or pkg_name)
satisfying_versions = self._check_for_defined_matching_versions(
pkg_class, spec.versions
)
# Version ranges ("@1.3" without the "=", "@1.2:1.4") and lists
# will end up here
ordered_satisfying_versions = sorted(satisfying_versions, reverse=True)
vspecs = list(spack.spec.Spec("@{0}".format(x)) for x in ordered_satisfying_versions)
version_specs.extend(vspecs)
for spec in version_specs:
spec.attach_git_version_lookup()
return version_specs
class SpecBuilder(object): class SpecBuilder(object):
@@ -2319,6 +2466,8 @@ class SpecBuilder(object):
r"^root$", r"^root$",
r"^virtual_node$", r"^virtual_node$",
r"^virtual_root$", r"^virtual_root$",
r"^.*holds?$",
r"^literal.*$",
] ]
) )
) )
@@ -2463,11 +2612,16 @@ def reorder_flags(self):
# add flags from each source, lowest to highest precedence # add flags from each source, lowest to highest precedence
for name in sorted_sources: for name in sorted_sources:
source = self._specs[name] if name in self._hash_specs else cmd_specs[name] all_src_flags = list()
extend_flag_list(from_sources, source.compiler_flags.get(flag_type, [])) per_pkg_sources = [self._specs[name]]
if name in cmd_specs:
per_pkg_sources.append(cmd_specs[name])
for source in per_pkg_sources:
all_src_flags.extend(source.compiler_flags.get(flag_type, []))
extend_flag_list(from_sources, all_src_flags)
# compiler flags from compilers config are lowest precedence # compiler flags from compilers config are lowest precedence
ordered_compiler_flags = from_compiler + from_sources ordered_compiler_flags = list(llnl.util.lang.dedupe(from_compiler + from_sources))
compiler_flags = spec.compiler_flags.get(flag_type, []) compiler_flags = spec.compiler_flags.get(flag_type, [])
msg = "%s does not equal %s" % (set(compiler_flags), set(ordered_compiler_flags)) msg = "%s does not equal %s" % (set(compiler_flags), set(ordered_compiler_flags))
@@ -2753,12 +2907,13 @@ class InternalConcretizerError(spack.error.UnsatisfiableSpecError):
""" """
def __init__(self, provided, conflicts): def __init__(self, provided, conflicts):
indented = [" %s\n" % conflict for conflict in conflicts] msg = (
error_msg = "".join(indented) "Spack concretizer internal error. Please submit a bug report and include the "
msg = "Spack concretizer internal error. Please submit a bug report" "command, environment if applicable and the following error message."
msg += "\n Please include the command, environment if applicable," f"\n {provided} is unsatisfiable, errors are:"
msg += "\n and the following error message." )
msg = "\n %s is unsatisfiable, errors are:\n%s" % (provided, error_msg)
msg += "".join([f"\n {conflict}" for conflict in conflicts])
super(spack.error.UnsatisfiableSpecError, self).__init__(msg) super(spack.error.UnsatisfiableSpecError, self).__init__(msg)

View File

@@ -0,0 +1,72 @@
% Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
% Spack Project Developers. See the top-level COPYRIGHT file for details.
%
% SPDX-License-Identifier: (Apache-2.0 OR MIT)
% associated conditions by cause -> effect
condition_cause(Effect, Cause) :-
condition_holds(Effect), condition_holds(Cause),
attr(Name, A1),
condition_requirement(Effect, Name, A1),
imposed_constraint(Cause, Name, A1).
condition_cause(Effect, Cause) :-
condition_holds(Effect), condition_holds(Cause),
attr(Name, A1, A2),
condition_requirement(Effect, Name, A1, A2),
imposed_constraint(Cause, Name, A1, A2).
condition_cause(Effect, Cause) :-
condition_holds(Effect), condition_holds(Cause),
attr(Name, A1, A2, A3),
condition_requirement(Effect, Name, A1, A2, A3),
imposed_constraint(Cause, Name, A1, A2, A3).
condition_cause(Effect, Cause) :-
condition_holds(Effect), condition_holds(Cause),
attr(Name, A1, A2, A3, A4),
condition_requirement(Effect, Name, A1, A2, A3, A4),
imposed_constraint(Cause, Name, A1, A2, A3, A4).
% At most one variant for single valued variants
error(0, "'{0}' required multiple values for single-valued variant '{1}'\n Requested 'Spec({1}={2})' and 'Spec({1}={3})'", Package, Variant, Value1, Value2, startcauses, Cause1, Cause2)
:- attr("node", Package),
variant(Package, Variant),
variant_single_value(Package, Variant),
build(Package),
attr("variant_value", Package, Variant, Value1),
imposed_constraint(Cause1, "variant_set", Package, Variant, Value1),
condition_holds(Cause1),
attr("variant_value", Package, Variant, Value2),
imposed_constraint(Cause2, "variant_set", Package, Variant, Value2),
condition_holds(Cause2),
Value1 < Value2. % see[1] in concretize.lp
% We cannot have a version that violates another version constraint
error(0, "Version '{0}' of {1} does not satisfy '@{2}'", Version, Package, Constraint, startcauses, VersionCause, ConstraintCause)
:- attr("node", Package),
attr("version", Package, Version),
imposed_constraint(VersionCause, "node_version_satisfies", Package, Version),
condition_holds(VersionCause),
attr("node_version_satisfies", Package, Constraint),
imposed_constraint(ConstraintCause, "node_version_satisfies", Package, Constraint),
condition_holds(ConstraintCause),
not version_satisfies(Package, Constraint, Version).
% A virtual package may or may not have a version, but never has more than one
% Error to catch how it happens
error(0, "Version '{0}' of {1} does not satisfy '@{2}'", Version, Virtual, Constraint, startcauses, VersionCause, ConstraintCause)
:- attr("virtual_node", Virtual),
attr("version", Virtual, Version),
imposed_constraint(VersionCause, "node_version_satisfies", Virtual, Version),
condition_holds(VersionCause),
attr("node_version_satisfies", Virtual, Constraint),
imposed_constraint(ConstraintCause, "node_version_satisfies", Virtual, Constraint),
condition_holds(ConstraintCause),
not version_satisfies(Virtual, Constraint, Version).
% More specific error message if the version cannot satisfy some constraint
% Otherwise covered by `no_version_error` and `versions_conflict_error`.
error(0, "Cannot satisfy '{0}@{1}'", Package, Constraint, startcauses, ConstraintCause)
:- attr("node_version_satisfies", Package, Constraint),
imposed_constraint(ConstraintCause, "node_version_satisfies", Package, Constraint),
condition_holds(ConstraintCause),
attr("version", Package, Version),
not version_satisfies(Package, Constraint, Version).

View File

@@ -12,8 +12,8 @@
%----------------------------------------------------------------------------- %-----------------------------------------------------------------------------
% Give clingo the choice to solve an input spec or not % Give clingo the choice to solve an input spec or not
{ literal_solved(ID) } :- literal(ID). { attr("literal_solved", ID) } :- literal(ID).
literal_not_solved(ID) :- not literal_solved(ID), literal(ID). literal_not_solved(ID) :- not attr("literal_solved", ID), literal(ID).
% If concretize_everything() is a fact, then we cannot have unsolved specs % If concretize_everything() is a fact, then we cannot have unsolved specs
:- literal_not_solved(ID), concretize_everything. :- literal_not_solved(ID), concretize_everything.
@@ -21,24 +21,14 @@ literal_not_solved(ID) :- not literal_solved(ID), literal(ID).
% Make a problem with "zero literals solved" unsat. This is to trigger % Make a problem with "zero literals solved" unsat. This is to trigger
% looking for solutions to the ASP problem with "errors", which results % looking for solutions to the ASP problem with "errors", which results
% in better reporting for users. See #30669 for details. % in better reporting for users. See #30669 for details.
1 { literal_solved(ID) : literal(ID) }. 1 { attr("literal_solved", ID) : literal(ID) }.
opt_criterion(300, "number of input specs not concretized"). opt_criterion(300, "number of input specs not concretized").
#minimize{ 0@300: #true }. #minimize{ 0@300: #true }.
#minimize { 1@300,ID : literal_not_solved(ID) }. #minimize { 1@300,ID : literal_not_solved(ID) }.
% Map constraint on the literal ID to the correct PSID
attr(Name, A1) :- literal(LiteralID, Name, A1), literal_solved(LiteralID).
attr(Name, A1, A2) :- literal(LiteralID, Name, A1, A2), literal_solved(LiteralID).
attr(Name, A1, A2, A3) :- literal(LiteralID, Name, A1, A2, A3), literal_solved(LiteralID).
attr(Name, A1, A2, A3, A4) :- literal(LiteralID, Name, A1, A2, A3, A4), literal_solved(LiteralID).
#defined concretize_everything/0. #defined concretize_everything/0.
#defined literal/1. #defined literal/1.
#defined literal/3.
#defined literal/4.
#defined literal/5.
#defined literal/6.
% Attributes for node packages which must have a single value % Attributes for node packages which must have a single value
attr_single_value("version"). attr_single_value("version").
@@ -58,6 +48,13 @@ error(100, multiple_values_error, Attribute, Package)
attr_single_value(Attribute), attr_single_value(Attribute),
2 { attr(Attribute, Package, Version) }. 2 { attr(Attribute, Package, Version) }.
%-----------------------------------------------------------------------------
% Define functions for error handling
%-----------------------------------------------------------------------------
#defined error/9.
#defined condition_cause/2.
%----------------------------------------------------------------------------- %-----------------------------------------------------------------------------
% Version semantics % Version semantics
%----------------------------------------------------------------------------- %-----------------------------------------------------------------------------
@@ -96,7 +93,18 @@ version_satisfies(Package, Constraint, HashVersion) :- version_satisfies(Package
{ attr("version", Package, Version) : version_declared(Package, Version) } { attr("version", Package, Version) : version_declared(Package, Version) }
:- attr("node", Package). :- attr("node", Package).
% Error to ensure structure of the program is not violated
error(2, "No version from '{0}' satisfies '@{1}' and '@{2}'", Package, Version1, Version2)
:- attr("node", Package),
attr("version", Package, Version1),
attr("version", Package, Version2),
Version1 < Version2. % see[1]
error(2, "No versions available for package '{0}'", Package)
:- attr("node", Package), not attr("version", Package, _).
% A virtual package may or may not have a version, but never has more than one % A virtual package may or may not have a version, but never has more than one
% fallback error for structure in case there's another way for it to happen
error(100, "Cannot select a single version for virtual '{0}'", Virtual) error(100, "Cannot select a single version for virtual '{0}'", Virtual)
:- attr("virtual_node", Virtual), :- attr("virtual_node", Virtual),
2 { attr("version", Virtual, Version) }. 2 { attr("version", Virtual, Version) }.
@@ -150,8 +158,7 @@ possible_version_weight(Package, Weight)
:- attr("node_version_satisfies", Package, Constraint), :- attr("node_version_satisfies", Package, Constraint),
version_satisfies(Package, Constraint, _). version_satisfies(Package, Constraint, _).
% More specific error message if the version cannot satisfy some constraint % Error for structure of program
% Otherwise covered by `no_version_error` and `versions_conflict_error`.
error(10, "Cannot satisfy '{0}@{1}'", Package, Constraint) error(10, "Cannot satisfy '{0}@{1}'", Package, Constraint)
:- attr("node_version_satisfies", Package, Constraint), :- attr("node_version_satisfies", Package, Constraint),
attr("version", Package, Version), attr("version", Package, Version),
@@ -182,9 +189,8 @@ condition_holds(ID) :-
attr(Name, A1, A2, A3) : condition_requirement(ID, Name, A1, A2, A3); attr(Name, A1, A2, A3) : condition_requirement(ID, Name, A1, A2, A3);
attr(Name, A1, A2, A3, A4) : condition_requirement(ID, Name, A1, A2, A3, A4). attr(Name, A1, A2, A3, A4) : condition_requirement(ID, Name, A1, A2, A3, A4).
% condition_holds(ID) implies all imposed_constraints, unless do_not_impose(ID) % condition_holds(ID) implies all imposed_constraints.
% is derived. This allows imposed constraints to be canceled in special cases. impose(ID) :- condition_holds(ID).
impose(ID) :- condition_holds(ID), not do_not_impose(ID).
% conditions that hold impose constraints on other specs % conditions that hold impose constraints on other specs
attr(Name, A1) :- impose(ID), imposed_constraint(ID, Name, A1). attr(Name, A1) :- impose(ID), imposed_constraint(ID, Name, A1).
@@ -229,33 +235,19 @@ depends_on(Package, Dependency) :- attr("depends_on", Package, Dependency, _).
% a dependency holds if its condition holds and if it is not external or % a dependency holds if its condition holds and if it is not external or
% concrete. We chop off dependencies for externals, and dependencies of % concrete. We chop off dependencies for externals, and dependencies of
% concrete specs don't need to be resolved -- they arise from the concrete % concrete specs don't need to be resolved -- they arise from the concrete
% specs themselves. % specs themselves. This attr is used in constraints from dependency conditions
dependency_holds(Package, Dependency, Type) :- attr("spack_installed", Package) :- build(Package), not external(Package).
dependency_condition(ID, Package, Dependency),
dependency_type(ID, Type),
build(Package),
not external(Package),
condition_holds(ID).
% We cut off dependencies of externals (as we don't really know them).
% Don't impose constraints on dependencies that don't exist.
do_not_impose(ID) :-
not dependency_holds(Package, Dependency, _),
dependency_condition(ID, Package, Dependency).
% declared dependencies are real if they're not virtual AND % declared dependencies are real if they're not virtual AND
% the package is not an external. % the package is not an external.
% They're only triggered if the associated dependnecy condition holds. % They're only triggered if the associated dependnecy condition holds.
attr("depends_on", Package, Dependency, Type) attr("depends_on", Package, Dependency, Type)
:- dependency_holds(Package, Dependency, Type), :- attr("dependency_holds", Package, Dependency, Type),
not virtual(Dependency). not virtual(Dependency).
% every root must be a node % every root must be a node
attr("node", Package) :- attr("root", Package). attr("node", Package) :- attr("root", Package).
% dependencies imply new nodes
attr("node", Dependency) :- attr("node", Package), depends_on(Package, Dependency).
% all nodes in the graph must be reachable from some root % all nodes in the graph must be reachable from some root
% this ensures a user can't say `zlib ^libiconv` (neither of which have any % this ensures a user can't say `zlib ^libiconv` (neither of which have any
% dependencies) and get a two-node unconnected graph % dependencies) and get a two-node unconnected graph
@@ -296,14 +288,17 @@ error(1, Msg) :- attr("node", Package),
% if a package depends on a virtual, it's not external and we have a % if a package depends on a virtual, it's not external and we have a
% provider for that virtual then it depends on the provider % provider for that virtual then it depends on the provider
attr("depends_on", Package, Provider, Type) attr("depends_on", Package, Provider, Type)
:- dependency_holds(Package, Virtual, Type), :- attr("dependency_holds", Package, Virtual, Type),
provider(Provider, Virtual), provider(Provider, Virtual),
not external(Package). not external(Package).
% dependencies on virtuals also imply that the virtual is a virtual node % If a package depends on a provider, the provider must be a node
attr("virtual_node", Virtual) % nodes that are not indirected by a virtual are instantiated
:- dependency_holds(Package, Virtual, Type), % directly from the imposed constraints of the dependency condition
virtual(Virtual), not external(Package). attr("node", Provider)
:- attr("dependency_holds", Package, Virtual, Type),
provider(Provider, Virtual),
not external(Package).
% If there's a virtual node, we must select one and only one provider. % If there's a virtual node, we must select one and only one provider.
% The provider must be selected among the possible providers. % The provider must be selected among the possible providers.
@@ -330,17 +325,11 @@ attr("root", Package) :- attr("virtual_root", Virtual), provider(Package, Virtua
% for environments that are concretized together (e.g. where we % for environments that are concretized together (e.g. where we
% asks to install "mpich" and "hdf5+mpi" and we want "mpich" to % asks to install "mpich" and "hdf5+mpi" and we want "mpich" to
% be the mpi provider) % be the mpi provider)
provider(Package, Virtual) :- attr("node", Package), virtual_condition_holds(Package, Virtual). provider(Package, Virtual) :- attr("node", Package), attr("virtual_condition_holds", Package, Virtual).
% The provider provides the virtual if some provider condition holds.
virtual_condition_holds(Provider, Virtual) :-
provider_condition(ID, Provider, Virtual),
condition_holds(ID),
virtual(Virtual).
% A package cannot be the actual provider for a virtual if it does not % A package cannot be the actual provider for a virtual if it does not
% fulfill the conditions to provide that virtual % fulfill the conditions to provide that virtual
:- provider(Package, Virtual), not virtual_condition_holds(Package, Virtual), :- provider(Package, Virtual), not attr("virtual_condition_holds", Package, Virtual),
internal_error("Virtual when provides not respected"). internal_error("Virtual when provides not respected").
#defined possible_provider/2. #defined possible_provider/2.
@@ -382,14 +371,8 @@ possible_provider_weight(Dependency, Virtual, 100, "fallback") :- provider(Depen
% do not warn if generated program contains none of these. % do not warn if generated program contains none of these.
#defined possible_provider/2. #defined possible_provider/2.
#defined provider_condition/3.
#defined required_provider_condition/3.
#defined required_provider_condition/4.
#defined required_provider_condition/5.
#defined required_provider_condition/6.
#defined declared_dependency/3. #defined declared_dependency/3.
#defined virtual/1. #defined virtual/1.
#defined virtual_condition_holds/2.
#defined external/1. #defined external/1.
#defined external_spec/2. #defined external_spec/2.
#defined external_version_declared/4. #defined external_version_declared/4.
@@ -437,25 +420,15 @@ external(Package) :- attr("external_spec_selected", Package, _).
% determine if an external spec has been selected % determine if an external spec has been selected
attr("external_spec_selected", Package, LocalIndex) :- attr("external_spec_selected", Package, LocalIndex) :-
external_conditions_hold(Package, LocalIndex), attr("external_conditions_hold", Package, LocalIndex),
attr("node", Package), attr("node", Package),
not attr("hash", Package, _). not attr("hash", Package, _).
external_conditions_hold(Package, LocalIndex) :-
possible_external(ID, Package, LocalIndex), condition_holds(ID).
% it cannot happen that a spec is external, but none of the external specs % it cannot happen that a spec is external, but none of the external specs
% conditions hold. % conditions hold.
error(100, "Attempted to use external for '{0}' which does not satisfy any configured external spec", Package) error(100, "Attempted to use external for '{0}' which does not satisfy any configured external spec", Package)
:- external(Package), :- external(Package),
not external_conditions_hold(Package, _). not attr("external_conditions_hold", Package, _).
#defined possible_external/3.
#defined external_spec_index/3.
#defined external_spec_condition/3.
#defined external_spec_condition/4.
#defined external_spec_condition/5.
#defined external_spec_condition/6.
%----------------------------------------------------------------------------- %-----------------------------------------------------------------------------
% Config required semantics % Config required semantics
@@ -494,6 +467,19 @@ requirement_group_satisfied(Package, X) :-
activate_requirement(Package, X), activate_requirement(Package, X),
requirement_group(Package, X). requirement_group(Package, X).
% TODO: the following two choice rules allow the solver to add compiler
% flags if their only source is from a requirement. This is overly-specific
% and should use a more-generic approach like in https://github.com/spack/spack/pull/37180
{ attr("node_flag", A1, A2, A3) } :-
requirement_group_member(Y, Package, X),
activate_requirement(Package, X),
imposed_constraint(Y,"node_flag_set", A1, A2, A3).
{ attr("node_flag_source", A1, A2, A3) } :-
requirement_group_member(Y, Package, X),
activate_requirement(Package, X),
imposed_constraint(Y,"node_flag_source", A1, A2, A3).
requirement_weight(Package, Group, W) :- requirement_weight(Package, Group, W) :-
W = #min { W = #min {
Z : requirement_has_weight(Y, Z), condition_holds(Y), requirement_group_member(Y, Package, Group); Z : requirement_has_weight(Y, Z), condition_holds(Y), requirement_group_member(Y, Package, Group);
@@ -581,7 +567,6 @@ attr("variant_value", Package, Variant, Value) :-
variant(Package, Variant), variant(Package, Variant),
build(Package). build(Package).
error(100, "'{0}' required multiple values for single-valued variant '{1}'", Package, Variant) error(100, "'{0}' required multiple values for single-valued variant '{1}'", Package, Variant)
:- attr("node", Package), :- attr("node", Package),
variant(Package, Variant), variant(Package, Variant),
@@ -652,7 +637,7 @@ variant_default_not_used(Package, Variant, Value)
external_with_variant_set(Package, Variant, Value) external_with_variant_set(Package, Variant, Value)
:- attr("variant_value", Package, Variant, Value), :- attr("variant_value", Package, Variant, Value),
condition_requirement(ID, "variant_value", Package, Variant, Value), condition_requirement(ID, "variant_value", Package, Variant, Value),
possible_external(ID, Package, _), imposed_constraint(ID, "external_conditions_hold", Package, _),
external(Package), external(Package),
attr("node", Package). attr("node", Package).

View File

@@ -23,5 +23,12 @@
#show error/4. #show error/4.
#show error/5. #show error/5.
#show error/6. #show error/6.
#show error/7.
#show error/8.
#show error/9.
% show cause -> effect data for errors
#show condition_cause/2.
#show condition/2.
% debug % debug

View File

@@ -110,7 +110,6 @@
"UnsatisfiableDependencySpecError", "UnsatisfiableDependencySpecError",
"AmbiguousHashError", "AmbiguousHashError",
"InvalidHashError", "InvalidHashError",
"NoSuchHashError",
"RedundantSpecError", "RedundantSpecError",
"SpecDeprecatedError", "SpecDeprecatedError",
] ]
@@ -145,9 +144,20 @@
#: ``color_formats.keys()``. #: ``color_formats.keys()``.
_separators = "[\\%s]" % "\\".join(color_formats.keys()) _separators = "[\\%s]" % "\\".join(color_formats.keys())
default_format = "{name}{@versions}" #: Default format for Spec.format(). This format can be round-tripped, so that:
default_format += "{%compiler.name}{@compiler.versions}{compiler_flags}" #: Spec(Spec("string").format()) == Spec("string)"
default_format += "{variants}{arch=architecture}" default_format = (
"{name}{@versions}"
"{%compiler.name}{@compiler.versions}{compiler_flags}"
"{variants}{arch=architecture}{/abstract_hash}"
)
#: Display format, which eliminates extra `@=` in the output, for readability.
display_format = (
"{name}{@version}"
"{%compiler.name}{@compiler.version}{compiler_flags}"
"{variants}{arch=architecture}{/abstract_hash}"
)
#: Regular expression to pull spec contents out of clearsigned signature #: Regular expression to pull spec contents out of clearsigned signature
#: file. #: file.
@@ -669,6 +679,16 @@ def from_dict(d):
d = d["compiler"] d = d["compiler"]
return CompilerSpec(d["name"], vn.VersionList.from_dict(d)) return CompilerSpec(d["name"], vn.VersionList.from_dict(d))
@property
def display_str(self):
"""Equivalent to {compiler.name}{@compiler.version} for Specs, without extra
@= for readability."""
if self.concrete:
return f"{self.name}@{self.version}"
elif self.versions != vn.any_version:
return f"{self.name}@{self.versions}"
return self.name
def __str__(self): def __str__(self):
out = self.name out = self.name
if self.versions and self.versions != vn.any_version: if self.versions and self.versions != vn.any_version:
@@ -1249,6 +1269,7 @@ def copy(self, *args, **kwargs):
class Spec(object): class Spec(object):
#: Cache for spec's prefix, computed lazily in the corresponding property #: Cache for spec's prefix, computed lazily in the corresponding property
_prefix = None _prefix = None
abstract_hash = None
@staticmethod @staticmethod
def default_arch(): def default_arch():
@@ -1556,7 +1577,7 @@ def _set_compiler(self, compiler):
def _add_dependency(self, spec: "Spec", *, deptypes: dp.DependencyArgument): def _add_dependency(self, spec: "Spec", *, deptypes: dp.DependencyArgument):
"""Called by the parser to add another spec as a dependency.""" """Called by the parser to add another spec as a dependency."""
if spec.name not in self._dependencies: if spec.name not in self._dependencies or not spec.name:
self.add_dependency_edge(spec, deptypes=deptypes) self.add_dependency_edge(spec, deptypes=deptypes)
return return
@@ -1617,6 +1638,10 @@ def fullname(self):
else (self.name if self.name else "") else (self.name if self.name else "")
) )
@property
def anonymous(self):
return not self.name and not self.abstract_hash
@property @property
def root(self): def root(self):
"""Follow dependent links and find the root of this spec's DAG. """Follow dependent links and find the root of this spec's DAG.
@@ -1632,7 +1657,9 @@ def root(self):
@property @property
def package(self): def package(self):
assert self.concrete, "Spec.package can only be called on concrete specs" assert self.concrete, "{0}: Spec.package can only be called on concrete specs".format(
self.name
)
if not self._package: if not self._package:
self._package = spack.repo.path.get(self) self._package = spack.repo.path.get(self)
return self._package return self._package
@@ -1713,14 +1740,14 @@ def traverse_edges(self, **kwargs):
def short_spec(self): def short_spec(self):
"""Returns a version of the spec with the dependencies hashed """Returns a version of the spec with the dependencies hashed
instead of completely enumerated.""" instead of completely enumerated."""
spec_format = "{name}{@version}{%compiler}" spec_format = "{name}{@version}{%compiler.name}{@compiler.version}"
spec_format += "{variants}{arch=architecture}{/hash:7}" spec_format += "{variants}{arch=architecture}{/hash:7}"
return self.format(spec_format) return self.format(spec_format)
@property @property
def cshort_spec(self): def cshort_spec(self):
"""Returns an auto-colorized version of ``self.short_spec``.""" """Returns an auto-colorized version of ``self.short_spec``."""
spec_format = "{name}{@version}{%compiler}" spec_format = "{name}{@version}{%compiler.name}{@compiler.version}"
spec_format += "{variants}{arch=architecture}{/hash:7}" spec_format += "{variants}{arch=architecture}{/hash:7}"
return self.cformat(spec_format) return self.cformat(spec_format)
@@ -1823,6 +1850,73 @@ def process_hash_bit_prefix(self, bits):
"""Get the first <bits> bits of the DAG hash as an integer type.""" """Get the first <bits> bits of the DAG hash as an integer type."""
return spack.util.hash.base32_prefix_bits(self.process_hash(), bits) return spack.util.hash.base32_prefix_bits(self.process_hash(), bits)
def _lookup_hash(self):
"""Lookup just one spec with an abstract hash, returning a spec from the the environment,
store, or finally, binary caches."""
import spack.environment
matches = []
active_env = spack.environment.active_environment()
if active_env:
env_matches = active_env.get_by_hash(self.abstract_hash) or []
matches = [m for m in env_matches if m._satisfies(self)]
if not matches:
db_matches = spack.store.db.get_by_hash(self.abstract_hash) or []
matches = [m for m in db_matches if m._satisfies(self)]
if not matches:
query = spack.binary_distribution.BinaryCacheQuery(True)
remote_matches = query("/" + self.abstract_hash) or []
matches = [m for m in remote_matches if m._satisfies(self)]
if not matches:
raise InvalidHashError(self, self.abstract_hash)
if len(matches) != 1:
raise spack.spec.AmbiguousHashError(
f"Multiple packages specify hash beginning '{self.abstract_hash}'.", *matches
)
return matches[0]
def lookup_hash(self):
"""Given a spec with an abstract hash, return a copy of the spec with all properties and
dependencies by looking up the hash in the environment, store, or finally, binary caches.
This is non-destructive."""
if self.concrete or not any(node.abstract_hash for node in self.traverse()):
return self
spec = self.copy(deps=False)
# root spec is replaced
if spec.abstract_hash:
new = self._lookup_hash()
spec._dup(new)
return spec
# Get dependencies that need to be replaced
for node in self.traverse(root=False):
if node.abstract_hash:
new = node._lookup_hash()
spec._add_dependency(new, deptypes=())
# reattach nodes that were not otherwise satisfied by new dependencies
for node in self.traverse(root=False):
if not any(n._satisfies(node) for n in spec.traverse()):
spec._add_dependency(node.copy(), deptypes=())
return spec
def replace_hash(self):
"""Given a spec with an abstract hash, attempt to populate all properties and dependencies
by looking up the hash in the environment, store, or finally, binary caches.
This is destructive."""
if not any(node for node in self.traverse(order="post") if node.abstract_hash):
return
spec_by_hash = self.lookup_hash()
self._dup(spec_by_hash)
def to_node_dict(self, hash=ht.dag_hash): def to_node_dict(self, hash=ht.dag_hash):
"""Create a dictionary representing the state of this Spec. """Create a dictionary representing the state of this Spec.
@@ -2581,6 +2675,8 @@ def _old_concretize(self, tests=False, deprecation_warning=True):
) )
warnings.warn(msg) warnings.warn(msg)
self.replace_hash()
if not self.name: if not self.name:
raise spack.error.SpecError("Attempting to concretize anonymous spec") raise spack.error.SpecError("Attempting to concretize anonymous spec")
@@ -2703,11 +2799,11 @@ def inject_patches_variant(root):
# Also record all patches required on dependencies by # Also record all patches required on dependencies by
# depends_on(..., patch=...) # depends_on(..., patch=...)
for dspec in root.traverse_edges(deptype=all, cover="edges", root=False): for dspec in root.traverse_edges(deptype=all, cover="edges", root=False):
pkg_deps = dspec.parent.package_class.dependencies if dspec.spec.concrete:
if dspec.spec.name not in pkg_deps:
continue continue
if dspec.spec.concrete: pkg_deps = dspec.parent.package_class.dependencies
if dspec.spec.name not in pkg_deps:
continue continue
patches = [] patches = []
@@ -2779,8 +2875,13 @@ def ensure_no_deprecated(root):
def _new_concretize(self, tests=False): def _new_concretize(self, tests=False):
import spack.solver.asp import spack.solver.asp
if not self.name: self.replace_hash()
raise spack.error.SpecError("Spec has no name; cannot concretize an anonymous spec")
for node in self.traverse():
if not node.name:
raise spack.error.SpecError(
f"Spec {node} has no name; cannot concretize an anonymous spec"
)
if self._concrete: if self._concrete:
return return
@@ -3363,6 +3464,11 @@ def constrain(self, other, deps=True):
raise spack.error.UnsatisfiableSpecError(self, other, "constrain a concrete spec") raise spack.error.UnsatisfiableSpecError(self, other, "constrain a concrete spec")
other = self._autospec(other) other = self._autospec(other)
if other.abstract_hash:
if not self.abstract_hash or other.abstract_hash.startswith(self.abstract_hash):
self.abstract_hash = other.abstract_hash
elif not self.abstract_hash.startswith(other.abstract_hash):
raise InvalidHashError(self, other.abstract_hash)
if not (self.name == other.name or (not self.name) or (not other.name)): if not (self.name == other.name or (not self.name) or (not other.name)):
raise UnsatisfiableSpecNameError(self.name, other.name) raise UnsatisfiableSpecNameError(self.name, other.name)
@@ -3521,6 +3627,12 @@ def intersects(self, other: "Spec", deps: bool = True) -> bool:
""" """
other = self._autospec(other) other = self._autospec(other)
lhs = self.lookup_hash() or self
rhs = other.lookup_hash() or other
return lhs._intersects(rhs, deps)
def _intersects(self, other: "Spec", deps: bool = True) -> bool:
if other.concrete and self.concrete: if other.concrete and self.concrete:
return self.dag_hash() == other.dag_hash() return self.dag_hash() == other.dag_hash()
@@ -3586,9 +3698,18 @@ def intersects(self, other: "Spec", deps: bool = True) -> bool:
else: else:
return True return True
def _intersects_dependencies(self, other): def satisfies(self, other, deps=True):
"""
This checks constraints on common dependencies against each other.
"""
other = self._autospec(other) other = self._autospec(other)
lhs = self.lookup_hash() or self
rhs = other.lookup_hash() or other
return lhs._satisfies(rhs, deps=deps)
def _intersects_dependencies(self, other):
if not other._dependencies or not self._dependencies: if not other._dependencies or not self._dependencies:
# one spec *could* eventually satisfy the other # one spec *could* eventually satisfy the other
return True return True
@@ -3623,7 +3744,7 @@ def _intersects_dependencies(self, other):
return True return True
def satisfies(self, other: "Spec", deps: bool = True) -> bool: def _satisfies(self, other: "Spec", deps: bool = True) -> bool:
"""Return True if all concrete specs matching self also match other, otherwise False. """Return True if all concrete specs matching self also match other, otherwise False.
Args: Args:
@@ -3768,6 +3889,7 @@ def _dup(self, other, deps=True, cleardeps=True):
and self.external_path != other.external_path and self.external_path != other.external_path
and self.external_modules != other.external_modules and self.external_modules != other.external_modules
and self.compiler_flags != other.compiler_flags and self.compiler_flags != other.compiler_flags
and self.abstract_hash != other.abstract_hash
) )
self._package = None self._package = None
@@ -3810,6 +3932,8 @@ def _dup(self, other, deps=True, cleardeps=True):
self._concrete = other._concrete self._concrete = other._concrete
self.abstract_hash = other.abstract_hash
if self._concrete: if self._concrete:
self._dunder_hash = other._dunder_hash self._dunder_hash = other._dunder_hash
self._normal = other._normal self._normal = other._normal
@@ -3999,6 +4123,7 @@ def _cmp_node(self):
yield self.compiler yield self.compiler
yield self.compiler_flags yield self.compiler_flags
yield self.architecture yield self.architecture
yield self.abstract_hash
# this is not present on older specs # this is not present on older specs
yield getattr(self, "_package_hash", None) yield getattr(self, "_package_hash", None)
@@ -4009,7 +4134,10 @@ def eq_node(self, other):
def _cmp_iter(self): def _cmp_iter(self):
"""Lazily yield components of self for comparison.""" """Lazily yield components of self for comparison."""
for item in self._cmp_node():
cmp_spec = self.lookup_hash() or self
for item in cmp_spec._cmp_node():
yield item yield item
# This needs to be in _cmp_iter so that no specs with different process hashes # This needs to be in _cmp_iter so that no specs with different process hashes
@@ -4020,10 +4148,10 @@ def _cmp_iter(self):
# TODO: they exist for speed. We should benchmark whether it's really worth # TODO: they exist for speed. We should benchmark whether it's really worth
# TODO: having two types of hashing now that we use `json` instead of `yaml` for # TODO: having two types of hashing now that we use `json` instead of `yaml` for
# TODO: spec hashing. # TODO: spec hashing.
yield self.process_hash() if self.concrete else None yield cmp_spec.process_hash() if cmp_spec.concrete else None
def deps(): def deps():
for dep in sorted(itertools.chain.from_iterable(self._dependencies.values())): for dep in sorted(itertools.chain.from_iterable(cmp_spec._dependencies.values())):
yield dep.spec.name yield dep.spec.name
yield tuple(sorted(dep.deptypes)) yield tuple(sorted(dep.deptypes))
yield hash(dep.spec) yield hash(dep.spec)
@@ -4144,7 +4272,7 @@ def write_attribute(spec, attribute, color):
raise SpecFormatSigilError(sig, "versions", attribute) raise SpecFormatSigilError(sig, "versions", attribute)
elif sig == "%" and attribute not in ("compiler", "compiler.name"): elif sig == "%" and attribute not in ("compiler", "compiler.name"):
raise SpecFormatSigilError(sig, "compilers", attribute) raise SpecFormatSigilError(sig, "compilers", attribute)
elif sig == "/" and not re.match(r"hash(:\d+)?$", attribute): elif sig == "/" and not re.match(r"(abstract_)?hash(:\d+)?$", attribute):
raise SpecFormatSigilError(sig, "DAG hashes", attribute) raise SpecFormatSigilError(sig, "DAG hashes", attribute)
elif sig == " arch=" and attribute not in ("architecture", "arch"): elif sig == " arch=" and attribute not in ("architecture", "arch"):
raise SpecFormatSigilError(sig, "the architecture", attribute) raise SpecFormatSigilError(sig, "the architecture", attribute)
@@ -4205,7 +4333,7 @@ def write_attribute(spec, attribute, color):
if callable(current): if callable(current):
raise SpecFormatStringError("Attempted to format callable object") raise SpecFormatStringError("Attempted to format callable object")
if not current: if current is None:
# We're not printing anything # We're not printing anything
return return
@@ -4264,7 +4392,9 @@ def cformat(self, *args, **kwargs):
return self.format(*args, **kwargs) return self.format(*args, **kwargs)
def __str__(self): def __str__(self):
sorted_nodes = [self] + sorted(self.traverse(root=False), key=lambda x: x.name) sorted_nodes = [self] + sorted(
self.traverse(root=False), key=lambda x: x.name or x.abstract_hash
)
spec_str = " ^".join(d.format() for d in sorted_nodes) spec_str = " ^".join(d.format() for d in sorted_nodes)
return spec_str.strip() return spec_str.strip()
@@ -5064,14 +5194,9 @@ def __init__(self, msg, *specs):
class InvalidHashError(spack.error.SpecError): class InvalidHashError(spack.error.SpecError):
def __init__(self, spec, hash): def __init__(self, spec, hash):
super(InvalidHashError, self).__init__( msg = f"No spec with hash {hash} could be found to match {spec}."
"The spec specified by %s does not match provided spec %s" % (hash, spec) msg += " Either the hash does not exist, or it does not match other spec constraints."
) super(InvalidHashError, self).__init__(msg)
class NoSuchHashError(spack.error.SpecError):
def __init__(self, hash):
super(NoSuchHashError, self).__init__("No installed spec matches the hash: '%s'" % hash)
class SpecFilenameError(spack.error.SpecError): class SpecFilenameError(spack.error.SpecError):

View File

@@ -4,7 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import itertools import itertools
import textwrap import textwrap
from typing import List from typing import List, Optional, Tuple
import llnl.util.lang import llnl.util.lang
@@ -66,17 +66,17 @@ def to_dict(self):
return dict(d) return dict(d)
def make_environment(dirs=None): @llnl.util.lang.memoized
"""Returns an configured environment for template rendering.""" def make_environment(dirs: Optional[Tuple[str, ...]] = None):
"""Returns a configured environment for template rendering."""
# Import at this scope to avoid slowing Spack startup down
import jinja2
if dirs is None: if dirs is None:
# Default directories where to search for templates # Default directories where to search for templates
builtins = spack.config.get("config:template_dirs", ["$spack/share/spack/templates"]) builtins = spack.config.get("config:template_dirs", ["$spack/share/spack/templates"])
extensions = spack.extensions.get_template_dirs() extensions = spack.extensions.get_template_dirs()
dirs = [canonicalize_path(d) for d in itertools.chain(builtins, extensions)] dirs = tuple(canonicalize_path(d) for d in itertools.chain(builtins, extensions))
# avoid importing this at the top level as it's used infrequently and
# slows down startup a bit.
import jinja2
# Loader for the templates # Loader for the templates
loader = jinja2.FileSystemLoader(dirs) loader = jinja2.FileSystemLoader(dirs)

View File

@@ -21,7 +21,7 @@
(["wrong-variant-in-depends-on"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]), (["wrong-variant-in-depends-on"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
# This package has a GitHub patch URL without full_index=1 # This package has a GitHub patch URL without full_index=1
(["invalid-github-patch-url"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]), (["invalid-github-patch-url"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
# This package has a stand-alone 'test' method in build-time callbacks # This package has a stand-alone 'test*' method in build-time callbacks
(["fail-test-audit"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]), (["fail-test-audit"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
# This package has no issues # This package has no issues
(["mpileaks"], None), (["mpileaks"], None),

View File

@@ -7,6 +7,8 @@
import pytest import pytest
from llnl.util.filesystem import touch
import spack.paths import spack.paths
@@ -125,6 +127,7 @@ def test_build_time_tests_are_executed_from_default_builder():
@pytest.mark.regression("34518") @pytest.mark.regression("34518")
@pytest.mark.usefixtures("builder_test_repository", "config", "working_env") @pytest.mark.usefixtures("builder_test_repository", "config", "working_env")
def test_monkey_patching_wrapped_pkg(): def test_monkey_patching_wrapped_pkg():
"""Confirm 'run_tests' is accessible through wrappers."""
s = spack.spec.Spec("old-style-autotools").concretized() s = spack.spec.Spec("old-style-autotools").concretized()
builder = spack.builder.create(s.package) builder = spack.builder.create(s.package)
assert s.package.run_tests is False assert s.package.run_tests is False
@@ -139,12 +142,29 @@ def test_monkey_patching_wrapped_pkg():
@pytest.mark.regression("34440") @pytest.mark.regression("34440")
@pytest.mark.usefixtures("builder_test_repository", "config", "working_env") @pytest.mark.usefixtures("builder_test_repository", "config", "working_env")
def test_monkey_patching_test_log_file(): def test_monkey_patching_test_log_file():
"""Confirm 'test_log_file' is accessible through wrappers."""
s = spack.spec.Spec("old-style-autotools").concretized() s = spack.spec.Spec("old-style-autotools").concretized()
builder = spack.builder.create(s.package) builder = spack.builder.create(s.package)
assert s.package.test_log_file is None
assert builder.pkg.test_log_file is None
assert builder.pkg_with_dispatcher.test_log_file is None
s.package.test_log_file = "/some/file" s.package.tester.test_log_file = "/some/file"
assert builder.pkg.test_log_file == "/some/file" assert builder.pkg.tester.test_log_file == "/some/file"
assert builder.pkg_with_dispatcher.test_log_file == "/some/file" assert builder.pkg_with_dispatcher.tester.test_log_file == "/some/file"
# Windows context manager's __exit__ fails with ValueError ("I/O operation
# on closed file").
@pytest.mark.skipif(sys.platform == "win32", reason="Does not run on windows")
def test_install_time_test_callback(tmpdir, config, mock_packages, mock_stage):
"""Confirm able to run stand-alone test as a post-install callback."""
s = spack.spec.Spec("py-test-callback").concretized()
builder = spack.builder.create(s.package)
builder.pkg.run_tests = True
s.package.tester.test_log_file = tmpdir.join("install_test.log")
touch(s.package.tester.test_log_file)
for phase_fn in builder:
phase_fn.execute()
with open(s.package.tester.test_log_file, "r") as f:
results = f.read().replace("\n", " ")
assert "PyTestCallback test" in results

View File

@@ -566,8 +566,7 @@ def test_ci_run_standalone_tests_not_installed_cdash(
ci.run_standalone_tests(**args) ci.run_standalone_tests(**args)
out = capfd.readouterr()[0] out = capfd.readouterr()[0]
# CDash *and* log file output means log file ignored # CDash *and* log file output means log file ignored
assert "xml option is ignored" in out assert "xml option is ignored with CDash" in out
assert "0 passed of 0" in out
# copy test results (though none) # copy test results (though none)
artifacts_dir = tmp_path / "artifacts" artifacts_dir = tmp_path / "artifacts"
@@ -595,9 +594,10 @@ def test_ci_skipped_report(tmpdir, mock_packages, config):
reason = "Testing skip" reason = "Testing skip"
handler.report_skipped(spec, tmpdir.strpath, reason=reason) handler.report_skipped(spec, tmpdir.strpath, reason=reason)
report = fs.join_path(tmpdir, "{0}_Testing.xml".format(pkg)) reports = [name for name in tmpdir.listdir() if str(name).endswith("Testing.xml")]
expected = "Skipped {0} package".format(pkg) assert len(reports) == 1
with open(report, "r") as f: expected = f"Skipped {pkg} package"
with open(reports[0], "r") as f:
have = [0, 0] have = [0, 0]
for line in f: for line in f:
if expected in line: if expected in line:

View File

@@ -3,6 +3,7 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import pickle import pickle
import sys
import pytest import pytest
@@ -39,7 +40,10 @@ def test_dump(tmpdir):
with tmpdir.as_cwd(): with tmpdir.as_cwd():
build_env("--dump", _out_file, "zlib") build_env("--dump", _out_file, "zlib")
with open(_out_file) as f: with open(_out_file) as f:
assert any(line.startswith("PATH=") for line in f.readlines()) if sys.platform == "win32":
assert any(line.startswith('set "PATH=') for line in f.readlines())
else:
assert any(line.startswith("PATH=") for line in f.readlines())
@pytest.mark.usefixtures("config", "mock_packages", "working_env") @pytest.mark.usefixtures("config", "mock_packages", "working_env")

View File

@@ -234,7 +234,7 @@ def test_ci_generate_with_env(
assert "rebuild-index" in yaml_contents assert "rebuild-index" in yaml_contents
rebuild_job = yaml_contents["rebuild-index"] rebuild_job = yaml_contents["rebuild-index"]
expected = "spack buildcache update-index --keys --mirror-url {0}".format(mirror_url) expected = "spack buildcache update-index --keys {0}".format(mirror_url)
assert rebuild_job["script"][0] == expected assert rebuild_job["script"][0] == expected
assert rebuild_job["custom_attribute"] == "custom!" assert rebuild_job["custom_attribute"] == "custom!"
@@ -2392,7 +2392,7 @@ def test_gitlab_ci_deprecated(
assert "rebuild-index" in yaml_contents assert "rebuild-index" in yaml_contents
rebuild_job = yaml_contents["rebuild-index"] rebuild_job = yaml_contents["rebuild-index"]
expected = "spack buildcache update-index --keys --mirror-url {0}".format(mirror_url) expected = "spack buildcache update-index --keys {0}".format(mirror_url)
assert rebuild_job["script"][0] == expected assert rebuild_job["script"][0] == expected
assert "variables" in yaml_contents assert "variables" in yaml_contents

View File

@@ -107,10 +107,10 @@ def test_compiler_find_no_apple_gcc(no_compilers_yaml, working_env, tmpdir):
def test_compiler_remove(mutable_config, mock_packages): def test_compiler_remove(mutable_config, mock_packages):
assert spack.spec.CompilerSpec("gcc@=4.5.0") in spack.compilers.all_compiler_specs()
args = spack.util.pattern.Bunch(all=True, compiler_spec="gcc@4.5.0", add_paths=[], scope=None) args = spack.util.pattern.Bunch(all=True, compiler_spec="gcc@4.5.0", add_paths=[], scope=None)
spack.cmd.compiler.compiler_remove(args) spack.cmd.compiler.compiler_remove(args)
compilers = spack.compilers.all_compiler_specs() assert spack.spec.CompilerSpec("gcc@=4.5.0") not in spack.compilers.all_compiler_specs()
assert spack.spec.CompilerSpec("gcc@4.5.0") not in compilers
@pytest.mark.skipif( @pytest.mark.skipif(
@@ -208,8 +208,8 @@ def test_compiler_find_mixed_suffixes(no_compilers_yaml, working_env, clangdir):
assert "gcc@8.4.0" in output assert "gcc@8.4.0" in output
config = spack.compilers.get_compiler_config("site", False) config = spack.compilers.get_compiler_config("site", False)
clang = next(c["compiler"] for c in config if c["compiler"]["spec"] == "clang@11.0.0") clang = next(c["compiler"] for c in config if c["compiler"]["spec"] == "clang@=11.0.0")
gcc = next(c["compiler"] for c in config if c["compiler"]["spec"] == "gcc@8.4.0") gcc = next(c["compiler"] for c in config if c["compiler"]["spec"] == "gcc@=8.4.0")
gfortran_path = str(clangdir.join("gfortran-8")) gfortran_path = str(clangdir.join("gfortran-8"))
@@ -250,7 +250,7 @@ def test_compiler_find_prefer_no_suffix(no_compilers_yaml, working_env, clangdir
assert "gcc@8.4.0" in output assert "gcc@8.4.0" in output
config = spack.compilers.get_compiler_config("site", False) config = spack.compilers.get_compiler_config("site", False)
clang = next(c["compiler"] for c in config if c["compiler"]["spec"] == "clang@11.0.0") clang = next(c["compiler"] for c in config if c["compiler"]["spec"] == "clang@=11.0.0")
assert clang["paths"]["cc"] == str(clangdir.join("clang")) assert clang["paths"]["cc"] == str(clangdir.join("clang"))
assert clang["paths"]["cxx"] == str(clangdir.join("clang++")) assert clang["paths"]["cxx"] == str(clangdir.join("clang++"))
@@ -277,7 +277,7 @@ def test_compiler_find_path_order(no_compilers_yaml, working_env, clangdir):
config = spack.compilers.get_compiler_config("site", False) config = spack.compilers.get_compiler_config("site", False)
gcc = next(c["compiler"] for c in config if c["compiler"]["spec"] == "gcc@8.4.0") gcc = next(c["compiler"] for c in config if c["compiler"]["spec"] == "gcc@=8.4.0")
assert gcc["paths"] == { assert gcc["paths"] == {
"cc": str(clangdir.join("first_in_path", "gcc-8")), "cc": str(clangdir.join("first_in_path", "gcc-8")),

View File

@@ -7,6 +7,7 @@
import pytest import pytest
import spack.environment as ev import spack.environment as ev
from spack import spack_version
from spack.main import SpackCommand from spack.main import SpackCommand
pytestmark = pytest.mark.usefixtures("config", "mutable_mock_repo") pytestmark = pytest.mark.usefixtures("config", "mutable_mock_repo")
@@ -54,3 +55,6 @@ def test_concretize_root_test_dependencies_are_concretized(unify, mutable_mock_e
add("b") add("b")
concretize("--test", "root") concretize("--test", "root")
assert e.matching_spec("test-dependency") assert e.matching_spec("test-dependency")
data = e._to_lockfile_dict()
assert data["spack"]["version"] == spack_version

View File

@@ -390,6 +390,19 @@ def test_remove_after_concretize():
assert not any(s.name == "mpileaks" for s in env_specs) assert not any(s.name == "mpileaks" for s in env_specs)
def test_remove_before_concretize():
e = ev.create("test")
e.unify = True
e.add("mpileaks")
e.concretize()
e.remove("mpileaks")
e.concretize()
assert not list(e.concretized_specs())
def test_remove_command(): def test_remove_command():
env("create", "test") env("create", "test")
assert "test" in env("list") assert "test" in env("list")
@@ -701,6 +714,7 @@ def test_env_with_config(environment_from_manifest):
def test_with_config_bad_include(environment_from_manifest): def test_with_config_bad_include(environment_from_manifest):
"""Confirm missing include paths raise expected exception and error."""
e = environment_from_manifest( e = environment_from_manifest(
""" """
spack: spack:
@@ -709,14 +723,10 @@ def test_with_config_bad_include(environment_from_manifest):
- no/such/file.yaml - no/such/file.yaml
""" """
) )
with pytest.raises(spack.config.ConfigFileError) as exc: with pytest.raises(spack.config.ConfigFileError, match="2 missing include path"):
with e: with e:
e.concretize() e.concretize()
err = str(exc)
assert "missing include" in err
assert "/no/such/directory" in err
assert os.path.join("no", "such", "file.yaml") in err
assert ev.active_environment() is None assert ev.active_environment() is None
@@ -909,7 +919,7 @@ def test_env_config_precedence(environment_from_manifest):
mpileaks: mpileaks:
version: ["2.2"] version: ["2.2"]
libelf: libelf:
version: ["0.8.11"] version: ["0.8.10"]
""" """
) )
@@ -2407,7 +2417,11 @@ def test_concretize_user_specs_together():
# Concretize a second time using 'mpich2' as the MPI provider # Concretize a second time using 'mpich2' as the MPI provider
e.remove("mpich") e.remove("mpich")
e.add("mpich2") e.add("mpich2")
e.concretize()
# Concretizing without invalidating the concrete spec for mpileaks fails
with pytest.raises(spack.error.UnsatisfiableSpecError):
e.concretize()
e.concretize(force=True)
assert all("mpich2" in spec for _, spec in e.concretized_specs()) assert all("mpich2" in spec for _, spec in e.concretized_specs())
assert all("mpich" not in spec for _, spec in e.concretized_specs()) assert all("mpich" not in spec for _, spec in e.concretized_specs())
@@ -2438,7 +2452,7 @@ def test_duplicate_packages_raise_when_concretizing_together():
e.add("mpich") e.add("mpich")
with pytest.raises( with pytest.raises(
spack.error.UnsatisfiableSpecError, match=r"relax the concretizer strictness" spack.error.UnsatisfiableSpecError, match=r"You could consider setting `concretizer:unify`"
): ):
e.concretize() e.concretize()
@@ -2674,7 +2688,7 @@ def test_modules_relative_to_views(environment_from_manifest, install_mockery, m
spec = e.specs_by_hash[e.concretized_order[0]] spec = e.specs_by_hash[e.concretized_order[0]]
view_prefix = e.default_view.get_projection_for_spec(spec) view_prefix = e.default_view.get_projection_for_spec(spec)
modules_glob = "%s/modules/**/*" % e.path modules_glob = "%s/modules/**/*/*" % e.path
modules = glob.glob(modules_glob) modules = glob.glob(modules_glob)
assert len(modules) == 1 assert len(modules) == 1
module = modules[0] module = modules[0]
@@ -2710,12 +2724,12 @@ def test_multiple_modules_post_env_hook(environment_from_manifest, install_mocke
spec = e.specs_by_hash[e.concretized_order[0]] spec = e.specs_by_hash[e.concretized_order[0]]
view_prefix = e.default_view.get_projection_for_spec(spec) view_prefix = e.default_view.get_projection_for_spec(spec)
modules_glob = "%s/modules/**/*" % e.path modules_glob = "%s/modules/**/*/*" % e.path
modules = glob.glob(modules_glob) modules = glob.glob(modules_glob)
assert len(modules) == 1 assert len(modules) == 1
module = modules[0] module = modules[0]
full_modules_glob = "%s/full_modules/**/*" % e.path full_modules_glob = "%s/full_modules/**/*/*" % e.path
full_modules = glob.glob(full_modules_glob) full_modules = glob.glob(full_modules_glob)
assert len(full_modules) == 1 assert len(full_modules) == 1
full_module = full_modules[0] full_module = full_modules[0]
@@ -3298,3 +3312,22 @@ def test_environment_created_in_users_location(mutable_config, tmpdir):
assert dir_name in out assert dir_name in out
assert env_dir in ev.root(dir_name) assert env_dir in ev.root(dir_name)
assert os.path.isdir(os.path.join(env_dir, dir_name)) assert os.path.isdir(os.path.join(env_dir, dir_name))
def test_environment_created_from_lockfile_has_view(mock_packages, tmpdir):
"""When an env is created from a lockfile, a view should be generated for it"""
env_a = str(tmpdir.join("a"))
env_b = str(tmpdir.join("b"))
# Create an environment and install a package in it
env("create", "-d", env_a)
with ev.Environment(env_a):
add("libelf")
install("--fake")
# Create another environment from the lockfile of the first environment
env("create", "-d", env_b, os.path.join(env_a, "spack.lock"))
# Make sure the view was created
with ev.Environment(env_b) as e:
assert os.path.isdir(e.view_path_default)

View File

@@ -357,3 +357,18 @@ def test_find_loaded(database, working_env):
output = find("--loaded") output = find("--loaded")
expected = find() expected = find()
assert output == expected assert output == expected
@pytest.mark.regression("37712")
def test_environment_with_version_range_in_compiler_doesnt_fail(tmp_path):
"""Tests that having an active environment with a root spec containing a compiler constrained
by a version range (i.e. @X.Y rather the single version than @=X.Y) doesn't result in an error
when invoking "spack find".
"""
test_environment = ev.create_in_dir(tmp_path)
test_environment.add("zlib %gcc@12.1.0")
test_environment.write()
with test_environment:
output = find()
assert "zlib%gcc@12.1.0" in output

View File

@@ -1072,11 +1072,18 @@ def test_install_empty_env(
], ],
) )
def test_installation_fail_tests(install_mockery, mock_fetch, name, method): def test_installation_fail_tests(install_mockery, mock_fetch, name, method):
"""Confirm build-time tests with unknown methods fail."""
output = install("--test=root", "--no-cache", name, fail_on_error=False) output = install("--test=root", "--no-cache", name, fail_on_error=False)
# Check that there is a single test failure reported
assert output.count("TestFailure: 1 test failed") == 1
# Check that the method appears twice: no attribute error and in message
assert output.count(method) == 2 assert output.count(method) == 2
assert output.count("method not implemented") == 1 assert output.count("method not implemented") == 1
assert output.count("TestFailure: 1 tests failed") == 1
# Check that the path to the test log file is also output
assert "See test log for details" in output
def test_install_use_buildcache( def test_install_use_buildcache(

View File

@@ -37,6 +37,15 @@ def mock_spec():
shutil.rmtree(s.package.stage.path) shutil.rmtree(s.package.stage.path)
def test_location_first(install_mockery, mock_fetch, mock_archive, mock_packages):
"""Test with and without the --first option"""
install = SpackCommand("install")
install("libelf@0.8.12")
install("libelf@0.8.13")
# This would normally return an error without --first
assert location("--first", "--install-dir", "libelf")
def test_location_build_dir(mock_spec): def test_location_build_dir(mock_spec):
"""Tests spack location --build-dir.""" """Tests spack location --build-dir."""
spec, pkg = mock_spec spec, pkg = mock_spec

View File

@@ -41,7 +41,7 @@ def _module_files(module_type, *specs):
["rm", "doesnotexist"], # Try to remove a non existing module ["rm", "doesnotexist"], # Try to remove a non existing module
["find", "mpileaks"], # Try to find a module with multiple matches ["find", "mpileaks"], # Try to find a module with multiple matches
["find", "doesnotexist"], # Try to find a module with no matches ["find", "doesnotexist"], # Try to find a module with no matches
["find", "--unkown_args"], # Try to give an unknown argument ["find", "--unknown_args"], # Try to give an unknown argument
] ]
) )
def failure_args(request): def failure_args(request):

View File

@@ -85,7 +85,15 @@ def mock_pkg_git_repo(git, tmpdir_factory):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def mock_pkg_names(): def mock_pkg_names():
repo = spack.repo.path.get_repo("builtin.mock") repo = spack.repo.path.get_repo("builtin.mock")
names = set(name for name in repo.all_package_names() if not name.startswith("pkg-"))
# Be sure to include virtual packages since packages with stand-alone
# tests may inherit additional tests from the virtuals they provide,
# such as packages that implement `mpi`.
names = set(
name
for name in repo.all_package_names(include_virtuals=True)
if not name.startswith("pkg-")
)
return names return names

View File

@@ -24,12 +24,12 @@
def test_spec(): def test_spec():
output = spec("mpileaks") output = spec("mpileaks")
assert "mpileaks@=2.3" in output assert "mpileaks@2.3" in output
assert "callpath@=1.0" in output assert "callpath@1.0" in output
assert "dyninst@=8.2" in output assert "dyninst@8.2" in output
assert "libdwarf@=20130729" in output assert "libdwarf@20130729" in output
assert "libelf@=0.8.1" in output assert "libelf@0.8.1" in output
assert "mpich@=3.0.4" in output assert "mpich@3.0.4" in output
def test_spec_concretizer_args(mutable_config, mutable_database): def test_spec_concretizer_args(mutable_config, mutable_database):
@@ -86,10 +86,9 @@ def test_spec_parse_unquoted_flags_report():
# cflags, we just explain how to fix it for the immediate next arg. # cflags, we just explain how to fix it for the immediate next arg.
spec("gcc cflags=-Os -pipe -other-arg-that-gets-ignored cflags=-I /usr/include") spec("gcc cflags=-Os -pipe -other-arg-that-gets-ignored cflags=-I /usr/include")
# Verify that the generated error message is nicely formatted. # Verify that the generated error message is nicely formatted.
assert str(cm.value) == dedent(
'''\
No installed spec matches the hash: 'usr'
expected_message = dedent(
'''\
Some compiler or linker flags were provided without quoting their arguments, Some compiler or linker flags were provided without quoting their arguments,
which now causes spack to try to parse the *next* argument as a spec component which now causes spack to try to parse the *next* argument as a spec component
such as a variant instead of an additional compiler or linker flag. If the such as a variant instead of an additional compiler or linker flag. If the
@@ -100,6 +99,8 @@ def test_spec_parse_unquoted_flags_report():
(2) cflags=-I /usr/include => cflags="-I /usr/include"''' (2) cflags=-I /usr/include => cflags="-I /usr/include"'''
) )
assert expected_message in str(cm.value)
# Verify that the same unquoted cflags report is generated in the error message even # Verify that the same unquoted cflags report is generated in the error message even
# if it fails during concretization, not just during parsing. # if it fails during concretization, not just during parsing.
with pytest.raises(spack.error.SpackError) as cm: with pytest.raises(spack.error.SpackError) as cm:
@@ -196,12 +197,12 @@ def test_env_aware_spec(mutable_mock_env_path):
with env: with env:
output = spec() output = spec()
assert "mpileaks@=2.3" in output assert "mpileaks@2.3" in output
assert "callpath@=1.0" in output assert "callpath@1.0" in output
assert "dyninst@=8.2" in output assert "dyninst@8.2" in output
assert "libdwarf@=20130729" in output assert "libdwarf@20130729" in output
assert "libelf@=0.8.1" in output assert "libelf@0.8.1" in output
assert "mpich@=3.0.4" in output assert "mpich@3.0.4" in output
@pytest.mark.parametrize( @pytest.mark.parametrize(

View File

@@ -16,6 +16,7 @@
import spack.package_base import spack.package_base
import spack.paths import spack.paths
import spack.store import spack.store
from spack.install_test import TestStatus
from spack.main import SpackCommand from spack.main import SpackCommand
install = SpackCommand("install") install = SpackCommand("install")
@@ -59,15 +60,14 @@ def test_test_dup_alias(
"""Ensure re-using an alias fails with suggestion to change.""" """Ensure re-using an alias fails with suggestion to change."""
install("libdwarf") install("libdwarf")
# Run the tests with the alias once # Run the (no) tests with the alias once
out = spack_test("run", "--alias", "libdwarf", "libdwarf") spack_test("run", "--alias", "libdwarf", "libdwarf")
assert "Spack test libdwarf" in out
# Try again with the alias but don't let it fail on the error # Try again with the alias but don't let it fail on the error
with capfd.disabled(): with capfd.disabled():
out = spack_test("run", "--alias", "libdwarf", "libdwarf", fail_on_error=False) out = spack_test("run", "--alias", "libdwarf", "libdwarf", fail_on_error=False)
assert "already exists" in out assert "already exists" in out and "Try another alias" in out
def test_test_output( def test_test_output(
@@ -83,51 +83,39 @@ def test_test_output(
# Grab test stage directory contents # Grab test stage directory contents
testdir = os.path.join(mock_test_stage, stage_files[0]) testdir = os.path.join(mock_test_stage, stage_files[0])
testdir_files = os.listdir(testdir) testdir_files = os.listdir(testdir)
testlogs = [name for name in testdir_files if str(name).endswith("out.txt")]
assert len(testlogs) == 1
# Grab the output from the test log # Grab the output from the test log to confirm expected result
testlog = list(filter(lambda x: x.endswith("out.txt") and x != "results.txt", testdir_files)) outfile = os.path.join(testdir, testlogs[0])
outfile = os.path.join(testdir, testlog[0])
with open(outfile, "r") as f: with open(outfile, "r") as f:
output = f.read() output = f.read()
assert "BEFORE TEST" in output assert "test_print" in output
assert "true: expect command status in [" in output assert "PASSED" in output
assert "AFTER TEST" in output
assert "FAILED" not in output
def test_test_output_on_error( @pytest.mark.parametrize(
mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config, capfd, mock_test_stage "pkg_name,failure", [("test-error", "exited with status 1"), ("test-fail", "not callable")]
)
def test_test_output_fails(
mock_packages,
mock_archive,
mock_fetch,
install_mockery_mutable_config,
mock_test_stage,
pkg_name,
failure,
): ):
install("test-error") """Confirm stand-alone test failure with expected outputs."""
# capfd interferes with Spack's capturing install(pkg_name)
with capfd.disabled(): out = spack_test("run", pkg_name, fail_on_error=False)
out = spack_test("run", "test-error", fail_on_error=False)
# Confirm package-specific failure is in the output
assert failure in out
# Confirm standard failure tagging AND test log reference also output
assert "TestFailure" in out assert "TestFailure" in out
assert "Command exited with status 1" in out assert "See test log for details" in out
def test_test_output_on_failure(
mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config, capfd, mock_test_stage
):
install("test-fail")
with capfd.disabled():
out = spack_test("run", "test-fail", fail_on_error=False)
assert "Expected 'not in the output' to match output of `true`" in out
assert "TestFailure" in out
def test_show_log_on_error(
mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config, capfd, mock_test_stage
):
"""Make sure spack prints location of test log on failure."""
install("test-error")
with capfd.disabled():
out = spack_test("run", "test-error", fail_on_error=False)
assert "See test log" in out
assert mock_test_stage in out
@pytest.mark.usefixtures( @pytest.mark.usefixtures(
@@ -136,11 +124,12 @@ def test_show_log_on_error(
@pytest.mark.parametrize( @pytest.mark.parametrize(
"pkg_name,msgs", "pkg_name,msgs",
[ [
("test-error", ["FAILED: Command exited", "TestFailure"]), ("test-error", ["exited with status 1", "TestFailure"]),
("test-fail", ["FAILED: Expected", "TestFailure"]), ("test-fail", ["not callable", "TestFailure"]),
], ],
) )
def test_junit_output_with_failures(tmpdir, mock_test_stage, pkg_name, msgs): def test_junit_output_with_failures(tmpdir, mock_test_stage, pkg_name, msgs):
"""Confirm stand-alone test failure expected outputs in JUnit reporting."""
install(pkg_name) install(pkg_name)
with tmpdir.as_cwd(): with tmpdir.as_cwd():
spack_test( spack_test(
@@ -173,6 +162,7 @@ def test_cdash_output_test_error(
mock_test_stage, mock_test_stage,
capfd, capfd,
): ):
"""Confirm stand-alone test error expected outputs in CDash reporting."""
install("test-error") install("test-error")
with tmpdir.as_cwd(): with tmpdir.as_cwd():
spack_test( spack_test(
@@ -183,12 +173,10 @@ def test_cdash_output_test_error(
fail_on_error=False, fail_on_error=False,
) )
report_dir = tmpdir.join("cdash_reports") report_dir = tmpdir.join("cdash_reports")
print(tmpdir.listdir()) reports = [name for name in report_dir.listdir() if str(name).endswith("Testing.xml")]
assert report_dir in tmpdir.listdir() assert len(reports) == 1
report_file = report_dir.join("test-error_Testing.xml") content = reports[0].open().read()
assert report_file in report_dir.listdir() assert "Command exited with status 1" in content
content = report_file.open().read()
assert "FAILED: Command exited with status 1" in content
def test_cdash_upload_clean_test( def test_cdash_upload_clean_test(
@@ -203,10 +191,12 @@ def test_cdash_upload_clean_test(
with tmpdir.as_cwd(): with tmpdir.as_cwd():
spack_test("run", "--log-file=cdash_reports", "--log-format=cdash", "printing-package") spack_test("run", "--log-file=cdash_reports", "--log-format=cdash", "printing-package")
report_dir = tmpdir.join("cdash_reports") report_dir = tmpdir.join("cdash_reports")
assert report_dir in tmpdir.listdir() reports = [name for name in report_dir.listdir() if str(name).endswith("Testing.xml")]
report_file = report_dir.join("printing-package_Testing.xml") assert len(reports) == 1
assert report_file in report_dir.listdir() content = reports[0].open().read()
content = report_file.open().read() assert "passed" in content
assert "Running test_print" in content, "Expected first command output"
assert "second command" in content, "Expected second command output"
assert "</Test>" in content assert "</Test>" in content
assert "<Text>" not in content assert "<Text>" not in content
@@ -226,17 +216,19 @@ def test_test_help_cdash(mock_test_stage):
def test_test_list_all(mock_packages): def test_test_list_all(mock_packages):
"""make sure `spack test list --all` returns all packages with tests""" """Confirm `spack test list --all` returns all packages with test methods"""
pkgs = spack_test("list", "--all").strip().split() pkgs = spack_test("list", "--all").strip().split()
assert set(pkgs) == set( assert set(pkgs) == set(
[ [
"fail-test-audit",
"mpich",
"printing-package", "printing-package",
"py-extension1", "py-extension1",
"py-extension2", "py-extension2",
"py-test-callback",
"simple-standalone-test", "simple-standalone-test",
"test-error", "test-error",
"test-fail", "test-fail",
"fail-test-audit",
] ]
) )
@@ -248,15 +240,6 @@ def test_test_list(mock_packages, mock_archive, mock_fetch, install_mockery_muta
assert pkg_with_tests in output assert pkg_with_tests in output
@pytest.mark.skipif(sys.platform == "win32", reason="Not supported on Windows (yet)")
def test_has_test_method_fails(capsys):
with pytest.raises(SystemExit):
spack.package_base.has_test_method("printing-package")
captured = capsys.readouterr()[1]
assert "is not a class" in captured
def test_read_old_results(mock_packages, mock_test_stage): def test_read_old_results(mock_packages, mock_test_stage):
"""Take test data generated before the switch to full hash everywhere """Take test data generated before the switch to full hash everywhere
and make sure we can still read it in""" and make sure we can still read it in"""
@@ -276,7 +259,7 @@ def test_read_old_results(mock_packages, mock_test_stage):
# The results command should still print the old test results # The results command should still print the old test results
results_output = spack_test("results") results_output = spack_test("results")
assert "PASSED" in results_output assert str(TestStatus.PASSED) in results_output
def test_test_results_none(mock_packages, mock_test_stage): def test_test_results_none(mock_packages, mock_test_stage):
@@ -291,15 +274,10 @@ def test_test_results_none(mock_packages, mock_test_stage):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"status,expected", "status", [TestStatus.FAILED, TestStatus.NO_TESTS, TestStatus.SKIPPED, TestStatus.PASSED]
[
("FAILED", "1 failed"),
("NO-TESTS", "1 no-tests"),
("SKIPPED", "1 skipped"),
("PASSED", "1 passed"),
],
) )
def test_test_results_status(mock_packages, mock_test_stage, status, expected): def test_test_results_status(mock_packages, mock_test_stage, status):
"""Confirm 'spack test results' returns expected status."""
name = "trivial" name = "trivial"
spec = spack.spec.Spec("trivial-smoke-test").concretized() spec = spack.spec.Spec("trivial-smoke-test").concretized()
suite = spack.install_test.TestSuite([spec], name) suite = spack.install_test.TestSuite([spec], name)
@@ -313,11 +291,11 @@ def test_test_results_status(mock_packages, mock_test_stage, status, expected):
args.insert(1, opt) args.insert(1, opt)
results = spack_test(*args) results = spack_test(*args)
if opt == "--failed" and status != "FAILED": if opt == "--failed" and status != TestStatus.FAILED:
assert status not in results assert str(status) not in results
else: else:
assert status in results assert str(status) in results
assert expected in results assert "1 {0}".format(status.lower()) in results
@pytest.mark.regression("35337") @pytest.mark.regression("35337")
@@ -341,3 +319,17 @@ def test_report_filename_for_cdash(install_mockery_mutable_config, mock_fetch):
spack.cmd.common.arguments.sanitize_reporter_options(args) spack.cmd.common.arguments.sanitize_reporter_options(args)
filename = spack.cmd.test.report_filename(args, suite) filename = spack.cmd.test.report_filename(args, suite)
assert filename != "https://blahblah/submit.php?project=debugging" assert filename != "https://blahblah/submit.php?project=debugging"
def test_test_output_multiple_specs(
mock_test_stage, mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config
):
"""Ensure proper reporting for suite with skipped, failing, and passed tests."""
install("test-error", "simple-standalone-test@0.9", "simple-standalone-test@1.0")
out = spack_test("run", "test-error", "simple-standalone-test", fail_on_error=False)
# Note that a spec with passing *and* skipped tests is still considered
# to have passed at this level. If you want to see the spec-specific
# part result summaries, you'll have to look at the "test-out.txt" files
# for each spec.
assert "1 failed, 2 passed of 3 specs" in out

View File

@@ -152,7 +152,9 @@ def test_preferred_versions(self):
assert spec.version == Version("2.2") assert spec.version == Version("2.2")
def test_preferred_versions_mixed_version_types(self): def test_preferred_versions_mixed_version_types(self):
update_packages("mixedversions", "version", ["2.0"]) if spack.config.get("config:concretizer") == "original":
pytest.skip("This behavior is not enforced for the old concretizer")
update_packages("mixedversions", "version", ["=2.0"])
spec = concretize("mixedversions") spec = concretize("mixedversions")
assert spec.version == Version("2.0") assert spec.version == Version("2.0")
@@ -228,6 +230,29 @@ def test_preferred(self):
spec.concretize() spec.concretize()
assert spec.version == Version("3.5.0") assert spec.version == Version("3.5.0")
def test_preferred_undefined_raises(self):
"""Preference should not specify an undefined version"""
if spack.config.get("config:concretizer") == "original":
pytest.xfail("This behavior is not enforced for the old concretizer")
update_packages("python", "version", ["3.5.0.1"])
spec = Spec("python")
with pytest.raises(spack.config.ConfigError):
spec.concretize()
def test_preferred_truncated(self):
"""Versions without "=" are treated as version ranges: if there is
a satisfying version defined in the package.py, we should use that
(don't define a new version).
"""
if spack.config.get("config:concretizer") == "original":
pytest.skip("This behavior is not enforced for the old concretizer")
update_packages("python", "version", ["3.5"])
spec = Spec("python")
spec.concretize()
assert spec.satisfies("@3.5.1")
def test_develop(self): def test_develop(self):
"""Test concretization with develop-like versions""" """Test concretization with develop-like versions"""
spec = Spec("develop-test") spec = Spec("develop-test")

View File

@@ -66,6 +66,28 @@ class V(Package):
) )
_pkgt = (
"t",
"""\
class T(Package):
version('2.1')
version('2.0')
depends_on('u', when='@2.1:')
""",
)
_pkgu = (
"u",
"""\
class U(Package):
version('1.1')
version('1.0')
""",
)
@pytest.fixture @pytest.fixture
def create_test_repo(tmpdir, mutable_config): def create_test_repo(tmpdir, mutable_config):
repo_path = str(tmpdir) repo_path = str(tmpdir)
@@ -79,7 +101,7 @@ def create_test_repo(tmpdir, mutable_config):
) )
packages_dir = tmpdir.join("packages") packages_dir = tmpdir.join("packages")
for pkg_name, pkg_str in [_pkgx, _pkgy, _pkgv]: for pkg_name, pkg_str in [_pkgx, _pkgy, _pkgv, _pkgt, _pkgu]:
pkg_dir = packages_dir.ensure(pkg_name, dir=True) pkg_dir = packages_dir.ensure(pkg_name, dir=True)
pkg_file = pkg_dir.join("package.py") pkg_file = pkg_dir.join("package.py")
with open(str(pkg_file), "w") as f: with open(str(pkg_file), "w") as f:
@@ -144,6 +166,45 @@ def test_requirement_isnt_optional(concretize_scope, test_repo):
Spec("x@1.1").concretize() Spec("x@1.1").concretize()
def test_require_undefined_version(concretize_scope, test_repo):
"""If a requirement specifies a numbered version that isn't in
the associated package.py and isn't part of a Git hash
equivalence (hash=number), then Spack should raise an error
(it is assumed this is a typo, and raising the error here
avoids a likely error when Spack attempts to fetch the version).
"""
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not support configuration requirements")
conf_str = """\
packages:
x:
require: "@1.2"
"""
update_packages_config(conf_str)
with pytest.raises(spack.config.ConfigError):
Spec("x").concretize()
def test_require_truncated(concretize_scope, test_repo):
"""A requirement specifies a version range, with satisfying
versions defined in the package.py. Make sure we choose one
of the defined versions (vs. allowing the requirement to
define a new version).
"""
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not support configuration requirements")
conf_str = """\
packages:
x:
require: "@1"
"""
update_packages_config(conf_str)
xspec = Spec("x").concretized()
assert xspec.satisfies("@1.1")
def test_git_user_supplied_reference_satisfaction( def test_git_user_supplied_reference_satisfaction(
concretize_scope, test_repo, mock_git_version_info, monkeypatch concretize_scope, test_repo, mock_git_version_info, monkeypatch
): ):
@@ -220,6 +281,40 @@ def test_requirement_adds_new_version(
assert s1.version.ref == a_commit_hash assert s1.version.ref == a_commit_hash
def test_requirement_adds_version_satisfies(
concretize_scope, test_repo, mock_git_version_info, monkeypatch
):
"""Make sure that new versions added by requirements are factored into
conditions. In this case create a new version that satisfies a
depends_on condition and make sure it is triggered (i.e. the
dependency is added).
"""
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not support configuration" " requirements")
repo_path, filename, commits = mock_git_version_info
monkeypatch.setattr(
spack.package_base.PackageBase, "git", path_to_file_url(repo_path), raising=False
)
# Sanity check: early version of T does not include U
s0 = Spec("t@2.0").concretized()
assert not ("u" in s0)
conf_str = """\
packages:
t:
require: "@{0}=2.2"
""".format(
commits[0]
)
update_packages_config(conf_str)
s1 = Spec("t").concretized()
assert "u" in s1
assert s1.satisfies("@2.2")
def test_requirement_adds_git_hash_version( def test_requirement_adds_git_hash_version(
concretize_scope, test_repo, mock_git_version_info, monkeypatch concretize_scope, test_repo, mock_git_version_info, monkeypatch
): ):
@@ -272,8 +367,11 @@ def test_requirement_adds_multiple_new_versions(
def test_preference_adds_new_version( def test_preference_adds_new_version(
concretize_scope, test_repo, mock_git_version_info, monkeypatch concretize_scope, test_repo, mock_git_version_info, monkeypatch
): ):
"""Normally a preference cannot define a new version, but that constraint
is ignored if the version is a Git hash-based version.
"""
if spack.config.get("config:concretizer") == "original": if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not support configuration requirements") pytest.skip("Original concretizer does not enforce this constraint for preferences")
repo_path, filename, commits = mock_git_version_info repo_path, filename, commits = mock_git_version_info
monkeypatch.setattr( monkeypatch.setattr(
@@ -296,6 +394,29 @@ def test_preference_adds_new_version(
assert not s3.satisfies("@2.3") assert not s3.satisfies("@2.3")
def test_external_adds_new_version_that_is_preferred(concretize_scope, test_repo):
"""Test that we can use a version, not declared in package recipe, as the
preferred version if that version appears in an external spec.
"""
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not enforce this constraint for preferences")
conf_str = """\
packages:
y:
version: ["2.7"]
externals:
- spec: y@2.7 # Not defined in y
prefix: /fake/nonexistent/path/
buildable: false
"""
update_packages_config(conf_str)
spec = Spec("x").concretized()
assert spec["y"].satisfies("@2.7")
assert spack.version.Version("2.7") not in spec["y"].package.versions
def test_requirement_is_successfully_applied(concretize_scope, test_repo): def test_requirement_is_successfully_applied(concretize_scope, test_repo):
"""If a simple requirement can be satisfied, make sure the """If a simple requirement can be satisfied, make sure the
concretization succeeds and the requirement spec is applied. concretization succeeds and the requirement spec is applied.
@@ -381,6 +502,22 @@ def test_one_package_multiple_oneof_groups(concretize_scope, test_repo):
assert s2.satisfies("%gcc+shared") assert s2.satisfies("%gcc+shared")
@pytest.mark.regression("34241")
def test_require_cflags(concretize_scope, test_repo):
"""Ensures that flags can be required from configuration."""
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not support configuration" " requirements")
conf_str = """\
packages:
y:
require: cflags="-g"
"""
update_packages_config(conf_str)
spec = Spec("y").concretized()
assert spec.satisfies("cflags=-g")
def test_requirements_for_package_that_is_not_needed(concretize_scope, test_repo): def test_requirements_for_package_that_is_not_needed(concretize_scope, test_repo):
"""Specify requirements for specs that are not concretized or """Specify requirements for specs that are not concretized or
a dependency of a concretized spec (in other words, none of a dependency of a concretized spec (in other words, none of

View File

@@ -2,6 +2,8 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import re
import pytest import pytest
import spack.container.writers as writers import spack.container.writers as writers
@@ -149,3 +151,14 @@ def test_not_stripping_all_symbols(minimal_configuration):
content = writers.create(minimal_configuration)() content = writers.create(minimal_configuration)()
assert "xargs strip" in content assert "xargs strip" in content
assert "xargs strip -s" not in content assert "xargs strip -s" not in content
@pytest.mark.regression("22341")
def test_using_single_quotes_in_dockerfiles(minimal_configuration):
"""Tests that Dockerfiles written by Spack use single quotes in manifest, to avoid issues
with shell substitution. This may happen e.g. when users have "definitions:" they want to
expand in dockerfiles.
"""
manifest_in_docker = writers.create(minimal_configuration).manifest
assert not re.search(r"echo\s*\"", manifest_in_docker, flags=re.MULTILINE)
assert re.search(r"echo\s*'", manifest_in_docker)

View File

@@ -4,7 +4,7 @@ lmod:
hash_length: 0 hash_length: 0
core_compilers: core_compilers:
- 'clang@3.3' - 'clang@12.0.0'
core_specs: core_specs:
- 'mpich@3.0.1' - 'mpich@3.0.1'

View File

@@ -0,0 +1,5 @@
enable:
- lmod
lmod:
core_compilers:
- 'clang@12.0.0'

View File

@@ -0,0 +1,5 @@
enable:
- lmod
lmod:
core_compilers:
- 'clang@=12.0.0'

View File

@@ -1,6 +1,7 @@
==> Testing package printing-package-1.0-hzgcoow ==> Testing package printing-package-1.0-hzgcoow
BEFORE TEST ==> [2022-12-06-20:21:46.550943] test: test_print: Test python print example.
==> [2022-02-28-20:21:46.510616] test: true: expect command status in [0] ==> [2022-12-06-20:21:46.553219] '/usr/tce/bin/python' '-c' 'print("Running test_print")'
==> [2022-02-28-20:21:46.510937] '/bin/true' Running test_print
PASSED ==> [2022-12-06-20:21:46.721077] '/usr/tce/bin/python' '-c' 'print("Running test_print")'
AFTER TEST PASSED: test_print
==> [2022-12-06-20:21:46.822608] Completed testing

View File

@@ -31,194 +31,164 @@ class Amdfftw(FftwBase):
Example : spack install amdfftw precision=float Example : spack install amdfftw precision=float
""" """
_name = 'amdfftw' _name = "amdfftw"
homepage = "https://developer.amd.com/amd-aocl/fftw/" homepage = "https://developer.amd.com/amd-aocl/fftw/"
url = "https://github.com/amd/amd-fftw/archive/3.0.tar.gz" url = "https://github.com/amd/amd-fftw/archive/3.0.tar.gz"
git = "https://github.com/amd/amd-fftw.git" git = "https://github.com/amd/amd-fftw.git"
maintainers = ['amd-toolchain-support'] maintainers("amd-toolchain-support")
version('3.1', sha256='3e777f3acef13fa1910db097e818b1d0d03a6a36ef41186247c6ab1ab0afc132') version("3.1", sha256="3e777f3acef13fa1910db097e818b1d0d03a6a36ef41186247c6ab1ab0afc132")
version('3.0.1', sha256='87030c6bbb9c710f0a64f4f306ba6aa91dc4b182bb804c9022b35aef274d1a4c') version("3.0.1", sha256="87030c6bbb9c710f0a64f4f306ba6aa91dc4b182bb804c9022b35aef274d1a4c")
version('3.0', sha256='a69deaf45478a59a69f77c4f7e9872967f1cfe996592dd12beb6318f18ea0bcd') version("3.0", sha256="a69deaf45478a59a69f77c4f7e9872967f1cfe996592dd12beb6318f18ea0bcd")
version('2.2', sha256='de9d777236fb290c335860b458131678f75aa0799c641490c644c843f0e246f8') version("2.2", sha256="de9d777236fb290c335860b458131678f75aa0799c641490c644c843f0e246f8")
variant('shared', default=True, variant("shared", default=True, description="Builds a shared version of the library")
description='Builds a shared version of the library') variant("openmp", default=True, description="Enable OpenMP support")
variant('openmp', default=True, variant("threads", default=False, description="Enable SMP threads support")
description='Enable OpenMP support') variant("debug", default=False, description="Builds a debug version of the library")
variant('threads', default=False,
description='Enable SMP threads support')
variant('debug', default=False,
description='Builds a debug version of the library')
variant( variant(
'amd-fast-planner', "amd-fast-planner",
default=False, default=False,
description='Option to reduce the planning time without much' description="Option to reduce the planning time without much"
'tradeoff in the performance. It is supported for' "tradeoff in the performance. It is supported for"
'Float and double precisions only.') "Float and double precisions only.",
)
variant("amd-top-n-planner", default=False, description="Build with amd-top-n-planner support")
variant( variant(
'amd-top-n-planner', "amd-mpi-vader-limit", default=False, description="Build with amd-mpi-vader-limit support"
default=False, )
description='Build with amd-top-n-planner support') variant("static", default=False, description="Build with static suppport")
variant( variant("amd-trans", default=False, description="Build with amd-trans suppport")
'amd-mpi-vader-limit', variant("amd-app-opt", default=False, description="Build with amd-app-opt suppport")
default=False,
description='Build with amd-mpi-vader-limit support')
variant(
'static',
default=False,
description='Build with static suppport')
variant(
'amd-trans',
default=False,
description='Build with amd-trans suppport')
variant(
'amd-app-opt',
default=False,
description='Build with amd-app-opt suppport')
depends_on('texinfo') depends_on("texinfo")
provides('fftw-api@3', when='@2:') provides("fftw-api@3", when="@2:")
conflicts( conflicts(
'precision=quad', "precision=quad",
when='@2.2 %aocc', when="@2.2 %aocc",
msg='Quad precision is not supported by AOCC clang version 2.2') msg="Quad precision is not supported by AOCC clang version 2.2",
)
conflicts( conflicts(
'+debug', "+debug", when="@2.2 %aocc", msg="debug mode is not supported by AOCC clang version 2.2"
when='@2.2 %aocc', )
msg='debug mode is not supported by AOCC clang version 2.2') conflicts("%gcc@:7.2", when="@2.2:", msg="GCC version above 7.2 is required for AMDFFTW")
conflicts( conflicts(
'%gcc@:7.2', "+amd-fast-planner ", when="+mpi", msg="mpi thread is not supported with amd-fast-planner"
when='@2.2:', )
msg='GCC version above 7.2 is required for AMDFFTW')
conflicts( conflicts(
'+amd-fast-planner ', "+amd-fast-planner", when="@2.2", msg="amd-fast-planner is supported from 3.0 onwards"
when='+mpi', )
msg='mpi thread is not supported with amd-fast-planner')
conflicts( conflicts(
'+amd-fast-planner', "+amd-fast-planner",
when='@2.2', when="precision=quad",
msg='amd-fast-planner is supported from 3.0 onwards') msg="Quad precision is not supported with amd-fast-planner",
)
conflicts( conflicts(
'+amd-fast-planner', "+amd-fast-planner",
when='precision=quad', when="precision=long_double",
msg='Quad precision is not supported with amd-fast-planner') msg="long_double precision is not supported with amd-fast-planner",
)
conflicts( conflicts(
'+amd-fast-planner', "+amd-top-n-planner",
when='precision=long_double', when="@:3.0.0",
msg='long_double precision is not supported with amd-fast-planner') msg="amd-top-n-planner is supported from 3.0.1 onwards",
)
conflicts( conflicts(
'+amd-top-n-planner', "+amd-top-n-planner",
when='@:3.0.0', when="precision=long_double",
msg='amd-top-n-planner is supported from 3.0.1 onwards') msg="long_double precision is not supported with amd-top-n-planner",
)
conflicts( conflicts(
'+amd-top-n-planner', "+amd-top-n-planner",
when='precision=long_double', when="precision=quad",
msg='long_double precision is not supported with amd-top-n-planner') msg="Quad precision is not supported with amd-top-n-planner",
)
conflicts( conflicts(
'+amd-top-n-planner', "+amd-top-n-planner",
when='precision=quad', when="+amd-fast-planner",
msg='Quad precision is not supported with amd-top-n-planner') msg="amd-top-n-planner cannot be used with amd-fast-planner",
)
conflicts( conflicts(
'+amd-top-n-planner', "+amd-top-n-planner", when="+threads", msg="amd-top-n-planner works only for single thread"
when='+amd-fast-planner', )
msg='amd-top-n-planner cannot be used with amd-fast-planner')
conflicts( conflicts(
'+amd-top-n-planner', "+amd-top-n-planner", when="+mpi", msg="mpi thread is not supported with amd-top-n-planner"
when='+threads', )
msg='amd-top-n-planner works only for single thread')
conflicts( conflicts(
'+amd-top-n-planner', "+amd-top-n-planner",
when='+mpi', when="+openmp",
msg='mpi thread is not supported with amd-top-n-planner') msg="openmp thread is not supported with amd-top-n-planner",
)
conflicts( conflicts(
'+amd-top-n-planner', "+amd-mpi-vader-limit",
when='+openmp', when="@:3.0.0",
msg='openmp thread is not supported with amd-top-n-planner') msg="amd-mpi-vader-limit is supported from 3.0.1 onwards",
)
conflicts( conflicts(
'+amd-mpi-vader-limit', "+amd-mpi-vader-limit",
when='@:3.0.0', when="precision=quad",
msg='amd-mpi-vader-limit is supported from 3.0.1 onwards') msg="Quad precision is not supported with amd-mpi-vader-limit",
)
conflicts("+amd-trans", when="+threads", msg="amd-trans works only for single thread")
conflicts("+amd-trans", when="+mpi", msg="mpi thread is not supported with amd-trans")
conflicts("+amd-trans", when="+openmp", msg="openmp thread is not supported with amd-trans")
conflicts( conflicts(
'+amd-mpi-vader-limit', "+amd-trans",
when='precision=quad', when="precision=long_double",
msg='Quad precision is not supported with amd-mpi-vader-limit') msg="long_double precision is not supported with amd-trans",
)
conflicts( conflicts(
'+amd-trans', "+amd-trans", when="precision=quad", msg="Quad precision is not supported with amd-trans"
when='+threads', )
msg='amd-trans works only for single thread') conflicts("+amd-app-opt", when="@:3.0.1", msg="amd-app-opt is supported from 3.1 onwards")
conflicts("+amd-app-opt", when="+mpi", msg="mpi thread is not supported with amd-app-opt")
conflicts( conflicts(
'+amd-trans', "+amd-app-opt",
when='+mpi', when="precision=long_double",
msg='mpi thread is not supported with amd-trans') msg="long_double precision is not supported with amd-app-opt",
)
conflicts( conflicts(
'+amd-trans', "+amd-app-opt",
when='+openmp', when="precision=quad",
msg='openmp thread is not supported with amd-trans') msg="Quad precision is not supported with amd-app-opt",
conflicts( )
'+amd-trans',
when='precision=long_double',
msg='long_double precision is not supported with amd-trans')
conflicts(
'+amd-trans',
when='precision=quad',
msg='Quad precision is not supported with amd-trans')
conflicts(
'+amd-app-opt',
when='@:3.0.1',
msg='amd-app-opt is supported from 3.1 onwards')
conflicts(
'+amd-app-opt',
when='+mpi',
msg='mpi thread is not supported with amd-app-opt')
conflicts(
'+amd-app-opt',
when='precision=long_double',
msg='long_double precision is not supported with amd-app-opt')
conflicts(
'+amd-app-opt',
when='precision=quad',
msg='Quad precision is not supported with amd-app-opt')
def configure(self, spec, prefix): def configure(self, spec, prefix):
"""Configure function""" """Configure function"""
# Base options # Base options
options = [ options = ["--prefix={0}".format(prefix), "--enable-amd-opt"]
'--prefix={0}'.format(prefix),
'--enable-amd-opt'
]
# Check if compiler is AOCC # Check if compiler is AOCC
if '%aocc' in spec: if "%aocc" in spec:
options.append('CC={0}'.format(os.path.basename(spack_cc))) options.append("CC={0}".format(os.path.basename(spack_cc)))
options.append('FC={0}'.format(os.path.basename(spack_fc))) options.append("FC={0}".format(os.path.basename(spack_fc)))
options.append('F77={0}'.format(os.path.basename(spack_fc))) options.append("F77={0}".format(os.path.basename(spack_fc)))
if '+debug' in spec: if "+debug" in spec:
options.append('--enable-debug') options.append("--enable-debug")
if '+mpi' in spec: if "+mpi" in spec:
options.append('--enable-mpi') options.append("--enable-mpi")
options.append('--enable-amd-mpifft') options.append("--enable-amd-mpifft")
else: else:
options.append('--disable-mpi') options.append("--disable-mpi")
options.append('--disable-amd-mpifft') options.append("--disable-amd-mpifft")
options.extend(self.enable_or_disable('shared')) options.extend(self.enable_or_disable("shared"))
options.extend(self.enable_or_disable('openmp')) options.extend(self.enable_or_disable("openmp"))
options.extend(self.enable_or_disable('threads')) options.extend(self.enable_or_disable("threads"))
options.extend(self.enable_or_disable('amd-fast-planner')) options.extend(self.enable_or_disable("amd-fast-planner"))
options.extend(self.enable_or_disable('amd-top-n-planner')) options.extend(self.enable_or_disable("amd-top-n-planner"))
options.extend(self.enable_or_disable('amd-mpi-vader-limit')) options.extend(self.enable_or_disable("amd-mpi-vader-limit"))
options.extend(self.enable_or_disable('static')) options.extend(self.enable_or_disable("static"))
options.extend(self.enable_or_disable('amd-trans')) options.extend(self.enable_or_disable("amd-trans"))
options.extend(self.enable_or_disable('amd-app-opt')) options.extend(self.enable_or_disable("amd-app-opt"))
if not self.compiler.f77 or not self.compiler.fc: if not self.compiler.f77 or not self.compiler.fc:
options.append('--disable-fortran') options.append("--disable-fortran")
# Cross compilation is supported in amd-fftw by making use of target # Cross compilation is supported in amd-fftw by making use of target
# variable to set AMD_ARCH configure option. # variable to set AMD_ARCH configure option.
@@ -226,17 +196,16 @@ class Amdfftw(FftwBase):
# use target variable to set appropriate -march option in AMD_ARCH. # use target variable to set appropriate -march option in AMD_ARCH.
arch = spec.architecture arch = spec.architecture
options.append( options.append(
'AMD_ARCH={0}'.format( "AMD_ARCH={0}".format(arch.target.optimization_flags(spec.compiler).split("=")[-1])
arch.target.optimization_flags( )
spec.compiler).split('=')[-1]))
# Specific SIMD support. # Specific SIMD support.
# float and double precisions are supported # float and double precisions are supported
simd_features = ['sse2', 'avx', 'avx2'] simd_features = ["sse2", "avx", "avx2"]
simd_options = [] simd_options = []
for feature in simd_features: for feature in simd_features:
msg = '--enable-{0}' if feature in spec.target else '--disable-{0}' msg = "--enable-{0}" if feature in spec.target else "--disable-{0}"
simd_options.append(msg.format(feature)) simd_options.append(msg.format(feature))
# When enabling configure option "--enable-amd-opt", do not use the # When enabling configure option "--enable-amd-opt", do not use the
@@ -246,20 +215,19 @@ class Amdfftw(FftwBase):
# Double is the default precision, for all the others we need # Double is the default precision, for all the others we need
# to enable the corresponding option. # to enable the corresponding option.
enable_precision = { enable_precision = {
'float': ['--enable-float'], "float": ["--enable-float"],
'double': None, "double": None,
'long_double': ['--enable-long-double'], "long_double": ["--enable-long-double"],
'quad': ['--enable-quad-precision'] "quad": ["--enable-quad-precision"],
} }
# Different precisions must be configured and compiled one at a time # Different precisions must be configured and compiled one at a time
configure = Executable('../configure') configure = Executable("../configure")
for precision in self.selected_precisions: for precision in self.selected_precisions:
opts = (enable_precision[precision] or []) + options[:] opts = (enable_precision[precision] or []) + options[:]
# SIMD optimizations are available only for float and double # SIMD optimizations are available only for float and double
if precision in ('float', 'double'): if precision in ("float", "double"):
opts += simd_options opts += simd_options
with working_dir(precision, create=True): with working_dir(precision, create=True):

View File

@@ -34,7 +34,7 @@ class Legion(CMakePackage):
homepage = "https://legion.stanford.edu/" homepage = "https://legion.stanford.edu/"
git = "https://github.com/StanfordLegion/legion.git" git = "https://github.com/StanfordLegion/legion.git"
maintainers = ['pmccormick', 'streichler'] maintainers('pmccormick', 'streichler')
tags = ['e4s'] tags = ['e4s']
version('21.03.0', tag='legion-21.03.0') version('21.03.0', tag='legion-21.03.0')
version('stable', branch='stable') version('stable', branch='stable')
@@ -355,7 +355,7 @@ class Legion(CMakePackage):
def cache_test_sources(self): def cache_test_sources(self):
"""Copy the example source files after the package is installed to an """Copy the example source files after the package is installed to an
install test subdirectory for use during `spack test run`.""" install test subdirectory for use during `spack test run`."""
self.cache_extra_test_sources([join_path('examples', 'local_function_tasks')]) cache_extra_test_sources(self, [join_path('examples', 'local_function_tasks')])
def run_local_function_tasks_test(self): def run_local_function_tasks_test(self):
"""Run stand alone test: local_function_tasks""" """Run stand alone test: local_function_tasks"""

View File

@@ -16,21 +16,21 @@ from spack.package import *
class Llvm(CMakePackage, CudaPackage): class Llvm(CMakePackage, CudaPackage):
"""The LLVM Project is a collection of modular and reusable compiler and """The LLVM Project is a collection of modular and reusable compiler and
toolchain technologies. Despite its name, LLVM has little to do toolchain technologies. Despite its name, LLVM has little to do
with traditional virtual machines, though it does provide helpful with traditional virtual machines, though it does provide helpful
libraries that can be used to build them. The name "LLVM" itself libraries that can be used to build them. The name "LLVM" itself
is not an acronym; it is the full name of the project. is not an acronym; it is the full name of the project.
""" """
homepage = "https://llvm.org/" homepage = "https://llvm.org/"
url = "https://github.com/llvm/llvm-project/archive/llvmorg-7.1.0.tar.gz" url = "https://github.com/llvm/llvm-project/archive/llvmorg-7.1.0.tar.gz"
list_url = "https://releases.llvm.org/download.html" list_url = "https://releases.llvm.org/download.html"
git = "https://github.com/llvm/llvm-project" git = "https://github.com/llvm/llvm-project"
maintainers = ['trws', 'haampie'] maintainers("trws", "haampie")
tags = ['e4s'] tags = ["e4s"]
generator = 'Ninja' generator = "Ninja"
family = "compiler" # Used by lmod family = "compiler" # Used by lmod
@@ -80,13 +80,12 @@ class Llvm(CMakePackage, CudaPackage):
# to save space, build with `build_type=Release`. # to save space, build with `build_type=Release`.
variant( variant(
"clang", "clang", default=True, description="Build the LLVM C/C++/Objective-C compiler frontend"
default=True,
description="Build the LLVM C/C++/Objective-C compiler frontend",
) )
variant( variant(
"flang", "flang",
default=False, when='@11: +clang', default=False,
when="@11: +clang",
description="Build the LLVM Fortran compiler frontend " description="Build the LLVM Fortran compiler frontend "
"(experimental - parser only, needs GCC)", "(experimental - parser only, needs GCC)",
) )
@@ -95,27 +94,23 @@ class Llvm(CMakePackage, CudaPackage):
default=False, default=False,
description="Include debugging code in OpenMP runtime libraries", description="Include debugging code in OpenMP runtime libraries",
) )
variant("lldb", default=True, when='+clang', description="Build the LLVM debugger") variant("lldb", default=True, when="+clang", description="Build the LLVM debugger")
variant("lld", default=True, description="Build the LLVM linker") variant("lld", default=True, description="Build the LLVM linker")
variant("mlir", default=False, when='@10:', description="Build with MLIR support") variant("mlir", default=False, when="@10:", description="Build with MLIR support")
variant( variant(
"internal_unwind", "internal_unwind", default=True, when="+clang", description="Build the libcxxabi libunwind"
default=True, when='+clang',
description="Build the libcxxabi libunwind",
) )
variant( variant(
"polly", "polly",
default=True, default=True,
description="Build the LLVM polyhedral optimization plugin, " description="Build the LLVM polyhedral optimization plugin, " "only builds for 3.7.0+",
"only builds for 3.7.0+",
) )
variant( variant(
"libcxx", "libcxx", default=True, when="+clang", description="Build the LLVM C++ standard library"
default=True, when='+clang',
description="Build the LLVM C++ standard library",
) )
variant( variant(
"compiler-rt", when='+clang', "compiler-rt",
when="+clang",
default=True, default=True,
description="Build LLVM compiler runtime, including sanitizers", description="Build LLVM compiler runtime, including sanitizers",
) )
@@ -124,11 +119,7 @@ class Llvm(CMakePackage, CudaPackage):
default=(sys.platform != "darwin"), default=(sys.platform != "darwin"),
description="Add support for LTO with the gold linker plugin", description="Add support for LTO with the gold linker plugin",
) )
variant( variant("split_dwarf", default=False, description="Build with split dwarf information")
"split_dwarf",
default=False,
description="Build with split dwarf information",
)
variant( variant(
"llvm_dylib", "llvm_dylib",
default=True, default=True,
@@ -136,18 +127,40 @@ class Llvm(CMakePackage, CudaPackage):
) )
variant( variant(
"link_llvm_dylib", "link_llvm_dylib",
default=False, when='+llvm_dylib', default=False,
when="+llvm_dylib",
description="Link LLVM tools against the LLVM shared library", description="Link LLVM tools against the LLVM shared library",
) )
variant( variant(
"targets", "targets",
default="none", default="none",
description=("What targets to build. Spack's target family is always added " description=(
"(e.g. X86 is automatically enabled when targeting znver2)."), "What targets to build. Spack's target family is always added "
values=("all", "none", "aarch64", "amdgpu", "arm", "avr", "bpf", "cppbackend", "(e.g. X86 is automatically enabled when targeting znver2)."
"hexagon", "lanai", "mips", "msp430", "nvptx", "powerpc", "riscv", ),
"sparc", "systemz", "webassembly", "x86", "xcore"), values=(
multi=True "all",
"none",
"aarch64",
"amdgpu",
"arm",
"avr",
"bpf",
"cppbackend",
"hexagon",
"lanai",
"mips",
"msp430",
"nvptx",
"powerpc",
"riscv",
"sparc",
"systemz",
"webassembly",
"x86",
"xcore",
),
multi=True,
) )
variant( variant(
"build_type", "build_type",
@@ -157,51 +170,52 @@ class Llvm(CMakePackage, CudaPackage):
) )
variant( variant(
"omp_tsan", "omp_tsan",
default=False, when='@6:', default=False,
when="@6:",
description="Build with OpenMP capable thread sanitizer", description="Build with OpenMP capable thread sanitizer",
) )
variant( variant(
"omp_as_runtime", "omp_as_runtime",
default=True, default=True,
when='+clang @12:', when="+clang @12:",
description="Build OpenMP runtime via ENABLE_RUNTIME by just-built Clang", description="Build OpenMP runtime via ENABLE_RUNTIME by just-built Clang",
) )
variant('code_signing', default=False,
when='+lldb platform=darwin',
description="Enable code-signing on macOS")
variant("python", default=False, description="Install python bindings")
variant('version_suffix', default='none', description="Add a symbol suffix")
variant( variant(
'shlib_symbol_version', "code_signing",
default='none', default=False,
when="+lldb platform=darwin",
description="Enable code-signing on macOS",
)
variant("python", default=False, description="Install python bindings")
variant("version_suffix", default="none", description="Add a symbol suffix")
variant(
"shlib_symbol_version",
default="none",
description="Add shared library symbol version", description="Add shared library symbol version",
when='@13:' when="@13:",
) )
variant( variant(
'z3', "z3", default=False, when="+clang @8:", description="Use Z3 for the clang static analyzer"
default=False,
when='+clang @8:',
description='Use Z3 for the clang static analyzer'
) )
provides('libllvm@14', when='@14.0.0:14') provides("libllvm@14", when="@14.0.0:14")
provides('libllvm@13', when='@13.0.0:13') provides("libllvm@13", when="@13.0.0:13")
provides('libllvm@12', when='@12.0.0:12') provides("libllvm@12", when="@12.0.0:12")
provides('libllvm@11', when='@11.0.0:11') provides("libllvm@11", when="@11.0.0:11")
provides('libllvm@10', when='@10.0.0:10') provides("libllvm@10", when="@10.0.0:10")
provides('libllvm@9', when='@9.0.0:9') provides("libllvm@9", when="@9.0.0:9")
provides('libllvm@8', when='@8.0.0:8') provides("libllvm@8", when="@8.0.0:8")
provides('libllvm@7', when='@7.0.0:7') provides("libllvm@7", when="@7.0.0:7")
provides('libllvm@6', when='@6.0.0:6') provides("libllvm@6", when="@6.0.0:6")
provides('libllvm@5', when='@5.0.0:5') provides("libllvm@5", when="@5.0.0:5")
provides('libllvm@4', when='@4.0.0:4') provides("libllvm@4", when="@4.0.0:4")
provides('libllvm@3', when='@3.0.0:3') provides("libllvm@3", when="@3.0.0:3")
extends("python", when="+python") extends("python", when="+python")
# Build dependency # Build dependency
depends_on("cmake@3.4.3:", type="build") depends_on("cmake@3.4.3:", type="build")
depends_on('cmake@3.13.4:', type='build', when='@12:') depends_on("cmake@3.13.4:", type="build", when="@12:")
depends_on("ninja", type="build") depends_on("ninja", type="build")
depends_on("python@2.7:2.8", when="@:4 ~python", type="build") depends_on("python@2.7:2.8", when="@:4 ~python", type="build")
depends_on("python", when="@5: ~python", type="build") depends_on("python", when="@5: ~python", type="build")
@@ -242,7 +256,7 @@ class Llvm(CMakePackage, CudaPackage):
# clang/lib: a lambda parameter cannot shadow an explicitly captured entity # clang/lib: a lambda parameter cannot shadow an explicitly captured entity
conflicts("%clang@8:", when="@:4") conflicts("%clang@8:", when="@:4")
# Internal compiler error on gcc 8.4 on aarch64 https://bugzilla.redhat.com/show_bug.cgi?id=1958295 # Internal compiler error on gcc 8.4 on aarch64 https://bugzilla.redhat.com/show_bug.cgi?id=1958295
conflicts('%gcc@8.4:8.4.9', when='@12: target=aarch64:') conflicts("%gcc@8.4:8.4.9", when="@12: target=aarch64:")
# When these versions are concretized, but not explicitly with +libcxx, these # When these versions are concretized, but not explicitly with +libcxx, these
# conflicts will enable clingo to set ~libcxx, making the build successful: # conflicts will enable clingo to set ~libcxx, making the build successful:
@@ -252,17 +266,17 @@ class Llvm(CMakePackage, CudaPackage):
# GCC 11 - latest stable release per GCC release page # GCC 11 - latest stable release per GCC release page
# Clang: 11, 12 - latest two stable releases per LLVM release page # Clang: 11, 12 - latest two stable releases per LLVM release page
# AppleClang 12 - latest stable release per Xcode release page # AppleClang 12 - latest stable release per Xcode release page
conflicts("%gcc@:10", when="@13:+libcxx") conflicts("%gcc@:10", when="@13:+libcxx")
conflicts("%clang@:10", when="@13:+libcxx") conflicts("%clang@:10", when="@13:+libcxx")
conflicts("%apple-clang@:11", when="@13:+libcxx") conflicts("%apple-clang@:11", when="@13:+libcxx")
# libcxx-4 and compiler-rt-4 fail to build with "newer" clang and gcc versions: # libcxx-4 and compiler-rt-4 fail to build with "newer" clang and gcc versions:
conflicts('%gcc@7:', when='@:4+libcxx') conflicts("%gcc@7:", when="@:4+libcxx")
conflicts('%clang@6:', when='@:4+libcxx') conflicts("%clang@6:", when="@:4+libcxx")
conflicts('%apple-clang@6:', when='@:4+libcxx') conflicts("%apple-clang@6:", when="@:4+libcxx")
conflicts('%gcc@7:', when='@:4+compiler-rt') conflicts("%gcc@7:", when="@:4+compiler-rt")
conflicts('%clang@6:', when='@:4+compiler-rt') conflicts("%clang@6:", when="@:4+compiler-rt")
conflicts('%apple-clang@6:', when='@:4+compiler-rt') conflicts("%apple-clang@6:", when="@:4+compiler-rt")
# cuda_arch value must be specified # cuda_arch value must be specified
conflicts("cuda_arch=none", when="+cuda", msg="A value for cuda_arch must be specified.") conflicts("cuda_arch=none", when="+cuda", msg="A value for cuda_arch must be specified.")
@@ -270,27 +284,27 @@ class Llvm(CMakePackage, CudaPackage):
# LLVM bug https://bugs.llvm.org/show_bug.cgi?id=48234 # LLVM bug https://bugs.llvm.org/show_bug.cgi?id=48234
# CMake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/21469 # CMake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/21469
# Fixed in upstream versions of both # Fixed in upstream versions of both
conflicts('^cmake@3.19.0', when='@6:11.0.0') conflicts("^cmake@3.19.0", when="@6:11.0.0")
# Github issue #4986 # Github issue #4986
patch("llvm_gcc7.patch", when="@4.0.0:4.0.1+lldb %gcc@7.0:") patch("llvm_gcc7.patch", when="@4.0.0:4.0.1+lldb %gcc@7.0:")
# sys/ustat.h has been removed in favour of statfs from glibc-2.28. Use fixed sizes: # sys/ustat.h has been removed in favour of statfs from glibc-2.28. Use fixed sizes:
patch('llvm5-sanitizer-ustat.patch', when="@4:6.0.0+compiler-rt") patch("llvm5-sanitizer-ustat.patch", when="@4:6.0.0+compiler-rt")
# Fix lld templates: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=230463 # Fix lld templates: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=230463
patch('llvm4-lld-ELF-Symbols.patch', when="@4+lld%clang@6:") patch("llvm4-lld-ELF-Symbols.patch", when="@4+lld%clang@6:")
patch('llvm5-lld-ELF-Symbols.patch', when="@5+lld%clang@7:") patch("llvm5-lld-ELF-Symbols.patch", when="@5+lld%clang@7:")
# Fix missing std:size_t in 'llvm@4:5' when built with '%clang@7:' # Fix missing std:size_t in 'llvm@4:5' when built with '%clang@7:'
patch('xray_buffer_queue-cstddef.patch', when="@4:5+compiler-rt%clang@7:") patch("xray_buffer_queue-cstddef.patch", when="@4:5+compiler-rt%clang@7:")
# https://github.com/llvm/llvm-project/commit/947f9692440836dcb8d88b74b69dd379d85974ce # https://github.com/llvm/llvm-project/commit/947f9692440836dcb8d88b74b69dd379d85974ce
patch('sanitizer-ipc_perm_mode.patch', when="@5:7+compiler-rt%clang@11:") patch("sanitizer-ipc_perm_mode.patch", when="@5:7+compiler-rt%clang@11:")
patch('sanitizer-ipc_perm_mode.patch', when="@5:9+compiler-rt%gcc@9:") patch("sanitizer-ipc_perm_mode.patch", when="@5:9+compiler-rt%gcc@9:")
# github.com/spack/spack/issues/24270: MicrosoftDemangle for %gcc@10: and %clang@13: # github.com/spack/spack/issues/24270: MicrosoftDemangle for %gcc@10: and %clang@13:
patch('missing-includes.patch', when='@8') patch("missing-includes.patch", when="@8")
# Backport from llvm master + additional fix # Backport from llvm master + additional fix
# see https://bugs.llvm.org/show_bug.cgi?id=39696 # see https://bugs.llvm.org/show_bug.cgi?id=39696
@@ -315,33 +329,33 @@ class Llvm(CMakePackage, CudaPackage):
patch("llvm_python_path.patch", when="@:11") patch("llvm_python_path.patch", when="@:11")
# Workaround for issue https://github.com/spack/spack/issues/18197 # Workaround for issue https://github.com/spack/spack/issues/18197
patch('llvm7_intel.patch', when='@7 %intel@18.0.2,19.0.0:19.1.99') patch("llvm7_intel.patch", when="@7 %intel@18.0.2,19.0.0:19.1.99")
# Remove cyclades support to build against newer kernel headers # Remove cyclades support to build against newer kernel headers
# https://reviews.llvm.org/D102059 # https://reviews.llvm.org/D102059
patch('no_cyclades.patch', when='@10:12.0.0') patch("no_cyclades.patch", when="@10:12.0.0")
patch('no_cyclades9.patch', when='@6:9') patch("no_cyclades9.patch", when="@6:9")
patch('llvm-gcc11.patch', when='@9:11%gcc@11:') patch("llvm-gcc11.patch", when="@9:11%gcc@11:")
# add -lpthread to build OpenMP libraries with Fujitsu compiler # add -lpthread to build OpenMP libraries with Fujitsu compiler
patch('llvm12-thread.patch', when='@12 %fj') patch("llvm12-thread.patch", when="@12 %fj")
patch('llvm13-thread.patch', when='@13 %fj') patch("llvm13-thread.patch", when="@13 %fj")
# avoid build failed with Fujitsu compiler # avoid build failed with Fujitsu compiler
patch('llvm13-fujitsu.patch', when='@13 %fj') patch("llvm13-fujitsu.patch", when="@13 %fj")
# patch for missing hwloc.h include for libompd # patch for missing hwloc.h include for libompd
patch('llvm14-hwloc-ompd.patch', when='@14') patch("llvm14-hwloc-ompd.patch", when="@14")
# make libflags a list in openmp subproject when ~omp_as_runtime # make libflags a list in openmp subproject when ~omp_as_runtime
patch('libomp-libflags-as-list.patch', when='@3.7:') patch("libomp-libflags-as-list.patch", when="@3.7:")
# The functions and attributes below implement external package # The functions and attributes below implement external package
# detection for LLVM. See: # detection for LLVM. See:
# #
# https://spack.readthedocs.io/en/latest/packaging_guide.html#making-a-package-discoverable-with-spack-external-find # https://spack.readthedocs.io/en/latest/packaging_guide.html#making-a-package-discoverable-with-spack-external-find
executables = ['clang', 'flang', 'ld.lld', 'lldb'] executables = ["clang", "flang", "ld.lld", "lldb"]
@classmethod @classmethod
def filter_detected_exes(cls, prefix, exes_in_prefix): def filter_detected_exes(cls, prefix, exes_in_prefix):
@@ -351,7 +365,7 @@ class Llvm(CMakePackage, CudaPackage):
# on some port and would hang Spack during detection. # on some port and would hang Spack during detection.
# clang-cl and clang-cpp are dev tools that we don't # clang-cl and clang-cpp are dev tools that we don't
# need to test # need to test
if any(x in exe for x in ('vscode', 'cpp', '-cl', '-gpu')): if any(x in exe for x in ("vscode", "cpp", "-cl", "-gpu")):
continue continue
result.append(exe) result.append(exe)
return result return result
@@ -360,20 +374,20 @@ class Llvm(CMakePackage, CudaPackage):
def determine_version(cls, exe): def determine_version(cls, exe):
version_regex = re.compile( version_regex = re.compile(
# Normal clang compiler versions are left as-is # Normal clang compiler versions are left as-is
r'clang version ([^ )\n]+)-svn[~.\w\d-]*|' r"clang version ([^ )\n]+)-svn[~.\w\d-]*|"
# Don't include hyphenated patch numbers in the version # Don't include hyphenated patch numbers in the version
# (see https://github.com/spack/spack/pull/14365 for details) # (see https://github.com/spack/spack/pull/14365 for details)
r'clang version ([^ )\n]+?)-[~.\w\d-]*|' r"clang version ([^ )\n]+?)-[~.\w\d-]*|"
r'clang version ([^ )\n]+)|' r"clang version ([^ )\n]+)|"
# LLDB # LLDB
r'lldb version ([^ )\n]+)|' r"lldb version ([^ )\n]+)|"
# LLD # LLD
r'LLD ([^ )\n]+) \(compatible with GNU linkers\)' r"LLD ([^ )\n]+) \(compatible with GNU linkers\)"
) )
try: try:
compiler = Executable(exe) compiler = Executable(exe)
output = compiler('--version', output=str, error=str) output = compiler("--version", output=str, error=str)
if 'Apple' in output: if "Apple" in output:
return None return None
match = version_regex.search(output) match = version_regex.search(output)
if match: if match:
@@ -387,38 +401,39 @@ class Llvm(CMakePackage, CudaPackage):
@classmethod @classmethod
def determine_variants(cls, exes, version_str): def determine_variants(cls, exes, version_str):
variants, compilers = ['+clang'], {} variants, compilers = ["+clang"], {}
lld_found, lldb_found = False, False lld_found, lldb_found = False, False
for exe in exes: for exe in exes:
if 'clang++' in exe: if "clang++" in exe:
compilers['cxx'] = exe compilers["cxx"] = exe
elif 'clang' in exe: elif "clang" in exe:
compilers['c'] = exe compilers["c"] = exe
elif 'flang' in exe: elif "flang" in exe:
variants.append('+flang') variants.append("+flang")
compilers['fc'] = exe compilers["fc"] = exe
compilers['f77'] = exe compilers["f77"] = exe
elif 'ld.lld' in exe: elif "ld.lld" in exe:
lld_found = True lld_found = True
compilers['ld'] = exe compilers["ld"] = exe
elif 'lldb' in exe: elif "lldb" in exe:
lldb_found = True lldb_found = True
compilers['lldb'] = exe compilers["lldb"] = exe
variants.append('+lld' if lld_found else '~lld') variants.append("+lld" if lld_found else "~lld")
variants.append('+lldb' if lldb_found else '~lldb') variants.append("+lldb" if lldb_found else "~lldb")
return ''.join(variants), {'compilers': compilers} return "".join(variants), {"compilers": compilers}
@classmethod @classmethod
def validate_detected_spec(cls, spec, extra_attributes): def validate_detected_spec(cls, spec, extra_attributes):
# For LLVM 'compilers' is a mandatory attribute # For LLVM 'compilers' is a mandatory attribute
msg = ('the extra attribute "compilers" must be set for ' msg = 'the extra attribute "compilers" must be set for ' 'the detected spec "{0}"'.format(
'the detected spec "{0}"'.format(spec)) spec
assert 'compilers' in extra_attributes, msg )
compilers = extra_attributes['compilers'] assert "compilers" in extra_attributes, msg
for key in ('c', 'cxx'): compilers = extra_attributes["compilers"]
msg = '{0} compiler not found for {1}' for key in ("c", "cxx"):
msg = "{0} compiler not found for {1}"
assert key in compilers, msg.format(key, spec) assert key in compilers, msg.format(key, spec)
@property @property
@@ -426,10 +441,10 @@ class Llvm(CMakePackage, CudaPackage):
msg = "cannot retrieve C compiler [spec is not concrete]" msg = "cannot retrieve C compiler [spec is not concrete]"
assert self.spec.concrete, msg assert self.spec.concrete, msg
if self.spec.external: if self.spec.external:
return self.spec.extra_attributes['compilers'].get('c', None) return self.spec.extra_attributes["compilers"].get("c", None)
result = None result = None
if '+clang' in self.spec: if "+clang" in self.spec:
result = os.path.join(self.spec.prefix.bin, 'clang') result = os.path.join(self.spec.prefix.bin, "clang")
return result return result
@property @property
@@ -437,10 +452,10 @@ class Llvm(CMakePackage, CudaPackage):
msg = "cannot retrieve C++ compiler [spec is not concrete]" msg = "cannot retrieve C++ compiler [spec is not concrete]"
assert self.spec.concrete, msg assert self.spec.concrete, msg
if self.spec.external: if self.spec.external:
return self.spec.extra_attributes['compilers'].get('cxx', None) return self.spec.extra_attributes["compilers"].get("cxx", None)
result = None result = None
if '+clang' in self.spec: if "+clang" in self.spec:
result = os.path.join(self.spec.prefix.bin, 'clang++') result = os.path.join(self.spec.prefix.bin, "clang++")
return result return result
@property @property
@@ -448,10 +463,10 @@ class Llvm(CMakePackage, CudaPackage):
msg = "cannot retrieve Fortran compiler [spec is not concrete]" msg = "cannot retrieve Fortran compiler [spec is not concrete]"
assert self.spec.concrete, msg assert self.spec.concrete, msg
if self.spec.external: if self.spec.external:
return self.spec.extra_attributes['compilers'].get('fc', None) return self.spec.extra_attributes["compilers"].get("fc", None)
result = None result = None
if '+flang' in self.spec: if "+flang" in self.spec:
result = os.path.join(self.spec.prefix.bin, 'flang') result = os.path.join(self.spec.prefix.bin, "flang")
return result return result
@property @property
@@ -459,27 +474,25 @@ class Llvm(CMakePackage, CudaPackage):
msg = "cannot retrieve Fortran 77 compiler [spec is not concrete]" msg = "cannot retrieve Fortran 77 compiler [spec is not concrete]"
assert self.spec.concrete, msg assert self.spec.concrete, msg
if self.spec.external: if self.spec.external:
return self.spec.extra_attributes['compilers'].get('f77', None) return self.spec.extra_attributes["compilers"].get("f77", None)
result = None result = None
if '+flang' in self.spec: if "+flang" in self.spec:
result = os.path.join(self.spec.prefix.bin, 'flang') result = os.path.join(self.spec.prefix.bin, "flang")
return result return result
@property @property
def libs(self): def libs(self):
return LibraryList(self.llvm_config("--libfiles", "all", return LibraryList(self.llvm_config("--libfiles", "all", result="list"))
result="list"))
@run_before('cmake') @run_before("cmake")
def codesign_check(self): def codesign_check(self):
if self.spec.satisfies("+code_signing"): if self.spec.satisfies("+code_signing"):
codesign = which('codesign') codesign = which("codesign")
mkdir('tmp') mkdir("tmp")
llvm_check_file = join_path('tmp', 'llvm_check') llvm_check_file = join_path("tmp", "llvm_check")
copy('/usr/bin/false', llvm_check_file) copy("/usr/bin/false", llvm_check_file)
try: try:
codesign('-f', '-s', 'lldb_codesign', '--dryrun', codesign("-f", "-s", "lldb_codesign", "--dryrun", llvm_check_file)
llvm_check_file)
except ProcessError: except ProcessError:
# Newer LLVM versions have a simple script that sets up # Newer LLVM versions have a simple script that sets up
@@ -489,32 +502,32 @@ class Llvm(CMakePackage, CudaPackage):
setup() setup()
except Exception: except Exception:
raise RuntimeError( raise RuntimeError(
'spack was unable to either find or set up' "spack was unable to either find or set up"
'code-signing on your system. Please refer to' "code-signing on your system. Please refer to"
'https://lldb.llvm.org/resources/build.html#' "https://lldb.llvm.org/resources/build.html#"
'code-signing-on-macos for details on how to' "code-signing-on-macos for details on how to"
'create this identity.' "create this identity."
) )
def flag_handler(self, name, flags): def flag_handler(self, name, flags):
if name == 'cxxflags': if name == "cxxflags":
flags.append(self.compiler.cxx11_flag) flags.append(self.compiler.cxx11_flag)
return(None, flags, None) return (None, flags, None)
elif name == 'ldflags' and self.spec.satisfies('%intel'): elif name == "ldflags" and self.spec.satisfies("%intel"):
flags.append('-shared-intel') flags.append("-shared-intel")
return(None, flags, None) return (None, flags, None)
return(flags, None, None) return (flags, None, None)
def setup_build_environment(self, env): def setup_build_environment(self, env):
"""When using %clang, add only its ld.lld-$ver and/or ld.lld to our PATH""" """When using %clang, add only its ld.lld-$ver and/or ld.lld to our PATH"""
if self.compiler.name in ['clang', 'apple-clang']: if self.compiler.name in ["clang", "apple-clang"]:
for lld in 'ld.lld-{0}'.format(self.compiler.version.version[0]), 'ld.lld': for lld in "ld.lld-{0}".format(self.compiler.version.version[0]), "ld.lld":
bin = os.path.join(os.path.dirname(self.compiler.cc), lld) bin = os.path.join(os.path.dirname(self.compiler.cc), lld)
sym = os.path.join(self.stage.path, 'ld.lld') sym = os.path.join(self.stage.path, "ld.lld")
if os.path.exists(bin) and not os.path.exists(sym): if os.path.exists(bin) and not os.path.exists(sym):
mkdirp(self.stage.path) mkdirp(self.stage.path)
os.symlink(bin, sym) os.symlink(bin, sym)
env.prepend_path('PATH', self.stage.path) env.prepend_path("PATH", self.stage.path)
def setup_run_environment(self, env): def setup_run_environment(self, env):
if "+clang" in self.spec: if "+clang" in self.spec:
@@ -531,7 +544,7 @@ class Llvm(CMakePackage, CudaPackage):
define = CMakePackage.define define = CMakePackage.define
from_variant = self.define_from_variant from_variant = self.define_from_variant
python = spec['python'] python = spec["python"]
cmake_args = [ cmake_args = [
define("LLVM_REQUIRES_RTTI", True), define("LLVM_REQUIRES_RTTI", True),
define("LLVM_ENABLE_RTTI", True), define("LLVM_ENABLE_RTTI", True),
@@ -544,14 +557,13 @@ class Llvm(CMakePackage, CudaPackage):
define("LIBOMP_HWLOC_INSTALL_DIR", spec["hwloc"].prefix), define("LIBOMP_HWLOC_INSTALL_DIR", spec["hwloc"].prefix),
] ]
version_suffix = spec.variants['version_suffix'].value version_suffix = spec.variants["version_suffix"].value
if version_suffix != 'none': if version_suffix != "none":
cmake_args.append(define('LLVM_VERSION_SUFFIX', version_suffix)) cmake_args.append(define("LLVM_VERSION_SUFFIX", version_suffix))
shlib_symbol_version = spec.variants.get('shlib_symbol_version', None) shlib_symbol_version = spec.variants.get("shlib_symbol_version", None)
if shlib_symbol_version is not None and shlib_symbol_version.value != 'none': if shlib_symbol_version is not None and shlib_symbol_version.value != "none":
cmake_args.append(define('LLVM_SHLIB_SYMBOL_VERSION', cmake_args.append(define("LLVM_SHLIB_SYMBOL_VERSION", shlib_symbol_version.value))
shlib_symbol_version.value))
if python.version >= Version("3"): if python.version >= Version("3"):
cmake_args.append(define("Python3_EXECUTABLE", python.command.path)) cmake_args.append(define("Python3_EXECUTABLE", python.command.path))
@@ -562,47 +574,56 @@ class Llvm(CMakePackage, CudaPackage):
runtimes = [] runtimes = []
if "+cuda" in spec: if "+cuda" in spec:
cmake_args.extend([ cmake_args.extend(
define("CUDA_TOOLKIT_ROOT_DIR", spec["cuda"].prefix), [
define("LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES", define("CUDA_TOOLKIT_ROOT_DIR", spec["cuda"].prefix),
",".join(spec.variants["cuda_arch"].value)), define(
define("CLANG_OPENMP_NVPTX_DEFAULT_ARCH", "LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES",
"sm_{0}".format(spec.variants["cuda_arch"].value[-1])), ",".join(spec.variants["cuda_arch"].value),
]) ),
define(
"CLANG_OPENMP_NVPTX_DEFAULT_ARCH",
"sm_{0}".format(spec.variants["cuda_arch"].value[-1]),
),
]
)
if "+omp_as_runtime" in spec: if "+omp_as_runtime" in spec:
cmake_args.extend([ cmake_args.extend(
define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True), [
# work around bad libelf detection in libomptarget define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
define("LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR", # work around bad libelf detection in libomptarget
spec["libelf"].prefix.include), define(
]) "LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR", spec["libelf"].prefix.include
),
]
)
else: else:
# still build libomptarget but disable cuda # still build libomptarget but disable cuda
cmake_args.extend([ cmake_args.extend(
define("CUDA_TOOLKIT_ROOT_DIR", "IGNORE"), [
define("CUDA_SDK_ROOT_DIR", "IGNORE"), define("CUDA_TOOLKIT_ROOT_DIR", "IGNORE"),
define("CUDA_NVCC_EXECUTABLE", "IGNORE"), define("CUDA_SDK_ROOT_DIR", "IGNORE"),
define("LIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES", "IGNORE"), define("CUDA_NVCC_EXECUTABLE", "IGNORE"),
]) define("LIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES", "IGNORE"),
]
)
cmake_args.append(from_variant("LIBOMPTARGET_ENABLE_DEBUG", "omp_debug")) cmake_args.append(from_variant("LIBOMPTARGET_ENABLE_DEBUG", "omp_debug"))
if "+lldb" in spec: if "+lldb" in spec:
projects.append("lldb") projects.append("lldb")
cmake_args.append(define('LLDB_ENABLE_LIBEDIT', True)) cmake_args.append(define("LLDB_ENABLE_LIBEDIT", True))
cmake_args.append(define('LLDB_ENABLE_NCURSES', True)) cmake_args.append(define("LLDB_ENABLE_NCURSES", True))
cmake_args.append(define('LLDB_ENABLE_LIBXML2', False)) cmake_args.append(define("LLDB_ENABLE_LIBXML2", False))
if spec.version >= Version('10'): if spec.version >= Version("10"):
cmake_args.append(from_variant("LLDB_ENABLE_PYTHON", 'python')) cmake_args.append(from_variant("LLDB_ENABLE_PYTHON", "python"))
else: else:
cmake_args.append(define("LLDB_DISABLE_PYTHON", '~python' in spec)) cmake_args.append(define("LLDB_DISABLE_PYTHON", "~python" in spec))
if spec.satisfies("@5.0.0: +python"): if spec.satisfies("@5.0.0: +python"):
cmake_args.append(define("LLDB_USE_SYSTEM_SIX", True)) cmake_args.append(define("LLDB_USE_SYSTEM_SIX", True))
if "+gold" in spec: if "+gold" in spec:
cmake_args.append( cmake_args.append(define("LLVM_BINUTILS_INCDIR", spec["binutils"].prefix.include))
define("LLVM_BINUTILS_INCDIR", spec["binutils"].prefix.include)
)
if "+clang" in spec: if "+clang" in spec:
projects.append("clang") projects.append("clang")
@@ -612,10 +633,10 @@ class Llvm(CMakePackage, CudaPackage):
else: else:
projects.append("openmp") projects.append("openmp")
if '@8' in spec: if "@8" in spec:
cmake_args.append(from_variant('CLANG_ANALYZER_ENABLE_Z3_SOLVER', 'z3')) cmake_args.append(from_variant("CLANG_ANALYZER_ENABLE_Z3_SOLVER", "z3"))
elif '@9:' in spec: elif "@9:" in spec:
cmake_args.append(from_variant('LLVM_ENABLE_Z3_SOLVER', 'z3')) cmake_args.append(from_variant("LLVM_ENABLE_Z3_SOLVER", "z3"))
if "+flang" in spec: if "+flang" in spec:
projects.append("flang") projects.append("flang")
@@ -634,26 +655,26 @@ class Llvm(CMakePackage, CudaPackage):
projects.append("polly") projects.append("polly")
cmake_args.append(define("LINK_POLLY_INTO_TOOLS", True)) cmake_args.append(define("LINK_POLLY_INTO_TOOLS", True))
cmake_args.extend([ cmake_args.extend(
define("BUILD_SHARED_LIBS", False), [
from_variant("LLVM_BUILD_LLVM_DYLIB", "llvm_dylib"), define("BUILD_SHARED_LIBS", False),
from_variant("LLVM_LINK_LLVM_DYLIB", "link_llvm_dylib"), from_variant("LLVM_BUILD_LLVM_DYLIB", "llvm_dylib"),
from_variant("LLVM_USE_SPLIT_DWARF", "split_dwarf"), from_variant("LLVM_LINK_LLVM_DYLIB", "link_llvm_dylib"),
# By default on Linux, libc++.so is a ldscript. CMake fails to add from_variant("LLVM_USE_SPLIT_DWARF", "split_dwarf"),
# CMAKE_INSTALL_RPATH to it, which fails. Statically link libc++abi.a # By default on Linux, libc++.so is a ldscript. CMake fails to add
# into libc++.so, linking with -lc++ or -stdlib=libc++ is enough. # CMAKE_INSTALL_RPATH to it, which fails. Statically link libc++abi.a
define('LIBCXX_ENABLE_STATIC_ABI_LIBRARY', True) # into libc++.so, linking with -lc++ or -stdlib=libc++ is enough.
]) define("LIBCXX_ENABLE_STATIC_ABI_LIBRARY", True),
]
)
cmake_args.append(define( cmake_args.append(define("LLVM_TARGETS_TO_BUILD", get_llvm_targets_to_build(spec)))
"LLVM_TARGETS_TO_BUILD",
get_llvm_targets_to_build(spec)))
cmake_args.append(from_variant("LIBOMP_TSAN_SUPPORT", "omp_tsan")) cmake_args.append(from_variant("LIBOMP_TSAN_SUPPORT", "omp_tsan"))
if self.compiler.name == "gcc": if self.compiler.name == "gcc":
compiler = Executable(self.compiler.cc) compiler = Executable(self.compiler.cc)
gcc_output = compiler('-print-search-dirs', output=str, error=str) gcc_output = compiler("-print-search-dirs", output=str, error=str)
for line in gcc_output.splitlines(): for line in gcc_output.splitlines():
if line.startswith("install:"): if line.startswith("install:"):
@@ -665,7 +686,7 @@ class Llvm(CMakePackage, CudaPackage):
cmake_args.append(define("GCC_INSTALL_PREFIX", gcc_prefix)) cmake_args.append(define("GCC_INSTALL_PREFIX", gcc_prefix))
if self.spec.satisfies("~code_signing platform=darwin"): if self.spec.satisfies("~code_signing platform=darwin"):
cmake_args.append(define('LLDB_USE_SYSTEM_DEBUGSERVER', True)) cmake_args.append(define("LLDB_USE_SYSTEM_DEBUGSERVER", True))
# Semicolon seperated list of projects to enable # Semicolon seperated list of projects to enable
cmake_args.append(define("LLVM_ENABLE_PROJECTS", projects)) cmake_args.append(define("LLVM_ENABLE_PROJECTS", projects))
@@ -689,20 +710,24 @@ class Llvm(CMakePackage, CudaPackage):
# rebuild libomptarget to get bytecode runtime library files # rebuild libomptarget to get bytecode runtime library files
with working_dir(ompdir, create=True): with working_dir(ompdir, create=True):
cmake_args = [ cmake_args = [
'-G', 'Ninja', "-G",
define('CMAKE_BUILD_TYPE', spec.variants['build_type'].value), "Ninja",
define("CMAKE_BUILD_TYPE", spec.variants["build_type"].value),
define("CMAKE_C_COMPILER", spec.prefix.bin + "/clang"), define("CMAKE_C_COMPILER", spec.prefix.bin + "/clang"),
define("CMAKE_CXX_COMPILER", spec.prefix.bin + "/clang++"), define("CMAKE_CXX_COMPILER", spec.prefix.bin + "/clang++"),
define("CMAKE_INSTALL_PREFIX", spec.prefix), define("CMAKE_INSTALL_PREFIX", spec.prefix),
define('CMAKE_PREFIX_PATH', prefix_paths) define("CMAKE_PREFIX_PATH", prefix_paths),
] ]
cmake_args.extend(self.cmake_args()) cmake_args.extend(self.cmake_args())
cmake_args.extend([ cmake_args.extend(
define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True), [
define("LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR", define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
spec["libelf"].prefix.include), define(
self.stage.source_path + "/openmp", "LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR", spec["libelf"].prefix.include
]) ),
self.stage.source_path + "/openmp",
]
)
cmake(*cmake_args) cmake(*cmake_args)
ninja() ninja()
@@ -717,22 +742,22 @@ class Llvm(CMakePackage, CudaPackage):
install_tree("bin", join_path(self.prefix, "libexec", "llvm")) install_tree("bin", join_path(self.prefix, "libexec", "llvm"))
def llvm_config(self, *args, **kwargs): def llvm_config(self, *args, **kwargs):
lc = Executable(self.prefix.bin.join('llvm-config')) lc = Executable(self.prefix.bin.join("llvm-config"))
if not kwargs.get('output'): if not kwargs.get("output"):
kwargs['output'] = str kwargs["output"] = str
ret = lc(*args, **kwargs) ret = lc(*args, **kwargs)
if kwargs.get('result') == "list": if kwargs.get("result") == "list":
return ret.split() return ret.split()
else: else:
return ret return ret
def get_llvm_targets_to_build(spec): def get_llvm_targets_to_build(spec):
targets = spec.variants['targets'].value targets = spec.variants["targets"].value
# Build everything? # Build everything?
if 'all' in targets: if "all" in targets:
return 'all' return "all"
# Convert targets variant values to CMake LLVM_TARGETS_TO_BUILD array. # Convert targets variant values to CMake LLVM_TARGETS_TO_BUILD array.
spack_to_cmake = { spack_to_cmake = {
@@ -753,10 +778,10 @@ def get_llvm_targets_to_build(spec):
"systemz": "SystemZ", "systemz": "SystemZ",
"webassembly": "WebAssembly", "webassembly": "WebAssembly",
"x86": "X86", "x86": "X86",
"xcore": "XCore" "xcore": "XCore",
} }
if 'none' in targets: if "none" in targets:
llvm_targets = set() llvm_targets = set()
else: else:
llvm_targets = set(spack_to_cmake[target] for target in targets) llvm_targets = set(spack_to_cmake[target] for target in targets)

View File

@@ -27,8 +27,7 @@ class Mfem(Package, CudaPackage, ROCmPackage):
homepage = 'http://www.mfem.org' homepage = 'http://www.mfem.org'
git = 'https://github.com/mfem/mfem.git' git = 'https://github.com/mfem/mfem.git'
maintainers = ['v-dobrev', 'tzanio', 'acfisher', maintainers('v-dobrev', 'tzanio', 'acfisher', 'goxberry', 'markcmiller86')
'goxberry', 'markcmiller86']
test_requires_compiler = True test_requires_compiler = True
@@ -815,8 +814,7 @@ class Mfem(Package, CudaPackage, ROCmPackage):
def cache_test_sources(self): def cache_test_sources(self):
"""Copy the example source files after the package is installed to an """Copy the example source files after the package is installed to an
install test subdirectory for use during `spack test run`.""" install test subdirectory for use during `spack test run`."""
self.cache_extra_test_sources([self.examples_src_dir, cache_extra_test_sources(self, [self.examples_src_dir, self.examples_data_dir])
self.examples_data_dir])
def test(self): def test(self):
test_dir = join_path( test_dir = join_path(

View File

@@ -22,127 +22,140 @@ class PyTorch(PythonPackage, CudaPackage):
with strong GPU acceleration.""" with strong GPU acceleration."""
homepage = "https://pytorch.org/" homepage = "https://pytorch.org/"
git = "https://github.com/pytorch/pytorch.git" git = "https://github.com/pytorch/pytorch.git"
maintainers = ['adamjstewart'] maintainers("adamjstewart")
# Exact set of modules is version- and variant-specific, just attempt to import the # Exact set of modules is version- and variant-specific, just attempt to import the
# core libraries to ensure that the package was successfully installed. # core libraries to ensure that the package was successfully installed.
import_modules = ['torch', 'torch.autograd', 'torch.nn', 'torch.utils'] import_modules = ["torch", "torch.autograd", "torch.nn", "torch.utils"]
version('master', branch='master', submodules=True) version("master", branch="master", submodules=True)
version('1.10.1', tag='v1.10.1', submodules=True) version("1.10.1", tag="v1.10.1", submodules=True)
version('1.10.0', tag='v1.10.0', submodules=True) version("1.10.0", tag="v1.10.0", submodules=True)
version('1.9.1', tag='v1.9.1', submodules=True) version("1.9.1", tag="v1.9.1", submodules=True)
version('1.9.0', tag='v1.9.0', submodules=True) version("1.9.0", tag="v1.9.0", submodules=True)
version('1.8.2', tag='v1.8.2', submodules=True) version("1.8.2", tag="v1.8.2", submodules=True)
version('1.8.1', tag='v1.8.1', submodules=True) version("1.8.1", tag="v1.8.1", submodules=True)
version('1.8.0', tag='v1.8.0', submodules=True) version("1.8.0", tag="v1.8.0", submodules=True)
version('1.7.1', tag='v1.7.1', submodules=True) version("1.7.1", tag="v1.7.1", submodules=True)
version('1.7.0', tag='v1.7.0', submodules=True) version("1.7.0", tag="v1.7.0", submodules=True)
version('1.6.0', tag='v1.6.0', submodules=True) version("1.6.0", tag="v1.6.0", submodules=True)
version('1.5.1', tag='v1.5.1', submodules=True) version("1.5.1", tag="v1.5.1", submodules=True)
version('1.5.0', tag='v1.5.0', submodules=True) version("1.5.0", tag="v1.5.0", submodules=True)
version('1.4.1', tag='v1.4.1', submodules=True) version("1.4.1", tag="v1.4.1", submodules=True)
version('1.4.0', tag='v1.4.0', submodules=True, deprecated=True, version(
submodules_delete=['third_party/fbgemm']) "1.4.0",
version('1.3.1', tag='v1.3.1', submodules=True) tag="v1.4.0",
version('1.3.0', tag='v1.3.0', submodules=True) submodules=True,
version('1.2.0', tag='v1.2.0', submodules=True) deprecated=True,
version('1.1.0', tag='v1.1.0', submodules=True) submodules_delete=["third_party/fbgemm"],
version('1.0.1', tag='v1.0.1', submodules=True) )
version('1.0.0', tag='v1.0.0', submodules=True) version("1.3.1", tag="v1.3.1", submodules=True)
version('0.4.1', tag='v0.4.1', submodules=True, deprecated=True, version("1.3.0", tag="v1.3.0", submodules=True)
submodules_delete=['third_party/nervanagpu']) version("1.2.0", tag="v1.2.0", submodules=True)
version('0.4.0', tag='v0.4.0', submodules=True, deprecated=True) version("1.1.0", tag="v1.1.0", submodules=True)
version('0.3.1', tag='v0.3.1', submodules=True, deprecated=True) version("1.0.1", tag="v1.0.1", submodules=True)
version("1.0.0", tag="v1.0.0", submodules=True)
version(
"0.4.1",
tag="v0.4.1",
submodules=True,
deprecated=True,
submodules_delete=["third_party/nervanagpu"],
)
version("0.4.0", tag="v0.4.0", submodules=True, deprecated=True)
version("0.3.1", tag="v0.3.1", submodules=True, deprecated=True)
is_darwin = sys.platform == 'darwin' is_darwin = sys.platform == "darwin"
# All options are defined in CMakeLists.txt. # All options are defined in CMakeLists.txt.
# Some are listed in setup.py, but not all. # Some are listed in setup.py, but not all.
variant('caffe2', default=True, description='Build Caffe2') variant("caffe2", default=True, description="Build Caffe2")
variant('test', default=False, description='Build C++ test binaries') variant("test", default=False, description="Build C++ test binaries")
variant('cuda', default=not is_darwin, description='Use CUDA') variant("cuda", default=not is_darwin, description="Use CUDA")
variant('rocm', default=False, description='Use ROCm') variant("rocm", default=False, description="Use ROCm")
variant('cudnn', default=not is_darwin, description='Use cuDNN') variant("cudnn", default=not is_darwin, description="Use cuDNN")
variant('fbgemm', default=True, description='Use FBGEMM (quantized 8-bit server operators)') variant("fbgemm", default=True, description="Use FBGEMM (quantized 8-bit server operators)")
variant('kineto', default=True, description='Use Kineto profiling library') variant("kineto", default=True, description="Use Kineto profiling library")
variant('magma', default=not is_darwin, description='Use MAGMA') variant("magma", default=not is_darwin, description="Use MAGMA")
variant('metal', default=is_darwin, description='Use Metal for Caffe2 iOS build') variant("metal", default=is_darwin, description="Use Metal for Caffe2 iOS build")
variant('nccl', default=not is_darwin, description='Use NCCL') variant("nccl", default=not is_darwin, description="Use NCCL")
variant('nnpack', default=True, description='Use NNPACK') variant("nnpack", default=True, description="Use NNPACK")
variant('numa', default=not is_darwin, description='Use NUMA') variant("numa", default=not is_darwin, description="Use NUMA")
variant('numpy', default=True, description='Use NumPy') variant("numpy", default=True, description="Use NumPy")
variant('openmp', default=True, description='Use OpenMP for parallel code') variant("openmp", default=True, description="Use OpenMP for parallel code")
variant('qnnpack', default=True, description='Use QNNPACK (quantized 8-bit operators)') variant("qnnpack", default=True, description="Use QNNPACK (quantized 8-bit operators)")
variant('valgrind', default=not is_darwin, description='Use Valgrind') variant("valgrind", default=not is_darwin, description="Use Valgrind")
variant('xnnpack', default=True, description='Use XNNPACK') variant("xnnpack", default=True, description="Use XNNPACK")
variant('mkldnn', default=True, description='Use MKLDNN') variant("mkldnn", default=True, description="Use MKLDNN")
variant('distributed', default=not is_darwin, description='Use distributed') variant("distributed", default=not is_darwin, description="Use distributed")
variant('mpi', default=not is_darwin, description='Use MPI for Caffe2') variant("mpi", default=not is_darwin, description="Use MPI for Caffe2")
variant('gloo', default=not is_darwin, description='Use Gloo') variant("gloo", default=not is_darwin, description="Use Gloo")
variant('tensorpipe', default=not is_darwin, description='Use TensorPipe') variant("tensorpipe", default=not is_darwin, description="Use TensorPipe")
variant('onnx_ml', default=True, description='Enable traditional ONNX ML API') variant("onnx_ml", default=True, description="Enable traditional ONNX ML API")
variant('breakpad', default=True, description='Enable breakpad crash dump library') variant("breakpad", default=True, description="Enable breakpad crash dump library")
conflicts('+cuda', when='+rocm') conflicts("+cuda", when="+rocm")
conflicts('+cudnn', when='~cuda') conflicts("+cudnn", when="~cuda")
conflicts('+magma', when='~cuda') conflicts("+magma", when="~cuda")
conflicts('+nccl', when='~cuda~rocm') conflicts("+nccl", when="~cuda~rocm")
conflicts('+nccl', when='platform=darwin') conflicts("+nccl", when="platform=darwin")
conflicts('+numa', when='platform=darwin', msg='Only available on Linux') conflicts("+numa", when="platform=darwin", msg="Only available on Linux")
conflicts('+valgrind', when='platform=darwin', msg='Only available on Linux') conflicts("+valgrind", when="platform=darwin", msg="Only available on Linux")
conflicts('+mpi', when='~distributed') conflicts("+mpi", when="~distributed")
conflicts('+gloo', when='~distributed') conflicts("+gloo", when="~distributed")
conflicts('+tensorpipe', when='~distributed') conflicts("+tensorpipe", when="~distributed")
conflicts('+kineto', when='@:1.7') conflicts("+kineto", when="@:1.7")
conflicts('+valgrind', when='@:1.7') conflicts("+valgrind", when="@:1.7")
conflicts('~caffe2', when='@0.4.0:1.6') # no way to disable caffe2? conflicts("~caffe2", when="@0.4.0:1.6") # no way to disable caffe2?
conflicts('+caffe2', when='@:0.3.1') # caffe2 did not yet exist? conflicts("+caffe2", when="@:0.3.1") # caffe2 did not yet exist?
conflicts('+tensorpipe', when='@:1.5') conflicts("+tensorpipe", when="@:1.5")
conflicts('+xnnpack', when='@:1.4') conflicts("+xnnpack", when="@:1.4")
conflicts('~onnx_ml', when='@:1.4') # no way to disable ONNX? conflicts("~onnx_ml", when="@:1.4") # no way to disable ONNX?
conflicts('+rocm', when='@:0.4') conflicts("+rocm", when="@:0.4")
conflicts('+cudnn', when='@:0.4') conflicts("+cudnn", when="@:0.4")
conflicts('+fbgemm', when='@:0.4,1.4.0') conflicts("+fbgemm", when="@:0.4,1.4.0")
conflicts('+qnnpack', when='@:0.4') conflicts("+qnnpack", when="@:0.4")
conflicts('+mkldnn', when='@:0.4') conflicts("+mkldnn", when="@:0.4")
conflicts('+breakpad', when='@:1.9') # Option appeared in 1.10.0 conflicts("+breakpad", when="@:1.9") # Option appeared in 1.10.0
conflicts('+breakpad', when='target=ppc64:', msg='Unsupported') conflicts("+breakpad", when="target=ppc64:", msg="Unsupported")
conflicts('+breakpad', when='target=ppc64le:', msg='Unsupported') conflicts("+breakpad", when="target=ppc64le:", msg="Unsupported")
conflicts('cuda_arch=none', when='+cuda', conflicts(
msg='Must specify CUDA compute capabilities of your GPU, see ' "cuda_arch=none",
'https://developer.nvidia.com/cuda-gpus') when="+cuda",
msg="Must specify CUDA compute capabilities of your GPU, see "
"https://developer.nvidia.com/cuda-gpus",
)
# Required dependencies # Required dependencies
depends_on('cmake@3.5:', type='build') depends_on("cmake@3.5:", type="build")
# Use Ninja generator to speed up build times, automatically used if found # Use Ninja generator to speed up build times, automatically used if found
depends_on('ninja@1.5:', when='@1.1.0:', type='build') depends_on("ninja@1.5:", when="@1.1.0:", type="build")
# See python_min_version in setup.py # See python_min_version in setup.py
depends_on('python@3.6.2:', when='@1.7.1:', type=('build', 'link', 'run')) depends_on("python@3.6.2:", when="@1.7.1:", type=("build", "link", "run"))
depends_on('python@3.6.1:', when='@1.6.0:1.7.0', type=('build', 'link', 'run')) depends_on("python@3.6.1:", when="@1.6.0:1.7.0", type=("build", "link", "run"))
depends_on('python@3.5:', when='@1.5.0:1.5', type=('build', 'link', 'run')) depends_on("python@3.5:", when="@1.5.0:1.5", type=("build", "link", "run"))
depends_on('python@2.7:2.8,3.5:', when='@1.4.0:1.4', type=('build', 'link', 'run')) depends_on("python@2.7:2.8,3.5:", when="@1.4.0:1.4", type=("build", "link", "run"))
depends_on('python@2.7:2.8,3.5:3.7', when='@:1.3', type=('build', 'link', 'run')) depends_on("python@2.7:2.8,3.5:3.7", when="@:1.3", type=("build", "link", "run"))
depends_on('py-setuptools', type=('build', 'run')) depends_on("py-setuptools", type=("build", "run"))
depends_on('py-future', when='@1.5:', type=('build', 'run')) depends_on("py-future", when="@1.5:", type=("build", "run"))
depends_on('py-future', when='@1.1: ^python@:2', type=('build', 'run')) depends_on("py-future", when="@1.1: ^python@:2", type=("build", "run"))
depends_on('py-pyyaml', type=('build', 'run')) depends_on("py-pyyaml", type=("build", "run"))
depends_on('py-typing', when='@0.4: ^python@:3.4', type=('build', 'run')) depends_on("py-typing", when="@0.4: ^python@:3.4", type=("build", "run"))
depends_on('py-typing-extensions', when='@1.7:', type=('build', 'run')) depends_on("py-typing-extensions", when="@1.7:", type=("build", "run"))
depends_on('py-pybind11@2.6.2', when='@1.8.0:', type=('build', 'link', 'run')) depends_on("py-pybind11@2.6.2", when="@1.8.0:", type=("build", "link", "run"))
depends_on('py-pybind11@2.3.0', when='@1.1.0:1.7', type=('build', 'link', 'run')) depends_on("py-pybind11@2.3.0", when="@1.1.0:1.7", type=("build", "link", "run"))
depends_on('py-pybind11@2.2.4', when='@1.0.0:1.0', type=('build', 'link', 'run')) depends_on("py-pybind11@2.2.4", when="@1.0.0:1.0", type=("build", "link", "run"))
depends_on('py-pybind11@2.2.2', when='@0.4.0:0.4', type=('build', 'link', 'run')) depends_on("py-pybind11@2.2.2", when="@0.4.0:0.4", type=("build", "link", "run"))
depends_on('py-dataclasses', when='@1.7: ^python@3.6.0:3.6', type=('build', 'run')) depends_on("py-dataclasses", when="@1.7: ^python@3.6.0:3.6", type=("build", "run"))
depends_on('py-tqdm', type='run') depends_on("py-tqdm", type="run")
depends_on('py-protobuf', when='@0.4:', type=('build', 'run')) depends_on("py-protobuf", when="@0.4:", type=("build", "run"))
depends_on('protobuf', when='@0.4:') depends_on("protobuf", when="@0.4:")
depends_on('blas') depends_on("blas")
depends_on('lapack') depends_on("lapack")
depends_on('eigen', when='@0.4:') depends_on("eigen", when="@0.4:")
# https://github.com/pytorch/pytorch/issues/60329 # https://github.com/pytorch/pytorch/issues/60329
# depends_on('cpuinfo@2020-12-17', when='@1.8.0:') # depends_on('cpuinfo@2020-12-17', when='@1.8.0:')
# depends_on('cpuinfo@2020-06-11', when='@1.6.0:1.7') # depends_on('cpuinfo@2020-06-11', when='@1.6.0:1.7')
@@ -152,30 +165,30 @@ class PyTorch(PythonPackage, CudaPackage):
# depends_on('sleef@3.4.0_2019-07-30', when='@1.6.0:1.7') # depends_on('sleef@3.4.0_2019-07-30', when='@1.6.0:1.7')
# https://github.com/Maratyszcza/FP16/issues/18 # https://github.com/Maratyszcza/FP16/issues/18
# depends_on('fp16@2020-05-14', when='@1.6.0:') # depends_on('fp16@2020-05-14', when='@1.6.0:')
depends_on('pthreadpool@2021-04-13', when='@1.9.0:') depends_on("pthreadpool@2021-04-13", when="@1.9.0:")
depends_on('pthreadpool@2020-10-05', when='@1.8.0:1.8') depends_on("pthreadpool@2020-10-05", when="@1.8.0:1.8")
depends_on('pthreadpool@2020-06-15', when='@1.6.0:1.7') depends_on("pthreadpool@2020-06-15", when="@1.6.0:1.7")
depends_on('psimd@2020-05-17', when='@1.6.0:') depends_on("psimd@2020-05-17", when="@1.6.0:")
depends_on('fxdiv@2020-04-17', when='@1.6.0:') depends_on("fxdiv@2020-04-17", when="@1.6.0:")
depends_on('benchmark', when='@1.6:+test') depends_on("benchmark", when="@1.6:+test")
# Optional dependencies # Optional dependencies
depends_on('cuda@7.5:', when='+cuda', type=('build', 'link', 'run')) depends_on("cuda@7.5:", when="+cuda", type=("build", "link", "run"))
depends_on('cuda@9:', when='@1.1:+cuda', type=('build', 'link', 'run')) depends_on("cuda@9:", when="@1.1:+cuda", type=("build", "link", "run"))
depends_on('cuda@9.2:', when='@1.6:+cuda', type=('build', 'link', 'run')) depends_on("cuda@9.2:", when="@1.6:+cuda", type=("build", "link", "run"))
depends_on('cudnn@6.0:7', when='@:1.0+cudnn') depends_on("cudnn@6.0:7", when="@:1.0+cudnn")
depends_on('cudnn@7.0:7', when='@1.1.0:1.5+cudnn') depends_on("cudnn@7.0:7", when="@1.1.0:1.5+cudnn")
depends_on('cudnn@7.0:', when='@1.6.0:+cudnn') depends_on("cudnn@7.0:", when="@1.6.0:+cudnn")
depends_on('magma', when='+magma') depends_on("magma", when="+magma")
depends_on('nccl', when='+nccl') depends_on("nccl", when="+nccl")
depends_on('numactl', when='+numa') depends_on("numactl", when="+numa")
depends_on('py-numpy', when='+numpy', type=('build', 'run')) depends_on("py-numpy", when="+numpy", type=("build", "run"))
depends_on('llvm-openmp', when='%apple-clang +openmp') depends_on("llvm-openmp", when="%apple-clang +openmp")
depends_on('valgrind', when='+valgrind') depends_on("valgrind", when="+valgrind")
# https://github.com/pytorch/pytorch/issues/60332 # https://github.com/pytorch/pytorch/issues/60332
# depends_on('xnnpack@2021-02-22', when='@1.8.0:+xnnpack') # depends_on('xnnpack@2021-02-22', when='@1.8.0:+xnnpack')
# depends_on('xnnpack@2020-03-23', when='@1.6.0:1.7+xnnpack') # depends_on('xnnpack@2020-03-23', when='@1.6.0:1.7+xnnpack')
depends_on('mpi', when='+mpi') depends_on("mpi", when="+mpi")
# https://github.com/pytorch/pytorch/issues/60270 # https://github.com/pytorch/pytorch/issues/60270
# depends_on('gloo@2021-05-04', when='@1.9.0:+gloo') # depends_on('gloo@2021-05-04', when='@1.9.0:+gloo')
# depends_on('gloo@2020-09-18', when='@1.7.0:1.8+gloo') # depends_on('gloo@2020-09-18', when='@1.7.0:1.8+gloo')
@@ -183,31 +196,35 @@ class PyTorch(PythonPackage, CudaPackage):
# https://github.com/pytorch/pytorch/issues/60331 # https://github.com/pytorch/pytorch/issues/60331
# depends_on('onnx@1.8.0_2020-11-03', when='@1.8.0:+onnx_ml') # depends_on('onnx@1.8.0_2020-11-03', when='@1.8.0:+onnx_ml')
# depends_on('onnx@1.7.0_2020-05-31', when='@1.6.0:1.7+onnx_ml') # depends_on('onnx@1.7.0_2020-05-31', when='@1.6.0:1.7+onnx_ml')
depends_on('mkl', when='+mkldnn') depends_on("mkl", when="+mkldnn")
# Test dependencies # Test dependencies
depends_on('py-hypothesis', type='test') depends_on("py-hypothesis", type="test")
depends_on('py-six', type='test') depends_on("py-six", type="test")
depends_on('py-psutil', type='test') depends_on("py-psutil", type="test")
# Fix BLAS being overridden by MKL # Fix BLAS being overridden by MKL
# https://github.com/pytorch/pytorch/issues/60328 # https://github.com/pytorch/pytorch/issues/60328
patch('https://patch-diff.githubusercontent.com/raw/pytorch/pytorch/pull/59220.patch', patch(
sha256='e37afffe45cf7594c22050109942370e49983ad772d12ebccf508377dc9dcfc9', "https://patch-diff.githubusercontent.com/raw/pytorch/pytorch/pull/59220.patch",
when='@1.2.0:') sha256="e37afffe45cf7594c22050109942370e49983ad772d12ebccf508377dc9dcfc9",
when="@1.2.0:",
)
# Fixes build on older systems with glibc <2.12 # Fixes build on older systems with glibc <2.12
patch('https://patch-diff.githubusercontent.com/raw/pytorch/pytorch/pull/55063.patch', patch(
sha256='e17eaa42f5d7c18bf0d7c37d7b0910127a01ad53fdce3e226a92893356a70395', "https://patch-diff.githubusercontent.com/raw/pytorch/pytorch/pull/55063.patch",
when='@1.1.0:1.8.1') sha256="e17eaa42f5d7c18bf0d7c37d7b0910127a01ad53fdce3e226a92893356a70395",
when="@1.1.0:1.8.1",
)
# Fixes CMake configuration error when XNNPACK is disabled # Fixes CMake configuration error when XNNPACK is disabled
# https://github.com/pytorch/pytorch/pull/35607 # https://github.com/pytorch/pytorch/pull/35607
# https://github.com/pytorch/pytorch/pull/37865 # https://github.com/pytorch/pytorch/pull/37865
patch('xnnpack.patch', when='@1.5.0:1.5') patch("xnnpack.patch", when="@1.5.0:1.5")
# Fixes build error when ROCm is enabled for pytorch-1.5 release # Fixes build error when ROCm is enabled for pytorch-1.5 release
patch('rocm.patch', when='@1.5.0:1.5+rocm') patch("rocm.patch", when="@1.5.0:1.5+rocm")
# Fixes fatal error: sleef.h: No such file or directory # Fixes fatal error: sleef.h: No such file or directory
# https://github.com/pytorch/pytorch/pull/35359 # https://github.com/pytorch/pytorch/pull/35359
@@ -216,47 +233,56 @@ class PyTorch(PythonPackage, CudaPackage):
# Fixes compilation with Clang 9.0.0 and Apple Clang 11.0.3 # Fixes compilation with Clang 9.0.0 and Apple Clang 11.0.3
# https://github.com/pytorch/pytorch/pull/37086 # https://github.com/pytorch/pytorch/pull/37086
patch('https://github.com/pytorch/pytorch/commit/e921cd222a8fbeabf5a3e74e83e0d8dfb01aa8b5.patch', patch(
sha256='17561b16cd2db22f10c0fe1fdcb428aecb0ac3964ba022a41343a6bb8cba7049', "https://github.com/pytorch/pytorch/commit/e921cd222a8fbeabf5a3e74e83e0d8dfb01aa8b5.patch",
when='@1.1:1.5') sha256="17561b16cd2db22f10c0fe1fdcb428aecb0ac3964ba022a41343a6bb8cba7049",
when="@1.1:1.5",
)
# Removes duplicate definition of getCusparseErrorString # Removes duplicate definition of getCusparseErrorString
# https://github.com/pytorch/pytorch/issues/32083 # https://github.com/pytorch/pytorch/issues/32083
patch('cusparseGetErrorString.patch', when='@0.4.1:1.0^cuda@10.1.243:') patch("cusparseGetErrorString.patch", when="@0.4.1:1.0^cuda@10.1.243:")
# Fixes 'FindOpenMP.cmake' # Fixes 'FindOpenMP.cmake'
# to detect openmp settings used by Fujitsu compiler. # to detect openmp settings used by Fujitsu compiler.
patch('detect_omp_of_fujitsu_compiler.patch', when='%fj') patch("detect_omp_of_fujitsu_compiler.patch", when="%fj")
# Fix compilation of +distributed~tensorpipe # Fix compilation of +distributed~tensorpipe
# https://github.com/pytorch/pytorch/issues/68002 # https://github.com/pytorch/pytorch/issues/68002
patch('https://github.com/pytorch/pytorch/commit/c075f0f633fa0136e68f0a455b5b74d7b500865c.patch', patch(
sha256='e69e41b5c171bfb00d1b5d4ee55dd5e4c8975483230274af4ab461acd37e40b8', when='@1.10.0+distributed~tensorpipe') "https://github.com/pytorch/pytorch/commit/c075f0f633fa0136e68f0a455b5b74d7b500865c.patch",
sha256="e69e41b5c171bfb00d1b5d4ee55dd5e4c8975483230274af4ab461acd37e40b8",
when="@1.10.0+distributed~tensorpipe",
)
# Both build and install run cmake/make/make install # Both build and install run cmake/make/make install
# Only run once to speed up build times # Only run once to speed up build times
phases = ['install'] phases = ["install"]
@property @property
def libs(self): def libs(self):
root = join_path(self.prefix, self.spec['python'].package.site_packages_dir, root = join_path(
'torch', 'lib') self.prefix, self.spec["python"].package.site_packages_dir, "torch", "lib"
return find_libraries('libtorch', root) )
return find_libraries("libtorch", root)
@property @property
def headers(self): def headers(self):
root = join_path(self.prefix, self.spec['python'].package.site_packages_dir, root = join_path(
'torch', 'include') self.prefix, self.spec["python"].package.site_packages_dir, "torch", "include"
)
headers = find_all_headers(root) headers = find_all_headers(root)
headers.directories = [root] headers.directories = [root]
return headers return headers
@when('@1.5.0:') @when("@1.5.0:")
def patch(self): def patch(self):
# https://github.com/pytorch/pytorch/issues/52208 # https://github.com/pytorch/pytorch/issues/52208
filter_file('torch_global_deps PROPERTIES LINKER_LANGUAGE C', filter_file(
'torch_global_deps PROPERTIES LINKER_LANGUAGE CXX', "torch_global_deps PROPERTIES LINKER_LANGUAGE C",
'caffe2/CMakeLists.txt') "torch_global_deps PROPERTIES LINKER_LANGUAGE CXX",
"caffe2/CMakeLists.txt",
)
def setup_build_environment(self, env): def setup_build_environment(self, env):
"""Set environment variables used to control the build. """Set environment variables used to control the build.
@@ -269,7 +295,8 @@ class PyTorch(PythonPackage, CudaPackage):
most flags defined in ``CMakeLists.txt`` can be specified as most flags defined in ``CMakeLists.txt`` can be specified as
environment variables. environment variables.
""" """
def enable_or_disable(variant, keyword='USE', var=None, newer=False):
def enable_or_disable(variant, keyword="USE", var=None, newer=False):
"""Set environment variable to enable or disable support for a """Set environment variable to enable or disable support for a
particular variant. particular variant.
@@ -284,137 +311,135 @@ class PyTorch(PythonPackage, CudaPackage):
# Version 1.1.0 switched from NO_* to USE_* or BUILD_* # Version 1.1.0 switched from NO_* to USE_* or BUILD_*
# But some newer variants have always used USE_* or BUILD_* # But some newer variants have always used USE_* or BUILD_*
if self.spec.satisfies('@1.1:') or newer: if self.spec.satisfies("@1.1:") or newer:
if '+' + variant in self.spec: if "+" + variant in self.spec:
env.set(keyword + '_' + var, 'ON') env.set(keyword + "_" + var, "ON")
else: else:
env.set(keyword + '_' + var, 'OFF') env.set(keyword + "_" + var, "OFF")
else: else:
if '+' + variant in self.spec: if "+" + variant in self.spec:
env.unset('NO_' + var) env.unset("NO_" + var)
else: else:
env.set('NO_' + var, 'ON') env.set("NO_" + var, "ON")
# Build in parallel to speed up build times # Build in parallel to speed up build times
env.set('MAX_JOBS', make_jobs) env.set("MAX_JOBS", make_jobs)
# Spack logs have trouble handling colored output # Spack logs have trouble handling colored output
env.set('COLORIZE_OUTPUT', 'OFF') env.set("COLORIZE_OUTPUT", "OFF")
if self.spec.satisfies('@0.4:'): if self.spec.satisfies("@0.4:"):
enable_or_disable('test', keyword='BUILD') enable_or_disable("test", keyword="BUILD")
if self.spec.satisfies('@1.7:'): if self.spec.satisfies("@1.7:"):
enable_or_disable('caffe2', keyword='BUILD') enable_or_disable("caffe2", keyword="BUILD")
enable_or_disable('cuda') enable_or_disable("cuda")
if '+cuda' in self.spec: if "+cuda" in self.spec:
# cmake/public/cuda.cmake # cmake/public/cuda.cmake
# cmake/Modules_CUDA_fix/upstream/FindCUDA.cmake # cmake/Modules_CUDA_fix/upstream/FindCUDA.cmake
env.unset('CUDA_ROOT') env.unset("CUDA_ROOT")
torch_cuda_arch = ';'.join('{0:.1f}'.format(float(i) / 10.0) for i torch_cuda_arch = ";".join(
in "{0:.1f}".format(float(i) / 10.0) for i in self.spec.variants["cuda_arch"].value
self.spec.variants['cuda_arch'].value) )
env.set('TORCH_CUDA_ARCH_LIST', torch_cuda_arch) env.set("TORCH_CUDA_ARCH_LIST", torch_cuda_arch)
enable_or_disable('rocm') enable_or_disable("rocm")
enable_or_disable('cudnn') enable_or_disable("cudnn")
if '+cudnn' in self.spec: if "+cudnn" in self.spec:
# cmake/Modules_CUDA_fix/FindCUDNN.cmake # cmake/Modules_CUDA_fix/FindCUDNN.cmake
env.set('CUDNN_INCLUDE_DIR', self.spec['cudnn'].prefix.include) env.set("CUDNN_INCLUDE_DIR", self.spec["cudnn"].prefix.include)
env.set('CUDNN_LIBRARY', self.spec['cudnn'].libs[0]) env.set("CUDNN_LIBRARY", self.spec["cudnn"].libs[0])
enable_or_disable('fbgemm') enable_or_disable("fbgemm")
if self.spec.satisfies('@1.8:'): if self.spec.satisfies("@1.8:"):
enable_or_disable('kineto') enable_or_disable("kineto")
enable_or_disable('magma') enable_or_disable("magma")
enable_or_disable('metal') enable_or_disable("metal")
if self.spec.satisfies('@1.10:'): if self.spec.satisfies("@1.10:"):
enable_or_disable('breakpad') enable_or_disable("breakpad")
enable_or_disable('nccl') enable_or_disable("nccl")
if '+nccl' in self.spec: if "+nccl" in self.spec:
env.set('NCCL_LIB_DIR', self.spec['nccl'].libs.directories[0]) env.set("NCCL_LIB_DIR", self.spec["nccl"].libs.directories[0])
env.set('NCCL_INCLUDE_DIR', self.spec['nccl'].prefix.include) env.set("NCCL_INCLUDE_DIR", self.spec["nccl"].prefix.include)
# cmake/External/nnpack.cmake # cmake/External/nnpack.cmake
enable_or_disable('nnpack') enable_or_disable("nnpack")
enable_or_disable('numa') enable_or_disable("numa")
if '+numa' in self.spec: if "+numa" in self.spec:
# cmake/Modules/FindNuma.cmake # cmake/Modules/FindNuma.cmake
env.set('NUMA_ROOT_DIR', self.spec['numactl'].prefix) env.set("NUMA_ROOT_DIR", self.spec["numactl"].prefix)
# cmake/Modules/FindNumPy.cmake # cmake/Modules/FindNumPy.cmake
enable_or_disable('numpy') enable_or_disable("numpy")
# cmake/Modules/FindOpenMP.cmake # cmake/Modules/FindOpenMP.cmake
enable_or_disable('openmp', newer=True) enable_or_disable("openmp", newer=True)
enable_or_disable('qnnpack') enable_or_disable("qnnpack")
if self.spec.satisfies('@1.3:'): if self.spec.satisfies("@1.3:"):
enable_or_disable('qnnpack', var='PYTORCH_QNNPACK') enable_or_disable("qnnpack", var="PYTORCH_QNNPACK")
if self.spec.satisfies('@1.8:'): if self.spec.satisfies("@1.8:"):
enable_or_disable('valgrind') enable_or_disable("valgrind")
if self.spec.satisfies('@1.5:'): if self.spec.satisfies("@1.5:"):
enable_or_disable('xnnpack') enable_or_disable("xnnpack")
enable_or_disable('mkldnn') enable_or_disable("mkldnn")
enable_or_disable('distributed') enable_or_disable("distributed")
enable_or_disable('mpi') enable_or_disable("mpi")
# cmake/Modules/FindGloo.cmake # cmake/Modules/FindGloo.cmake
enable_or_disable('gloo', newer=True) enable_or_disable("gloo", newer=True)
if self.spec.satisfies('@1.6:'): if self.spec.satisfies("@1.6:"):
enable_or_disable('tensorpipe') enable_or_disable("tensorpipe")
if '+onnx_ml' in self.spec: if "+onnx_ml" in self.spec:
env.set('ONNX_ML', 'ON') env.set("ONNX_ML", "ON")
else: else:
env.set('ONNX_ML', 'OFF') env.set("ONNX_ML", "OFF")
if not self.spec.satisfies('@master'): if not self.spec.satisfies("@master"):
env.set('PYTORCH_BUILD_VERSION', self.version) env.set("PYTORCH_BUILD_VERSION", self.version)
env.set('PYTORCH_BUILD_NUMBER', 0) env.set("PYTORCH_BUILD_NUMBER", 0)
# BLAS to be used by Caffe2 # BLAS to be used by Caffe2
# Options defined in cmake/Dependencies.cmake and cmake/Modules/FindBLAS.cmake # Options defined in cmake/Dependencies.cmake and cmake/Modules/FindBLAS.cmake
if self.spec['blas'].name == 'atlas': if self.spec["blas"].name == "atlas":
env.set('BLAS', 'ATLAS') env.set("BLAS", "ATLAS")
env.set('WITH_BLAS', 'atlas') env.set("WITH_BLAS", "atlas")
elif self.spec['blas'].name in ['blis', 'amdblis']: elif self.spec["blas"].name in ["blis", "amdblis"]:
env.set('BLAS', 'BLIS') env.set("BLAS", "BLIS")
env.set('WITH_BLAS', 'blis') env.set("WITH_BLAS", "blis")
elif self.spec['blas'].name == 'eigen': elif self.spec["blas"].name == "eigen":
env.set('BLAS', 'Eigen') env.set("BLAS", "Eigen")
elif self.spec['lapack'].name in ['libflame', 'amdlibflame']: elif self.spec["lapack"].name in ["libflame", "amdlibflame"]:
env.set('BLAS', 'FLAME') env.set("BLAS", "FLAME")
env.set('WITH_BLAS', 'FLAME') env.set("WITH_BLAS", "FLAME")
elif self.spec['blas'].name in [ elif self.spec["blas"].name in ["intel-mkl", "intel-parallel-studio", "intel-oneapi-mkl"]:
'intel-mkl', 'intel-parallel-studio', 'intel-oneapi-mkl']: env.set("BLAS", "MKL")
env.set('BLAS', 'MKL') env.set("WITH_BLAS", "mkl")
env.set('WITH_BLAS', 'mkl') elif self.spec["blas"].name == "openblas":
elif self.spec['blas'].name == 'openblas': env.set("BLAS", "OpenBLAS")
env.set('BLAS', 'OpenBLAS') env.set("WITH_BLAS", "open")
env.set('WITH_BLAS', 'open') elif self.spec["blas"].name == "veclibfort":
elif self.spec['blas'].name == 'veclibfort': env.set("BLAS", "vecLib")
env.set('BLAS', 'vecLib') env.set("WITH_BLAS", "veclib")
env.set('WITH_BLAS', 'veclib')
else: else:
env.set('BLAS', 'Generic') env.set("BLAS", "Generic")
env.set('WITH_BLAS', 'generic') env.set("WITH_BLAS", "generic")
# Don't use vendored third-party libraries when possible # Don't use vendored third-party libraries when possible
env.set('BUILD_CUSTOM_PROTOBUF', 'OFF') env.set("BUILD_CUSTOM_PROTOBUF", "OFF")
env.set('USE_SYSTEM_NCCL', 'ON') env.set("USE_SYSTEM_NCCL", "ON")
env.set('USE_SYSTEM_EIGEN_INSTALL', 'ON') env.set("USE_SYSTEM_EIGEN_INSTALL", "ON")
if self.spec.satisfies('@0.4:'): if self.spec.satisfies("@0.4:"):
env.set('pybind11_DIR', self.spec['py-pybind11'].prefix) env.set("pybind11_DIR", self.spec["py-pybind11"].prefix)
env.set('pybind11_INCLUDE_DIR', env.set("pybind11_INCLUDE_DIR", self.spec["py-pybind11"].prefix.include)
self.spec['py-pybind11'].prefix.include) if self.spec.satisfies("@1.10:"):
if self.spec.satisfies('@1.10:'): env.set("USE_SYSTEM_PYBIND11", "ON")
env.set('USE_SYSTEM_PYBIND11', 'ON')
# https://github.com/pytorch/pytorch/issues/60334 # https://github.com/pytorch/pytorch/issues/60334
# if self.spec.satisfies('@1.8:'): # if self.spec.satisfies('@1.8:'):
# env.set('USE_SYSTEM_SLEEF', 'ON') # env.set('USE_SYSTEM_SLEEF', 'ON')
if self.spec.satisfies('@1.6:'): if self.spec.satisfies("@1.6:"):
# env.set('USE_SYSTEM_LIBS', 'ON') # env.set('USE_SYSTEM_LIBS', 'ON')
# https://github.com/pytorch/pytorch/issues/60329 # https://github.com/pytorch/pytorch/issues/60329
# env.set('USE_SYSTEM_CPUINFO', 'ON') # env.set('USE_SYSTEM_CPUINFO', 'ON')
@@ -422,27 +447,26 @@ class PyTorch(PythonPackage, CudaPackage):
# env.set('USE_SYSTEM_GLOO', 'ON') # env.set('USE_SYSTEM_GLOO', 'ON')
# https://github.com/Maratyszcza/FP16/issues/18 # https://github.com/Maratyszcza/FP16/issues/18
# env.set('USE_SYSTEM_FP16', 'ON') # env.set('USE_SYSTEM_FP16', 'ON')
env.set('USE_SYSTEM_PTHREADPOOL', 'ON') env.set("USE_SYSTEM_PTHREADPOOL", "ON")
env.set('USE_SYSTEM_PSIMD', 'ON') env.set("USE_SYSTEM_PSIMD", "ON")
env.set('USE_SYSTEM_FXDIV', 'ON') env.set("USE_SYSTEM_FXDIV", "ON")
env.set('USE_SYSTEM_BENCHMARK', 'ON') env.set("USE_SYSTEM_BENCHMARK", "ON")
# https://github.com/pytorch/pytorch/issues/60331 # https://github.com/pytorch/pytorch/issues/60331
# env.set('USE_SYSTEM_ONNX', 'ON') # env.set('USE_SYSTEM_ONNX', 'ON')
# https://github.com/pytorch/pytorch/issues/60332 # https://github.com/pytorch/pytorch/issues/60332
# env.set('USE_SYSTEM_XNNPACK', 'ON') # env.set('USE_SYSTEM_XNNPACK', 'ON')
@run_before('install') @run_before("install")
def build_amd(self): def build_amd(self):
if '+rocm' in self.spec: if "+rocm" in self.spec:
python(os.path.join('tools', 'amd_build', 'build_amd.py')) python(os.path.join("tools", "amd_build", "build_amd.py"))
@run_after('install') @run_after("install")
@on_package_attributes(run_tests=True) @on_package_attributes(run_tests=True)
def install_test(self): def install_test(self):
with working_dir('test'): with working_dir("test"):
python('run_test.py') python("run_test.py")
# Tests need to be re-added since `phases` was overridden # Tests need to be re-added since `phases` was overridden
run_after('install')( run_after("install")(PythonPackage._run_default_install_time_test_callbacks)
PythonPackage._run_default_install_time_test_callbacks) run_after("install")(PythonPackage.sanity_check_prefix)
run_after('install')(PythonPackage.sanity_check_prefix)

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,7 @@
import spack.repo import spack.repo
import spack.spec import spack.spec
import spack.store import spack.store
import spack.version as vn
from spack.schema.database_index import schema from spack.schema.database_index import schema
from spack.util.executable import Executable from spack.util.executable import Executable
@@ -1051,3 +1052,16 @@ def test_query_installed_when_package_unknown(database, tmpdir):
assert not s.installed_upstream assert not s.installed_upstream
with pytest.raises(spack.repo.UnknownNamespaceError): with pytest.raises(spack.repo.UnknownNamespaceError):
s.package s.package
def test_error_message_when_using_too_new_db(database, monkeypatch):
"""Sometimes the database format needs to be bumped. When that happens, we have forward
incompatibilities that need to be reported in a clear way to the user, in case we moved
back to an older version of Spack. This test ensures that the error message for a too
new database version stays comprehensible across refactoring of the database code.
"""
monkeypatch.setattr(spack.database, "_db_version", vn.Version("0"))
with pytest.raises(
spack.database.InvalidDatabaseVersionError, match="you need a newer Spack version"
):
spack.database.Database(database.root)._read()

Some files were not shown because too many files have changed in this diff Show More