From 834ed2f1172a120b5d1008293b0d40df8c3459a8 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Tue, 15 Oct 2024 15:52:31 +0200 Subject: [PATCH 01/28] env depfile: generate Makefile with absolute script path (#46966) Co-authored-by: Harmen Stoppels --- lib/spack/spack/environment/depfile.py | 3 +++ lib/spack/spack/test/cmd/env.py | 20 +++++++++++++++----- share/spack/templates/depfile/Makefile | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/spack/spack/environment/depfile.py b/lib/spack/spack/environment/depfile.py index 06dc8f157d05ec..38d673192be591 100644 --- a/lib/spack/spack/environment/depfile.py +++ b/lib/spack/spack/environment/depfile.py @@ -9,11 +9,13 @@ import os import re +import shlex from enum import Enum from typing import List, Optional import spack.deptypes as dt import spack.environment.environment as ev +import spack.paths import spack.spec import spack.traverse as traverse @@ -226,6 +228,7 @@ def to_dict(self): "install_deps_target": self._target("install-deps"), "any_hash_target": self._target("%"), "jobserver_support": self.jobserver_support, + "spack_script": shlex.quote(spack.paths.spack_script), "adjacency_list": self.make_adjacency_list, "phony_convenience_targets": " ".join(self.phony_convenience_targets), "pkg_ids_variable": self.pkg_identifier_variable, diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index 70e2c56e412603..d1d35e6f5e0cb4 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -3953,7 +3953,7 @@ def test_environment_depfile_makefile(depfile_flags, expected_installs, tmpdir, ) # Do make dry run. - out = make("-n", "-f", makefile, output=str) + out = make("-n", "-f", makefile, "SPACK=spack", output=str) specs_that_make_would_install = _parse_dry_run_package_installs(out) @@ -3991,7 +3991,7 @@ def test_depfile_works_with_gitversions(tmpdir, mock_packages, monkeypatch): env("depfile", "-o", makefile, "--make-disable-jobserver", "--make-prefix=prefix") # Do a dry run on the generated depfile - out = make("-n", "-f", makefile, output=str) + out = make("-n", "-f", makefile, "SPACK=spack", output=str) # Check that all specs are there (without duplicates) specs_that_make_would_install = _parse_dry_run_package_installs(out) @@ -4053,7 +4053,12 @@ def test_depfile_phony_convenience_targets( # Phony install/* target should install picked package and all its deps specs_that_make_would_install = _parse_dry_run_package_installs( - make("-n", picked_spec.format("install/{name}-{version}-{hash}"), output=str) + make( + "-n", + picked_spec.format("install/{name}-{version}-{hash}"), + "SPACK=spack", + output=str, + ) ) assert set(specs_that_make_would_install) == set(expected_installs) @@ -4061,7 +4066,12 @@ def test_depfile_phony_convenience_targets( # Phony install-deps/* target shouldn't install picked package specs_that_make_would_install = _parse_dry_run_package_installs( - make("-n", picked_spec.format("install-deps/{name}-{version}-{hash}"), output=str) + make( + "-n", + picked_spec.format("install-deps/{name}-{version}-{hash}"), + "SPACK=spack", + output=str, + ) ) assert set(specs_that_make_would_install) == set(expected_installs) - {picked_package} @@ -4121,7 +4131,7 @@ def test_spack_package_ids_variable(tmpdir, mock_packages): make = Executable("make") # Do dry run. - out = make("-n", "-C", str(tmpdir), output=str) + out = make("-n", "-C", str(tmpdir), "SPACK=spack", output=str) # post-install: should've been executed with ev.read("test") as test: diff --git a/share/spack/templates/depfile/Makefile b/share/spack/templates/depfile/Makefile index 4b764752678c0f..cd9df1491c7eb3 100644 --- a/share/spack/templates/depfile/Makefile +++ b/share/spack/templates/depfile/Makefile @@ -1,4 +1,4 @@ -SPACK ?= spack -c config:install_status:false +SPACK ?= {{ spack_script }} -c config:install_status:false SPACK_INSTALL_FLAGS ?= # This variable can be used to add post install hooks From 237f886e5d06a1ffae95720ed140528db0b3986e Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Tue, 15 Oct 2024 16:50:00 +0200 Subject: [PATCH 02/28] `gimp`: Fix missing pkgconfig and gettext dependencies (#46912) * gimp deps: Fix missing pkgconfig and gettext deps * Let's mark @:2.10.32 as deprecated and remove after 0.23 is released. --- .../repos/builtin/packages/babl/package.py | 6 ++-- .../repos/builtin/packages/gimp/package.py | 31 ++++++++++++++----- .../packages/glib-networking/package.py | 3 +- .../gsettings-desktop-schemas/package.py | 1 + .../repos/builtin/packages/libjxl/package.py | 1 + .../builtin/packages/libmypaint/package.py | 4 ++- 6 files changed, 35 insertions(+), 11 deletions(-) diff --git a/var/spack/repos/builtin/packages/babl/package.py b/var/spack/repos/builtin/packages/babl/package.py index d100f204d4a385..f4ce9d3be4105e 100644 --- a/var/spack/repos/builtin/packages/babl/package.py +++ b/var/spack/repos/builtin/packages/babl/package.py @@ -15,12 +15,13 @@ class Babl(MesonPackage): component permutations.""" homepage = "https://gegl.org/babl" - url = "https://download.gimp.org/babl/0.1/babl-0.1.98.tar.xz" + url = "https://download.gimp.org/babl/0.1/babl-0.1.108.tar.xz" maintainers("benkirk") license("LGPL-3.0-or-later") + version("0.1.108", sha256="26defe9deaab7ac4d0e076cab49c2a0d6ebd0df0c31fd209925a5f07edee1475") version("0.1.106", sha256="d325135d3304f088c134cc620013acf035de2e5d125a50a2d91054e7377c415f") version("0.1.102", sha256="a88bb28506575f95158c8c89df6e23686e50c8b9fea412bf49fe8b80002d84f0") version("0.1.98", sha256="f3b222f84e462735de63fa9c3651942f2b78fd314c73a22e05ff7c73afd23af1") @@ -29,9 +30,10 @@ class Babl(MesonPackage): version("0.1.92", sha256="f667735028944b6375ad18f160a64ceb93f5c7dccaa9d8751de359777488a2c1") version("0.1.90", sha256="6e2ebb636f37581588e3d02499b3d2f69f9ac73e34a262f42911d7f5906a9243") - depends_on("c", type="build") # generated + depends_on("c", type="build") depends_on("cmake@3.4:", type="build") + depends_on("pkgconfig", type="build") depends_on("lcms") depends_on("gobject-introspection") diff --git a/var/spack/repos/builtin/packages/gimp/package.py b/var/spack/repos/builtin/packages/gimp/package.py index 5634be93063352..8519d2a71c12ba 100644 --- a/var/spack/repos/builtin/packages/gimp/package.py +++ b/var/spack/repos/builtin/packages/gimp/package.py @@ -26,14 +26,25 @@ class Gimp(AutotoolsPackage): license("GPL-3.0-or-later") version("2.10.38", sha256="50a845eec11c8831fe8661707950f5b8446e35f30edfb9acf98f85c1133f856e") - version("2.10.32", sha256="3f15c70554af5dcc1b46e6dc68f3d8f0a6cc9fe56b6d78ac08c0fd859ab89a25") - version("2.10.30", sha256="88815daa76ed7d4277eeb353358bafa116cd2fcd2c861d95b95135c1d52b67dc") - version("2.10.28", sha256="4f4dc22cff1ab5f026feaa2ab55e05775b3a11e198186b47bdab79cbfa078826") - version("2.10.26", sha256="5ddbccf1db462a41df9a26197fcb0d24c7152753a36b3c8b8a9506b4136395f7") - version("2.10.24", sha256="bd1bb762368c0dd3175cf05006812dd676949c3707e21f4e6857435cb435989e") + with default_args(deprecated=True): + version( + "2.10.32", sha256="3f15c70554af5dcc1b46e6dc68f3d8f0a6cc9fe56b6d78ac08c0fd859ab89a25" + ) + version( + "2.10.30", sha256="88815daa76ed7d4277eeb353358bafa116cd2fcd2c861d95b95135c1d52b67dc" + ) + version( + "2.10.28", sha256="4f4dc22cff1ab5f026feaa2ab55e05775b3a11e198186b47bdab79cbfa078826" + ) + version( + "2.10.26", sha256="5ddbccf1db462a41df9a26197fcb0d24c7152753a36b3c8b8a9506b4136395f7" + ) + version( + "2.10.24", sha256="bd1bb762368c0dd3175cf05006812dd676949c3707e21f4e6857435cb435989e" + ) - depends_on("c", type="build") # generated - depends_on("cxx", type="build") # generated + depends_on("c", type="build") + depends_on("cxx", type="build") variant("doc", default=True, description="Build documentation with gtk-doc") variant("ghostscript", default=True, description="Build with ghostscript support") @@ -56,6 +67,7 @@ class Gimp(AutotoolsPackage): # variant("python", default=False, description="Build with Python bindings") # ref. https://www.gimp.org/source/ + depends_on("gettext", type="build") depends_on("pkgconfig", type="build") depends_on("babl") depends_on("fontconfig@2.12.4:") @@ -71,6 +83,7 @@ class Gimp(AutotoolsPackage): depends_on("libexif") # depends_on("libheif+libde265", when="+libheif") depends_on("libjxl", when="+jpegxl") + depends_on("libjxl@:0.7", when="+jpegxl@:2.10.32") depends_on("libmng", when="+libmng") depends_on("libmypaint@1.4") depends_on("libpng") @@ -94,6 +107,10 @@ def url_for_version(self, version): url = "https://download.gimp.org/gimp/v{0}/gimp-{1}.tar.bz2" return url.format(version.up_to(2), version) + @when("@:2.10.32") + def patch(self): + filter_file("babl ", "babl-0.1 ", "configure") + def configure_args(self): args = [ "--disable-python", diff --git a/var/spack/repos/builtin/packages/glib-networking/package.py b/var/spack/repos/builtin/packages/glib-networking/package.py index 0d08df0c3b5bf4..d44f39fd5eb80d 100644 --- a/var/spack/repos/builtin/packages/glib-networking/package.py +++ b/var/spack/repos/builtin/packages/glib-networking/package.py @@ -18,9 +18,10 @@ class GlibNetworking(MesonPackage): version("2.65.90", sha256="91b35c5d7472d10229b0b01c0631ac171903e96f84a6fb22c4126a40528c09e2") version("2.65.1", sha256="d06311004f7dda4561c210f286a3678b631fb7187cb3b90616c5ba39307cc91f") - depends_on("c", type="build") # generated + depends_on("c", type="build") depends_on("gettext", type="build") + depends_on("pkgconfig", type="build") depends_on("glib") depends_on("gnutls") depends_on("gsettings-desktop-schemas") diff --git a/var/spack/repos/builtin/packages/gsettings-desktop-schemas/package.py b/var/spack/repos/builtin/packages/gsettings-desktop-schemas/package.py index 53844022699f83..29b6288ecc8246 100644 --- a/var/spack/repos/builtin/packages/gsettings-desktop-schemas/package.py +++ b/var/spack/repos/builtin/packages/gsettings-desktop-schemas/package.py @@ -24,6 +24,7 @@ class GsettingsDesktopSchemas(MesonPackage): depends_on("glib") depends_on("gobject-introspection", type="build") depends_on("gettext", type="build") + depends_on("pkgconfig", type="build") def setup_dependent_build_environment(self, env, dependent_spec): env.prepend_path("XDG_DATA_DIRS", self.prefix.share) diff --git a/var/spack/repos/builtin/packages/libjxl/package.py b/var/spack/repos/builtin/packages/libjxl/package.py index 68fd6d65d0dabe..5117fc3c92b73a 100644 --- a/var/spack/repos/builtin/packages/libjxl/package.py +++ b/var/spack/repos/builtin/packages/libjxl/package.py @@ -30,6 +30,7 @@ class Libjxl(CMakePackage): depends_on("cxx", type="build") # generated depends_on("cmake@3.10:", type="build") + depends_on("pkgconfig", type="build") depends_on("brotli") depends_on("highway") diff --git a/var/spack/repos/builtin/packages/libmypaint/package.py b/var/spack/repos/builtin/packages/libmypaint/package.py index 4ae0a1fb6c5bf6..2726201553fa6f 100644 --- a/var/spack/repos/builtin/packages/libmypaint/package.py +++ b/var/spack/repos/builtin/packages/libmypaint/package.py @@ -24,7 +24,9 @@ class Libmypaint(AutotoolsPackage): version("1.4.0", sha256="59d13b14c6aca0497095f29ee7228ca2499a923ba8e1dd718a2f2ecb45a9cbff") version("1.3.0", sha256="6a07d9d57fea60f68d218a953ce91b168975a003db24de6ac01ad69dcc94a671") - depends_on("c", type="build") # generated + depends_on("c", type="build") + depends_on("gettext", type="build") + depends_on("pkgconfig", type="build") variant("gegl", default=False, description="Enable GEGL based code in build") variant("introspection", default=True, description="Enable introspection for this build") From 1d76ed7aa4acebcd4201d84523143cae9e65f29e Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 15 Oct 2024 10:16:14 -0500 Subject: [PATCH 03/28] py-jupyter-server: add v2.14.2 (fix CVEs) (#46965) * py-jupyter-server: add v2.14.2 * [@spackbot] updating style on behalf of wdconinc * py-jupyter-events: add v0.10.0 * py-send2trash: add v1.8.3 * py-websocket-client: add v1.6.4, v1.7.0, v1.8.0 * py-websocket-client: back to underscore in source tarball --------- Co-authored-by: wdconinc --- .../packages/py-jupyter-events/package.py | 3 ++ .../packages/py-jupyter-server/package.py | 41 +++++++++++++++---- .../builtin/packages/py-send2trash/package.py | 1 + .../packages/py-websocket-client/package.py | 5 ++- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/var/spack/repos/builtin/packages/py-jupyter-events/package.py b/var/spack/repos/builtin/packages/py-jupyter-events/package.py index e87818492b324d..f1bd940b9d79fb 100644 --- a/var/spack/repos/builtin/packages/py-jupyter-events/package.py +++ b/var/spack/repos/builtin/packages/py-jupyter-events/package.py @@ -12,10 +12,13 @@ class PyJupyterEvents(PythonPackage): homepage = "https://github.com/jupyter/jupyter_events" pypi = "jupyter_events/jupyter_events-0.6.3.tar.gz" + version("0.10.0", sha256="670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22") version("0.6.3", sha256="9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3") depends_on("py-hatchling@1.5:", type="build") + depends_on("py-referencing", type=("build", "run"), when="@0.7:") + depends_on("py-jsonschema+format-nongpl@4.18:", type=("build", "run"), when="@0.7:") depends_on("py-jsonschema+format-nongpl@3.2:", type=("build", "run")) depends_on("py-python-json-logger@2.0.4:", type=("build", "run")) depends_on("py-pyyaml@5.3:", type=("build", "run")) diff --git a/var/spack/repos/builtin/packages/py-jupyter-server/package.py b/var/spack/repos/builtin/packages/py-jupyter-server/package.py index 669ef586d1e291..c8a4c422e19565 100644 --- a/var/spack/repos/builtin/packages/py-jupyter-server/package.py +++ b/var/spack/repos/builtin/packages/py-jupyter-server/package.py @@ -16,17 +16,32 @@ class PyJupyterServer(PythonPackage): license("BSD-3-Clause") + version("2.14.2", sha256="66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b") version("2.6.0", sha256="ae4af349f030ed08dd78cb7ac1a03a92d886000380c9ea6283f3c542a81f4b06") version("1.21.0", sha256="d0adca19913a3763359be7f0b8c2ea8bfde356f4b8edd8e3149d7d0fbfaa248b") version("1.18.1", sha256="2b72fc595bccae292260aad8157a0ead8da2c703ec6ae1bb7b36dbad0e267ea7") - version("1.17.0", sha256="7b3aa524790ab0da64f06dfe0b2af149d0a3f59aad71fdedcf1d8bae6508018c") - version("1.13.5", sha256="9e3e9717eea3bffab8cfb2ff330011be6c8bbd9cdae5b71cef169fcece2f19d3") - version("1.11.2", sha256="c1f32e0c1807ab2de37bf70af97a36b4436db0bc8af3124632b1f4441038bf95") - version("1.11.1", sha256="ab7ab1cc38512f15026cbcbb96300fb46ec8b24aa162263d9edd00e0a749b1e8") - version("1.11.0", sha256="8ab4f484a4a2698f757cff0769d27b5d991e0232a666d54f4d6ada4e6a61330b") - version("1.10.2", sha256="d3a3b68ebc6d7bfee1097f1712cf7709ee39c92379da2cc08724515bb85e72bf") - version("1.9.0", sha256="7d19006380f6217458a9db309b54e3dab87ced6c06329c61823907bef2a6f51b") - version("1.6.1", sha256="242ddd0b644f10e030f917019b47c381e0f2d2b950164af45cbd791d572198ac") + with default_args(deprecated=True): + # https://nvd.nist.gov/vuln/detail/CVE-2022-29241 + version( + "1.17.0", sha256="7b3aa524790ab0da64f06dfe0b2af149d0a3f59aad71fdedcf1d8bae6508018c" + ) + version( + "1.13.5", sha256="9e3e9717eea3bffab8cfb2ff330011be6c8bbd9cdae5b71cef169fcece2f19d3" + ) + version( + "1.11.2", sha256="c1f32e0c1807ab2de37bf70af97a36b4436db0bc8af3124632b1f4441038bf95" + ) + version( + "1.11.1", sha256="ab7ab1cc38512f15026cbcbb96300fb46ec8b24aa162263d9edd00e0a749b1e8" + ) + version( + "1.11.0", sha256="8ab4f484a4a2698f757cff0769d27b5d991e0232a666d54f4d6ada4e6a61330b" + ) + version( + "1.10.2", sha256="d3a3b68ebc6d7bfee1097f1712cf7709ee39c92379da2cc08724515bb85e72bf" + ) + version("1.9.0", sha256="7d19006380f6217458a9db309b54e3dab87ced6c06329c61823907bef2a6f51b") + version("1.6.1", sha256="242ddd0b644f10e030f917019b47c381e0f2d2b950164af45cbd791d572198ac") variant("typescript", default=False, description="Build the typescript code", when="@1.10.2:1") @@ -46,7 +61,9 @@ class PyJupyterServer(PythonPackage): depends_on("npm", type="build", when="+typescript") depends_on("py-anyio@3.1.0:", when="@2.2.1:", type=("build", "run")) depends_on("py-anyio@3.1.0:3", when="@:2.2.0", type=("build", "run")) + depends_on("py-argon2-cffi@21.1:", when="@2.14:", type=("build", "run")) depends_on("py-argon2-cffi", type=("build", "run")) + depends_on("py-jinja2@3.0.3:", when="@2.14:", type=("build", "run")) depends_on("py-jinja2", type=("build", "run")) depends_on("py-jupyter-client@7.4.4:", when="@2:", type=("build", "run")) depends_on("py-jupyter-client@6.1.12:", when="@1.16:", type=("build", "run")) @@ -54,18 +71,23 @@ class PyJupyterServer(PythonPackage): depends_on("py-jupyter-core@4.12:4,5.1:", when="@1.23.5:", type=("build", "run")) depends_on("py-jupyter-core@4.7:", when="@1.16:", type=("build", "run")) depends_on("py-jupyter-core@4.6:", type=("build", "run")) + depends_on("py-jupyter-server-terminals@0.4.4:", when="@2.14:", type=("build", "run")) depends_on("py-jupyter-server-terminals", when="@2:", type=("build", "run")) depends_on("py-nbconvert@6.4.4:", when="@1.16:", type=("build", "run")) depends_on("py-nbconvert", type=("build", "run")) depends_on("py-nbformat@5.3:", when="@2:", type=("build", "run")) depends_on("py-nbformat@5.2:", when="@1.15:", type=("build", "run")) depends_on("py-nbformat", type=("build", "run")) + depends_on("py-packaging@22.0:", when="@2.14:", type=("build", "run")) depends_on("py-packaging", when="@1.13.2:", type=("build", "run")) + depends_on("py-prometheus-client@0.9:", when="@2.14:", type=("build", "run")) depends_on("py-prometheus-client", type=("build", "run")) + # for windows depends_on pywinpty@2.0.1:, when='@2.14:' # for windows depends_on pywinpty, when='@1.13.2:' # py-pywinpty is not in spack and requires the build system maturin depends_on("py-pyzmq@24:", when="@2:", type=("build", "run")) depends_on("py-pyzmq@17:", type=("build", "run")) + depends_on("py-send2trash@1.8.2:", when="@2.7.1:", type=("build", "run")) depends_on("py-send2trash", type=("build", "run")) depends_on("py-terminado@0.8.3:", type=("build", "run")) depends_on("py-tornado@6.2:", when="@2:", type=("build", "run")) @@ -74,8 +96,11 @@ class PyJupyterServer(PythonPackage): depends_on("py-traitlets@5.1:", when="@1.16:", type=("build", "run")) depends_on("py-traitlets@5:", when="@1.13.3:", type=("build", "run")) depends_on("py-traitlets@4.2.1:", type=("build", "run")) + depends_on("py-websocket-client@1.7:", when="@2.14:", type=("build", "run")) depends_on("py-websocket-client", type=("build", "run")) + depends_on("py-jupyter-events@0.9:", when="@2.10.1:", type=("build", "run")) depends_on("py-jupyter-events@0.6:", when="@2.6:", type=("build", "run")) + depends_on("py-overrides@5.0:", when="@2.14:", type=("build", "run")) depends_on("py-overrides", when="@2.6:", type=("build", "run")) # old diff --git a/var/spack/repos/builtin/packages/py-send2trash/package.py b/var/spack/repos/builtin/packages/py-send2trash/package.py index 6c90fecee8bad4..fdd13fbd650403 100644 --- a/var/spack/repos/builtin/packages/py-send2trash/package.py +++ b/var/spack/repos/builtin/packages/py-send2trash/package.py @@ -14,6 +14,7 @@ class PySend2trash(PythonPackage): license("BSD-3-Clause") + version("1.8.3", sha256="90bcdf2ed2a18b687040c0f58bfccd6ad2e1b7ec495a9903119dc3c47c615052") version("1.8.0", sha256="937b038abd9f1e7b8c5d7a116be5dc4663beb71df74dcccffe56cacf992c7a9c") version("1.5.0", sha256="7cebc0ffc8b6d6e553bce9c6bb915614610ba2dec17c2f0643b1b97251da2a41") diff --git a/var/spack/repos/builtin/packages/py-websocket-client/package.py b/var/spack/repos/builtin/packages/py-websocket-client/package.py index b82bc1572984d8..eb5ddafbb6b9fc 100644 --- a/var/spack/repos/builtin/packages/py-websocket-client/package.py +++ b/var/spack/repos/builtin/packages/py-websocket-client/package.py @@ -15,6 +15,9 @@ class PyWebsocketClient(PythonPackage): license("Apache-2.0") + version("1.8.0", sha256="3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da") + version("1.7.0", sha256="10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6") + version("1.6.4", sha256="b3324019b3c28572086c4a319f91d1dcd44e6e11cd340232978c684a7650d0df") version("1.6.3", sha256="3aad25d31284266bcfcfd1fd8a743f63282305a364b8d0948a43bd606acc652f") version("1.5.1", sha256="3f09e6d8230892547132177f575a4e3e73cfdf06526e20cc02aa1c3b47184d40") version("1.4.1", sha256="f9611eb65c8241a67fb373bef040b3cf8ad377a9f6546a12b620b6511e8ea9ef") @@ -31,7 +34,7 @@ class PyWebsocketClient(PythonPackage): def url_for_version(self, version): url = "https://files.pythonhosted.org/packages/source/w/{0}/{0}-{1}.tar.gz" - if version >= Version("0.59.0"): + if self.spec.satisfies("@0.59.0:1.7"): letter = "websocket-client" else: letter = "websocket_client" From fc79c37e2d6b1a091415e5d279b65027d3793bd6 Mon Sep 17 00:00:00 2001 From: "Garth N. Wells" Date: Tue, 15 Oct 2024 16:38:18 +0100 Subject: [PATCH 04/28] (py-)fenics-dolfinx: add v0.9.0 (#46987) * Update fenics-dolfinx to v0.9 * py-fenics-dolfinx update to v0.9 * Small updates * Small fix --- .../builtin/packages/fenics-dolfinx/package.py | 9 +++++++-- .../builtin/packages/py-fenics-dolfinx/package.py | 14 +++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/var/spack/repos/builtin/packages/fenics-dolfinx/package.py b/var/spack/repos/builtin/packages/fenics-dolfinx/package.py index ba871cd731b1db..b252d5a9c90152 100644 --- a/var/spack/repos/builtin/packages/fenics-dolfinx/package.py +++ b/var/spack/repos/builtin/packages/fenics-dolfinx/package.py @@ -17,6 +17,7 @@ class FenicsDolfinx(CMakePackage): license("LGPL-3.0-or-later") version("main", branch="main") + version("0.9.0", sha256="b266c74360c2590c5745d74768c04568c965b44739becca4cd6b5aa58cdbbbd1") version("0.8.0", sha256="acf3104d9ecc0380677a6faf69eabfafc58d0cce43f7777e1307b95701c7cad9") version("0.7.2", sha256="7d9ce1338ce66580593b376327f23ac464a4ce89ef63c105efc1a38e5eae5c0b") version("0.6.0", sha256="eb8ac2bb2f032b0d393977993e1ab6b4101a84d54023a67206e3eac1a8d79b80") @@ -40,7 +41,8 @@ class FenicsDolfinx(CMakePackage): variant("slepc", default=False, description="slepc support") variant("adios2", default=False, description="adios2 support") - depends_on("cmake@3.19:", type="build") + depends_on("cmake@3.21:", when="@0.9:", type="build") + depends_on("cmake@3.19:", when="@:0.8", type="build") depends_on("pkgconfig", type="build") depends_on("mpi") depends_on("hdf5+mpi") @@ -49,16 +51,19 @@ class FenicsDolfinx(CMakePackage): depends_on("spdlog", when="@0.9:") depends_on("petsc+mpi+shared") - depends_on("slepc", when="+slepc") + + depends_on("adios2@2.8.1:+mpi", when="@0.9: +adios2") depends_on("adios2+mpi", when="+adios2") depends_on("fenics-ufcx@main", when="@main") + depends_on("fenics-ufcx@0.9", when="@0.9") depends_on("fenics-ufcx@0.8", when="@0.8") depends_on("fenics-ufcx@0.7", when="@0.7") depends_on("fenics-ufcx@0.6", when="@0.6") depends_on("fenics-basix@main", when="@main") + depends_on("fenics-basix@0.9", when="@0.9") depends_on("fenics-basix@0.8", when="@0.8") depends_on("fenics-basix@0.7", when="@0.7") depends_on("fenics-basix@0.6", when="@0.6") diff --git a/var/spack/repos/builtin/packages/py-fenics-dolfinx/package.py b/var/spack/repos/builtin/packages/py-fenics-dolfinx/package.py index 97ce274173cd5d..7ccfd32ddbad62 100644 --- a/var/spack/repos/builtin/packages/py-fenics-dolfinx/package.py +++ b/var/spack/repos/builtin/packages/py-fenics-dolfinx/package.py @@ -18,13 +18,15 @@ class PyFenicsDolfinx(PythonPackage): license("LGPL-3.0-only") version("main", branch="main") + version("0.9.0", sha256="b266c74360c2590c5745d74768c04568c965b44739becca4cd6b5aa58cdbbbd1") version("0.8.0", sha256="acf3104d9ecc0380677a6faf69eabfafc58d0cce43f7777e1307b95701c7cad9") version("0.7.2", sha256="7d9ce1338ce66580593b376327f23ac464a4ce89ef63c105efc1a38e5eae5c0b") version("0.6.0", sha256="eb8ac2bb2f032b0d393977993e1ab6b4101a84d54023a67206e3eac1a8d79b80") depends_on("cxx", type="build") # generated - depends_on("cmake@3.19:", type="build") + depends_on("cmake@3.21:", when="@0.9:", type="build") + depends_on("cmake@3.19:", when="@:0.8", type="build") depends_on("hdf5", type="build") depends_on("pkgconfig", type="build") @@ -33,24 +35,29 @@ class PyFenicsDolfinx(PythonPackage): depends_on("python@3.8:3.10", when="@0.6.0", type=("build", "run")) depends_on("fenics-dolfinx@main", when="@main") + depends_on("fenics-dolfinx@0.9.0", when="@0.9.0") depends_on("fenics-dolfinx@0.8.0", when="@0.8.0") depends_on("fenics-dolfinx@0.7.2", when="@0.7.2") depends_on("fenics-dolfinx@0.6.0", when="@0.6.0") depends_on("py-fenics-basix@main", type=("build", "run"), when="@main") + depends_on("py-fenics-basix@0.9", type=("build", "link"), when="@0.9") depends_on("py-fenics-basix@0.8", type=("build", "link"), when="@0.8") depends_on("fenics-basix@main", type=("build", "link"), when="@main") + depends_on("fenics-basix@0.9", type=("build", "link"), when="@0.9") depends_on("fenics-basix@0.8", type=("build", "link"), when="@0.8") depends_on("fenics-basix@0.7", type=("build", "link"), when="@0.7") depends_on("fenics-basix@0.6", type=("build", "link"), when="@0.6") depends_on("py-fenics-ffcx@main", type=("build", "run"), when="@main") + depends_on("py-fenics-ffcx@0.9", type=("build", "run"), when="@0.9") depends_on("py-fenics-ffcx@0.8", type=("build", "run"), when="@0.8") depends_on("py-fenics-ffcx@0.7", type=("build", "run"), when="@0.7") depends_on("py-fenics-ffcx@0.6", type=("build", "run"), when="@0.6") depends_on("py-fenics-ufl@main", type=("build", "run"), when="@main") + depends_on("py-fenics-ufl@2024.2", type=("build", "run"), when="@0.9") depends_on("py-fenics-ufl@2024.1", type=("build", "run"), when="@0.8") depends_on("py-fenics-ufl@2023.2", type=("build", "run"), when="@0.7") depends_on("py-fenics-ufl@2023.1", type=("build", "run"), when="@0.6") @@ -58,11 +65,12 @@ class PyFenicsDolfinx(PythonPackage): depends_on("py-numpy@1.21:", type=("build", "run")) depends_on("py-mpi4py", type=("build", "run")) depends_on("py-petsc4py", type=("build", "run")) - depends_on("py-cffi", type=("build", "run")) + depends_on("py-cffi@:1.16", type=("build", "run")) depends_on("py-nanobind@2:", when="@0.9:", type="build") depends_on("py-nanobind@1.8:1.9", when="@0.8", type="build") - depends_on("py-scikit-build-core+pyproject@0.5:", when="@0.8:", type="build") + depends_on("py-scikit-build-core+pyproject@0.10:", when="@0.10:", type="build") + depends_on("py-scikit-build-core+pyproject@0.5:", when="@0.8:0.9", type="build") depends_on("py-pybind11@2.7.0:", when="@:0.7", type=("build", "run")) depends_on("py-setuptools@42:", when="@:0.7", type="build") From 4d5844b4606c2ab947f406313364adc132455506 Mon Sep 17 00:00:00 2001 From: G-Ragghianti <33492707+G-Ragghianti@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:22:03 -0400 Subject: [PATCH 05/28] Changing github branch name (#46988) --- var/spack/repos/builtin/packages/dmtcp/package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/var/spack/repos/builtin/packages/dmtcp/package.py b/var/spack/repos/builtin/packages/dmtcp/package.py index 1b063a8e407ad9..4e890bbf85ce82 100644 --- a/var/spack/repos/builtin/packages/dmtcp/package.py +++ b/var/spack/repos/builtin/packages/dmtcp/package.py @@ -18,7 +18,7 @@ class Dmtcp(AutotoolsPackage): license("LGPL-3.0-only") maintainers("karya0") - version("master", branch="master") + version("main", branch="main") version("3.0.0", sha256="2c7e95e1dbc55db33433bfee48a65f274298e98f246a36ab6dad1e0694750d37") version("2.6.0", sha256="3ed62a86dd0cb9c828b93ee8c7c852d6f9c96a0efa48bcfe867521adf7bced68") version("2.5.2", sha256="0e3e5e15bd401b7b6937f2b678cd7d6a252eab0a143d5740b89cc3bebb4282be") From 0477875667e14dedddf59a9b3f5c379879ee2e50 Mon Sep 17 00:00:00 2001 From: psakievich Date: Tue, 15 Oct 2024 11:46:27 -0600 Subject: [PATCH 06/28] remove concrete spec constraint from `spack develop` (#46911) Remove the constraint for concrete specs and simply take the max(version) if a version is not given. This should default to the highest infinity version which is also the logical best guess for doing development. * Remove concrete verision constriant for develop, set docs * Add unit-test * Update lib/spack/docs/environments.rst Co-authored-by: kwryankrattiger <80296582+kwryankrattiger@users.noreply.github.com> * Update lib/spack/spack/cmd/develop.py Co-authored-by: Greg Becker * Consolidate env collection in cmd * Style --------- Co-authored-by: kwryankrattiger <80296582+kwryankrattiger@users.noreply.github.com> Co-authored-by: Greg Becker --- lib/spack/docs/environments.rst | 10 ++++++--- lib/spack/spack/cmd/develop.py | 21 ++++++++++--------- lib/spack/spack/test/cmd/develop.py | 6 ++++++ .../builtin.mock/packages/mpich/package.py | 1 + 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/lib/spack/docs/environments.rst b/lib/spack/docs/environments.rst index f2eb0fa9a0466a..eec185eab89e20 100644 --- a/lib/spack/docs/environments.rst +++ b/lib/spack/docs/environments.rst @@ -425,9 +425,13 @@ Developing Packages in a Spack Environment The ``spack develop`` command allows one to develop Spack packages in an environment. It requires a spec containing a concrete version, and -will configure Spack to install the package from local source. By -default, it will also clone the package to a subdirectory in the -environment. This package will have a special variant ``dev_path`` +will configure Spack to install the package from local source. +If a version is not provided from the command line interface then spack +will automatically pick the highest version the package has defined. +This means any infinity versions (``develop``, ``main``, ``stable``) will be +preferred in this selection process. +By default, ``spack develop`` will also clone the package to a subdirectory in the +environment for the local source. This package will have a special variant ``dev_path`` set, and Spack will ensure the package and its dependents are rebuilt any time the environment is installed if the package's local source code has been modified. Spack's native implementation to check for modifications diff --git a/lib/spack/spack/cmd/develop.py b/lib/spack/spack/cmd/develop.py index 0a9b7d13875ad3..1025b1bb691550 100644 --- a/lib/spack/spack/cmd/develop.py +++ b/lib/spack/spack/cmd/develop.py @@ -85,8 +85,14 @@ def _retrieve_develop_source(spec: spack.spec.Spec, abspath: str) -> None: def develop(parser, args): + # Note: we could put develop specs in any scope, but I assume + # users would only ever want to do this for either (a) an active + # env or (b) a specified config file (e.g. that is included by + # an environment) + # TODO: when https://github.com/spack/spack/pull/35307 is merged, + # an active env is not required if a scope is specified + env = spack.cmd.require_active_env(cmd_name="develop") if not args.spec: - env = spack.cmd.require_active_env(cmd_name="develop") if args.clone is False: raise SpackError("No spec provided to spack develop command") @@ -116,16 +122,18 @@ def develop(parser, args): raise SpackError("spack develop requires at most one named spec") spec = specs[0] + version = spec.versions.concrete_range_as_version if not version: - raise SpackError("Packages to develop must have a concrete version") + # look up the maximum version so infintiy versions are preferred for develop + version = max(spec.package_class.versions.keys()) + tty.msg(f"Defaulting to highest version: {spec.name}@{version}") spec.versions = spack.version.VersionList([version]) # If user does not specify --path, we choose to create a directory in the # active environment's directory, named after the spec path = args.path or spec.name if not os.path.isabs(path): - env = spack.cmd.require_active_env(cmd_name="develop") abspath = spack.util.path.canonicalize_path(path, default_wd=env.path) else: abspath = path @@ -149,13 +157,6 @@ def develop(parser, args): _retrieve_develop_source(spec, abspath) - # Note: we could put develop specs in any scope, but I assume - # users would only ever want to do this for either (a) an active - # env or (b) a specified config file (e.g. that is included by - # an environment) - # TODO: when https://github.com/spack/spack/pull/35307 is merged, - # an active env is not required if a scope is specified - env = spack.cmd.require_active_env(cmd_name="develop") tty.debug("Updating develop config for {0} transactionally".format(env.name)) with env.write_transaction(): if args.build_directory is not None: diff --git a/lib/spack/spack/test/cmd/develop.py b/lib/spack/spack/test/cmd/develop.py index 202e165165c4c4..c0cbb003ec1e2e 100644 --- a/lib/spack/spack/test/cmd/develop.py +++ b/lib/spack/spack/test/cmd/develop.py @@ -65,6 +65,12 @@ def test_develop_no_clone(self, tmpdir): develop("--no-clone", "-p", str(tmpdir), "mpich@1.0") self.check_develop(e, spack.spec.Spec("mpich@=1.0"), str(tmpdir)) + def test_develop_no_version(self, tmpdir): + env("create", "test") + with ev.read("test") as e: + develop("--no-clone", "-p", str(tmpdir), "mpich") + self.check_develop(e, spack.spec.Spec("mpich@=main"), str(tmpdir)) + def test_develop(self): env("create", "test") with ev.read("test") as e: diff --git a/var/spack/repos/builtin.mock/packages/mpich/package.py b/var/spack/repos/builtin.mock/packages/mpich/package.py index 08338033a9847c..4c87d6932fa8cc 100644 --- a/var/spack/repos/builtin.mock/packages/mpich/package.py +++ b/var/spack/repos/builtin.mock/packages/mpich/package.py @@ -16,6 +16,7 @@ class Mpich(Package): variant("debug", default=False, description="Compile MPICH with debug flags.") + version("main", branch="main", git="https://github.com/pmodels/mpich") version("3.0.4", md5="9c5d5d4fe1e17dd12153f40bc5b6dbc0") version("3.0.3", md5="0123456789abcdef0123456789abcdef") version("3.0.2", md5="0123456789abcdef0123456789abcdef") From 12599921591c58b868062ddcc5be5bea1b4c4454 Mon Sep 17 00:00:00 2001 From: Caetano Melone Date: Tue, 15 Oct 2024 14:49:45 -0300 Subject: [PATCH 07/28] Reduce noop job resource requests (#46920) `no-spec-to-rebuild` jobs use far less resources than they request. For example, [this](https://gitlab.spack.io/spack/spack/-/jobs/12944487) job [used](https://prometheus.spack.io/api/v1/query_range?query=container_memory_working_set_bytes{pod=%22runner-dcsgp53u-project-2-concurrent-3-0ubclrr1%22}&start=1728655743&end=1728656543&step=1s) around 3MB. While this won't lead to any crazy cost savings, k8s requests effectively block other jobs from using the resources, so reducing this to a reasonable number is important. --- share/spack/gitlab/cloud_pipelines/configs/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/spack/gitlab/cloud_pipelines/configs/ci.yaml b/share/spack/gitlab/cloud_pipelines/configs/ci.yaml index 5ad2b7cd9894fb..10eb7459a71b00 100644 --- a/share/spack/gitlab/cloud_pipelines/configs/ci.yaml +++ b/share/spack/gitlab/cloud_pipelines/configs/ci.yaml @@ -111,8 +111,8 @@ ci: CI_OIDC_REQUIRED: 0 GIT_STRATEGY: "none" CI_JOB_SIZE: "small" - KUBERNETES_CPU_REQUEST: "500m" - KUBERNETES_MEMORY_REQUEST: "500M" + KUBERNETES_CPU_REQUEST: "100m" + KUBERNETES_MEMORY_REQUEST: "5M" before_script:: [] after_script:: [] From 5947c13570297ed1663ba8c84eb04519521e9257 Mon Sep 17 00:00:00 2001 From: Chris Marsh Date: Tue, 15 Oct 2024 17:46:42 -0600 Subject: [PATCH 08/28] py-metpy: add v1.6.2 (#46990) * Add v1.6.2 * Add variant desc * fix style --- .../builtin/packages/py-metpy/package.py | 57 ++++++++++++++----- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/var/spack/repos/builtin/packages/py-metpy/package.py b/var/spack/repos/builtin/packages/py-metpy/package.py index 3be38a414c857b..59ab20a012b95f 100644 --- a/var/spack/repos/builtin/packages/py-metpy/package.py +++ b/var/spack/repos/builtin/packages/py-metpy/package.py @@ -20,20 +20,47 @@ class PyMetpy(PythonPackage): license("BSD-3-Clause") + version("1.6.2", sha256="eb065bac0d7818587fa38fa6c96dfe720d9d15b59af4e4866541894e267476bb") version("1.0.1", sha256="16fa9806facc24f31f454b898741ec5639a72ba9d4ff8a19ad0e94629d93cb95") - depends_on("python@3.6:", type=("build", "run")) - depends_on("py-setuptools", type="build") - depends_on("py-setuptools-scm", type="build") - depends_on("py-importlib-metadata@1.0.0:", when="^python@:3.7", type=("build", "run")) - depends_on("py-importlib-resources@1.3.0:", when="^python@:3.8", type=("build", "run")) - depends_on("py-matplotlib@2.1.0:", type=("build", "run")) - depends_on("py-numpy@1.16.0:", type=("build", "run")) - depends_on("py-pandas@0.24.0:", type=("build", "run")) - # Unable to Find "pint.unit" -- Module Not Found Error with py-pint@0.20: - depends_on("py-pint@0.10.1:0.19", type=("build", "run")) - depends_on("py-pooch@0.1:", type=("build", "run")) - depends_on("py-pyproj@2.3.0:", type=("build", "run")) - depends_on("py-scipy@1.0:", type=("build", "run")) - depends_on("py-traitlets@4.3.0:", type=("build", "run")) - depends_on("py-xarray@0.14.1:", type=("build", "run")) + variant( + "extras", + default=False, + when="@1.6.2:", + description="Enable xarray lazy-loading and advanced plotting", + ) + + with when("@1.6.2"): + depends_on("python@3.9:", type=("build", "run")) + depends_on("py-setuptools@61:", type="build") + depends_on("py-setuptools-scm@3.4:", type="build") + depends_on("py-matplotlib@3.5.0:", type=("build", "run")) + depends_on("py-numpy@1.20.0:", type=("build", "run")) + depends_on("py-pandas@1.4.0:", type=("build", "run")) + depends_on("py-pint@0.17:", type=("build", "run")) + depends_on("py-pooch@1.2.0:", type=("build", "run")) + depends_on("py-pyproj@3.0.0:", type=("build", "run")) + depends_on("py-scipy@1.8.0:", type=("build", "run")) + depends_on("py-traitlets@5.0.5:", type=("build", "run")) + depends_on("py-xarray@0.21.0:", type=("build", "run")) + + depends_on("py-cartopy@0.12.0:", when="+extras") + depends_on("py-dask@2020.12.0:", when="+extras") + depends_on("py-shapely@1.6.4:", when="+extras") + + with when("@1.0.1"): + depends_on("python@3.6:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-setuptools-scm", type="build") + depends_on("py-importlib-metadata@1.0.0:", when="^python@:3.7", type=("build", "run")) + depends_on("py-importlib-resources@1.3.0:", when="^python@:3.8", type=("build", "run")) + depends_on("py-matplotlib@2.1.0:", type=("build", "run")) + depends_on("py-numpy@1.16.0:", type=("build", "run")) + depends_on("py-pandas@0.24.0:", type=("build", "run")) + # Unable to Find "pint.unit" -- Module Not Found Error with py-pint@0.20: + depends_on("py-pint@0.10.1:0.19", type=("build", "run")) + depends_on("py-pooch@0.1:", type=("build", "run")) + depends_on("py-pyproj@2.3.0:", type=("build", "run")) + depends_on("py-scipy@1.0:", type=("build", "run")) + depends_on("py-traitlets@4.3.0:", type=("build", "run")) + depends_on("py-xarray@0.14.1:", type=("build", "run")) From 2099e9f5cd6b4c61ac2d1e7e7426f87453d9a833 Mon Sep 17 00:00:00 2001 From: downloadico Date: Tue, 15 Oct 2024 17:47:46 -0600 Subject: [PATCH 09/28] abinit: add v10.0.9 (#46923) Co-authored-by: Bernhard Kaindl Co-authored-by: Wouter Deconinck --- .../repos/builtin/packages/abinit/package.py | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/var/spack/repos/builtin/packages/abinit/package.py b/var/spack/repos/builtin/packages/abinit/package.py index 6b4e8dee2588c5..b93ab7798f5014 100644 --- a/var/spack/repos/builtin/packages/abinit/package.py +++ b/var/spack/repos/builtin/packages/abinit/package.py @@ -24,11 +24,12 @@ class Abinit(AutotoolsPackage): programs are provided. """ - homepage = "https://www.abinit.org/" - url = "https://www.abinit.org/sites/default/files/packages/abinit-10.0.7.tar.gz" + homepage = "https://abinit.github.io/abinit_web/" + url = "https://forge.abinit.org/abinit-10.0.9.tar.gz" license("Apache-2.0") maintainers("downloadico") + version("10.0.9", sha256="17650580295e07895f6c3c4b1f3f0fe0e0f3fea9bab5fd8ce7035b16a62f8e5e") version("10.0.7", sha256="a9fc044b33861b7defd50fafd19a73eb6f225e18ae30b23bc731d9c8009c881c") version("9.10.5", sha256="a9e0f0e058baa6088ea93d26ada369ccf0fe52dc9d4a865b1c38c20620148cd5") version("9.10.3", sha256="3f2a9aebbf1fee9855a09dd687f88d2317b8b8e04f97b2628ab96fb898dce49b") @@ -41,8 +42,6 @@ class Abinit(AutotoolsPackage): version("8.8.2", sha256="15216703bd56a799a249a112b336d07d733627d3756487a4b1cb48ebb625c3e7") version("8.6.3", sha256="82e8d071088ab8dc1b3a24380e30b68c544685678314df1213180b449c84ca65") version("8.2.2", sha256="e43544a178d758b0deff3011c51ef7c957d7f2df2ce8543366d68016af9f3ea1") - # Versions before 8.0.8b are not supported. - version("8.0.8b", sha256="37ad5f0f215d2a36e596383cb6e54de3313842a0390ce8d6b48a423d3ee25af2") depends_on("c", type="build") # generated depends_on("cxx", type="build") # generated @@ -210,14 +209,23 @@ def configure_args(self): # BLAS/LAPACK/SCALAPACK-ELPA linalg = spec["lapack"].libs + spec["blas"].libs + + # linalg_flavor is selected using the virtual lapack provider is_using_intel_libraries = spec["lapack"].name in INTEL_MATH_LIBRARIES + + # These *must* be elifs, otherwise spack's lapack provider is ignored + # linalg_flavor ends up as "custom", which is not supported by abinit@9.10.3: if is_using_intel_libraries: linalg_flavor = "mkl" - elif spec.satisfies("@9:") and spec.satisfies("^openblas"): - linalg_flavor = "openblas" - elif spec.satisfies("@9:") and spec.satisfies("^fujitsu-ssl2"): + # Else, if spack's virtual "lapack" provider is openblas, use it: + elif spec.satisfies("@9:") and ( + spec["lapack"].name == "openblas" or spec.satisfies("^fujitsu-ssl2") + ): linalg_flavor = "openblas" else: + # If you need to force custom (and not have it as fallback, like now) + # you should likely implement a variant to force it, but it seems that + # newer versions do not have it, so it should likely be a fallback: linalg_flavor = "custom" if spec.satisfies("+scalapack"): From b0314faa3d538d38ef516cbaa60c7653974123a2 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 15 Oct 2024 18:48:55 -0500 Subject: [PATCH 10/28] sqlcipher: add v4.6.1 (#47000) --- .../builtin/packages/sqlcipher/package.py | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/var/spack/repos/builtin/packages/sqlcipher/package.py b/var/spack/repos/builtin/packages/sqlcipher/package.py index 64de6d7367e477..221393e1b6e259 100644 --- a/var/spack/repos/builtin/packages/sqlcipher/package.py +++ b/var/spack/repos/builtin/packages/sqlcipher/package.py @@ -18,14 +18,18 @@ class Sqlcipher(AutotoolsPackage): license("BSD-3-Clause") - version("4.4.1", sha256="a36ed7c879a5e9af1054942201c75fc56f1db22e46bf6c2bbae3975dfeb6782d") - version("4.4.0", sha256="0924b2ae1079717954498bda78a30de20ce2a6083076b16214a711567821d148") - version("4.3.0", sha256="fccb37e440ada898902b294d02cde7af9e8706b185d77ed9f6f4d5b18b4c305f") - version("4.2.0", sha256="105c1b813f848da038c03647a8bfc9d42fb46865e6aaf4edfd46ff3b18cdccfc") - version("4.1.0", sha256="65144ca3ba4c0f9cd4bae8c20bb42f2b84424bf29d1ebcf04c44a728903b1faa") - version("4.0.1", sha256="2f803017378c7479cb791be59b7bad8392a15acddbcc094e4433581fe421f4ca") - version("4.0.0", sha256="c8f5fc6d800aae6107bf23900144804db5510c2676c93fbb269e4a0700837d68") - version("3.4.2", sha256="69897a5167f34e8a84c7069f1b283aba88cdfa8ec183165c4a5da2c816cfaadb") + version("4.6.1", sha256="d8f9afcbc2f4b55e316ca4ada4425daf3d0b4aab25f45e11a802ae422b9f53a3") + with default_args(deprecated=True): + # https://nvd.nist.gov/vuln/detail/CVE-2021-3119 + version("4.4.1", sha256="a36ed7c879a5e9af1054942201c75fc56f1db22e46bf6c2bbae3975dfeb6782d") + version("4.4.0", sha256="0924b2ae1079717954498bda78a30de20ce2a6083076b16214a711567821d148") + version("4.3.0", sha256="fccb37e440ada898902b294d02cde7af9e8706b185d77ed9f6f4d5b18b4c305f") + version("4.2.0", sha256="105c1b813f848da038c03647a8bfc9d42fb46865e6aaf4edfd46ff3b18cdccfc") + version("4.1.0", sha256="65144ca3ba4c0f9cd4bae8c20bb42f2b84424bf29d1ebcf04c44a728903b1faa") + version("4.0.1", sha256="2f803017378c7479cb791be59b7bad8392a15acddbcc094e4433581fe421f4ca") + version("4.0.0", sha256="c8f5fc6d800aae6107bf23900144804db5510c2676c93fbb269e4a0700837d68") + # strictly, 3.4.2 is not affected by any CVEs + version("3.4.2", sha256="69897a5167f34e8a84c7069f1b283aba88cdfa8ec183165c4a5da2c816cfaadb") depends_on("c", type="build") # generated depends_on("cxx", type="build") # generated From e3afe9a364d2abd4f73f3ea96847f2d8a576d4b2 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 15 Oct 2024 18:50:56 -0500 Subject: [PATCH 11/28] yara: add v4.5.2 (fix CVE) (#46998) * yara: add v4.5.2 * yara: deprecate 3.9.0 --- var/spack/repos/builtin/packages/yara/package.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/var/spack/repos/builtin/packages/yara/package.py b/var/spack/repos/builtin/packages/yara/package.py index 7b2da9e1e8767d..cce0191a10413e 100644 --- a/var/spack/repos/builtin/packages/yara/package.py +++ b/var/spack/repos/builtin/packages/yara/package.py @@ -15,7 +15,10 @@ class Yara(AutotoolsPackage): license("BSD-3-Clause") - version("3.9.0", sha256="ebe7fab0abadb90449a62afbd24e196e18b177efe71ffd8bf22df95c5386f64d") + version("4.5.2", sha256="1f87056fcb10ee361936ee7b0548444f7974612ebb0e681734d8de7df055d1ec") + with default_args(deprecated=True): + # https://nvd.nist.gov/vuln/detail/CVE-2021-3402 + version("3.9.0", sha256="ebe7fab0abadb90449a62afbd24e196e18b177efe71ffd8bf22df95c5386f64d") depends_on("c", type="build") # generated depends_on("cxx", type="build") # generated @@ -24,3 +27,4 @@ class Yara(AutotoolsPackage): depends_on("automake", type="build") depends_on("libtool", type="build") depends_on("m4", type="build") + depends_on("pkgconfig", type="build", when="@4:") From 58e2f7a54f62d10b8f0812a524d345fc27b81993 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 15 Oct 2024 19:03:47 -0500 Subject: [PATCH 12/28] hive: add v4.0.1 (#46995) --- var/spack/repos/builtin/packages/hive/package.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/var/spack/repos/builtin/packages/hive/package.py b/var/spack/repos/builtin/packages/hive/package.py index 8a26d742e453b9..89dc7de044ed0d 100644 --- a/var/spack/repos/builtin/packages/hive/package.py +++ b/var/spack/repos/builtin/packages/hive/package.py @@ -19,10 +19,13 @@ class Hive(Package): license("Apache-2.0", checked_by="wdconinc") - version("3.1.3", sha256="0c9b6a6359a7341b6029cc9347435ee7b379f93846f779d710b13f795b54bb16") - version("3.1.2", sha256="d75dcf36908b4e7b9b0ec9aec57a46a6628b97b276c233cb2c2f1a3e89b13462") - version("2.3.6", sha256="0b3736edc8d15f01ed649bfce7d74346c35fd57567411e9d0c3f48578f76610d") - version("1.2.2", sha256="763b246a1a1ceeb815493d1e5e1d71836b0c5b9be1c4cd9c8d685565113771d1") + version("4.0.1", sha256="2bf988a1ed17437b1103e367939c25a13f64d36cf6d1c3bef8c3f319f0067619") + with default_args(deprecated=True): + # https://nvd.nist.gov/vuln/detail/CVE-2020-13949 + version("3.1.3", sha256="0c9b6a6359a7341b6029cc9347435ee7b379f93846f779d710b13f795b54bb16") + version("3.1.2", sha256="d75dcf36908b4e7b9b0ec9aec57a46a6628b97b276c233cb2c2f1a3e89b13462") + version("2.3.6", sha256="0b3736edc8d15f01ed649bfce7d74346c35fd57567411e9d0c3f48578f76610d") + version("1.2.2", sha256="763b246a1a1ceeb815493d1e5e1d71836b0c5b9be1c4cd9c8d685565113771d1") depends_on("hadoop", type="run") From 2a7dd29f9570af75c3a47fc37208d22ebfe4f570 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 15 Oct 2024 19:17:03 -0500 Subject: [PATCH 13/28] krb5: add v1.21.3 (fix CVEs) (#46989) * krb5: add 1.21.3 * krb5: fix style * [@spackbot] updating style on behalf of wdconinc --------- Co-authored-by: wdconinc --- .../repos/builtin/packages/krb5/package.py | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/var/spack/repos/builtin/packages/krb5/package.py b/var/spack/repos/builtin/packages/krb5/package.py index 73c349ca6f8636..0485a999005c8b 100644 --- a/var/spack/repos/builtin/packages/krb5/package.py +++ b/var/spack/repos/builtin/packages/krb5/package.py @@ -16,21 +16,46 @@ class Krb5(AutotoolsPackage): list_url = "https://kerberos.org/dist/krb5/" list_depth = 1 - license("MIT") - - version("1.21.2", sha256="9560941a9d843c0243a71b17a7ac6fe31c7cebb5bce3983db79e52ae7e850491") - version("1.20.1", sha256="704aed49b19eb5a7178b34b2873620ec299db08752d6a8574f95d41879ab8851") - version("1.19.4", sha256="41f5981c5a4de0a26b3937e679a116cd5b3739641fd253124aac91f7179b54eb") - version("1.19.3", sha256="56d04863cfddc9d9eb7af17556e043e3537d41c6e545610778676cf551b9dcd0") - version("1.19.2", sha256="10453fee4e3a8f8ce6129059e5c050b8a65dab1c257df68b99b3112eaa0cdf6a") - version("1.18.2", sha256="c6e4c9ec1a98141c3f5d66ddf1a135549050c9fab4e9a4620ee9b22085873ae0") - version("1.18.1", sha256="02a4e700f10936f937cd1a4c303cab8687a11abecc6107bd4b706b9329cd5400") - version("1.18", sha256="73913934d711dcf9d5f5605803578edb44b9a11786df3c1b2711f4e1752f2c88") - version("1.17.1", sha256="3706d7ec2eaa773e0e32d3a87bf742ebaecae7d064e190443a3acddfd8afb181") - version("1.17", sha256="5a6e2284a53de5702d3dc2be3b9339c963f9b5397d3fbbc53beb249380a781f5") - version("1.16.3", sha256="e40499df7c6dbef0cf9b11870a0e167cde827737d8b2c06a9436334f08ab9b0d") - version("1.16.2", sha256="9f721e1fe593c219174740c71de514c7228a97d23eb7be7597b2ae14e487f027") - version("1.16.1", sha256="214ffe394e3ad0c730564074ec44f1da119159d94281bbec541dc29168d21117") + license("MIT", checked_by="wdconinc") + + version("1.21.3", sha256="b7a4cd5ead67fb08b980b21abd150ff7217e85ea320c9ed0c6dadd304840ad35") + with default_args(deprecated=True): + # https://nvd.nist.gov/vuln/detail/CVE-2024-37371 + version( + "1.21.2", sha256="9560941a9d843c0243a71b17a7ac6fe31c7cebb5bce3983db79e52ae7e850491" + ) + version( + "1.20.1", sha256="704aed49b19eb5a7178b34b2873620ec299db08752d6a8574f95d41879ab8851" + ) + version( + "1.19.4", sha256="41f5981c5a4de0a26b3937e679a116cd5b3739641fd253124aac91f7179b54eb" + ) + version( + "1.19.3", sha256="56d04863cfddc9d9eb7af17556e043e3537d41c6e545610778676cf551b9dcd0" + ) + version( + "1.19.2", sha256="10453fee4e3a8f8ce6129059e5c050b8a65dab1c257df68b99b3112eaa0cdf6a" + ) + version( + "1.18.2", sha256="c6e4c9ec1a98141c3f5d66ddf1a135549050c9fab4e9a4620ee9b22085873ae0" + ) + version( + "1.18.1", sha256="02a4e700f10936f937cd1a4c303cab8687a11abecc6107bd4b706b9329cd5400" + ) + version("1.18", sha256="73913934d711dcf9d5f5605803578edb44b9a11786df3c1b2711f4e1752f2c88") + version( + "1.17.1", sha256="3706d7ec2eaa773e0e32d3a87bf742ebaecae7d064e190443a3acddfd8afb181" + ) + version("1.17", sha256="5a6e2284a53de5702d3dc2be3b9339c963f9b5397d3fbbc53beb249380a781f5") + version( + "1.16.3", sha256="e40499df7c6dbef0cf9b11870a0e167cde827737d8b2c06a9436334f08ab9b0d" + ) + version( + "1.16.2", sha256="9f721e1fe593c219174740c71de514c7228a97d23eb7be7597b2ae14e487f027" + ) + version( + "1.16.1", sha256="214ffe394e3ad0c730564074ec44f1da119159d94281bbec541dc29168d21117" + ) depends_on("c", type="build") # generated depends_on("cxx", type="build") # generated @@ -42,7 +67,7 @@ class Krb5(AutotoolsPackage): depends_on("gettext") depends_on("perl", type="build") depends_on("findutils", type="build") - depends_on("pkgconfig", type="build", when="^openssl~shared") + depends_on("pkgconfig", type="build") variant( "shared", default=True, description="install shared libraries if True, static if false" From c00f36b5e2511dcd005371ea82acfe9ab58625a8 Mon Sep 17 00:00:00 2001 From: Michael B Kuhn <31661049+mbkuhn@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:29:28 -0600 Subject: [PATCH 14/28] adding latest AMR-Wind versions and correcting 2.1.0 reference (#46954) --- .../builtin/packages/amr-wind/package.py | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/var/spack/repos/builtin/packages/amr-wind/package.py b/var/spack/repos/builtin/packages/amr-wind/package.py index 5c11e17c465be6..a9657f4db7c271 100644 --- a/var/spack/repos/builtin/packages/amr-wind/package.py +++ b/var/spack/repos/builtin/packages/amr-wind/package.py @@ -22,7 +22,67 @@ class AmrWind(CMakePackage, CudaPackage, ROCmPackage): version("main", branch="main", submodules=True) version( - "2.1.0", tag="v2.1.0", commit="bc787f21deca9239928182e27400133934c62658", submodules=True + "3.1.5", tag="v3.1.5", commit="554f8aa1ac36c2bae17565c64d5bc33333cee396", submodules=True + ) + version( + "3.1.4", tag="v3.1.4", commit="e10f5ebd3141b9990a65ebe9f1bdca8554b59472", submodules=True + ) + version( + "3.1.3", tag="v3.1.3", commit="af8231ace69119133c4c8a906e98946ec5aa79c8", submodules=True + ) + version( + "3.1.2", tag="v3.1.2", commit="5edcac4496e30e450c0f21e7fa74f8b590dc3860", submodules=True + ) + version( + "3.1.1", tag="v3.1.1", commit="8ae06194fa47bf473615988f97a7b423d467b023", submodules=True + ) + version( + "3.1.0", tag="v3.1.0", commit="3e23581b132532bf70b09c38217ff9c46204f047", submodules=True + ) + version( + "3.0.2", tag="v3.0.2", commit="f867288dffecc6404189afa965189c2558cf9922", submodules=True + ) + version( + "3.0.1", tag="v3.0.1", commit="65aa85db5cb3bbabc767d5dde4b106b7022a0f90", submodules=True + ) + version( + "3.0.0", tag="v3.0.0", commit="2fbd345cfa7cb7277c1cb6a1323247579e1bbc32", submodules=True + ) + version( + "2.6.0", tag="v2.6.0", commit="31ef1137b00b304b62b84edaa5b819c0bf0b7436", submodules=True + ) + version( + "2.5.0", tag="v2.5.0", commit="f9f499b6926339f96b3ff260495b8782c045555c", submodules=True + ) + version( + "2.4.3", tag="v2.4.3", commit="4be85f376d4939f8e5534b7985917e4cfccedfaf", submodules=True + ) + version( + "2.4.2", tag="v2.4.2", commit="5ebb2abf2df9c87e6086d8f55a4d929ff0cdb37b", submodules=True + ) + version( + "2.4.1", tag="v2.4.1", commit="40accd372f850e10fcbeee6ddecc4d15fd6364c6", submodules=True + ) + version( + "2.4.0", tag="v2.4.0", commit="b8ab898b7e9e8e78455b61e303940b80d00d18ca", submodules=True + ) + version( + "2.3.2", tag="v2.3.2", commit="61cbb21e8dfdeea47a0add772cd52abac33c4901", submodules=True + ) + version( + "2.3.1", tag="v2.3.1", commit="cc51dadb34de9f333605a5bfb83b72c9310f676a", submodules=True + ) + version( + "2.3.0", tag="v2.3.0", commit="6ba000b628aa3178545cdbbea508cc2cb2e5c76c", submodules=True + ) + version( + "2.2.1", tag="v2.2.1", commit="e131a79f8e68be181390a2656f54268f90a9e78a", submodules=True + ) + version( + "2.2.0", tag="v2.2.0", commit="bc787f21deca9239928182e27400133934c62658", submodules=True + ) + version( + "2.1.0", tag="v2.1.0", commit="13e15b52f4a1651a3d72324a71ba1e18255663e7", submodules=True ) version( "2.0.0", tag="v2.0.0", commit="ea448365033fc6bc9ee0febeb369b377f4fd8240", submodules=True From 57586df91a6a681e06e280abdaa93fc2ea425565 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 15 Oct 2024 20:53:55 -0500 Subject: [PATCH 15/28] libtiff: add v4.7.0 (fix CVE) (#46999) * libtiff: add v4.7.0 * [@spackbot] updating style on behalf of wdconinc --------- Co-authored-by: wdconinc --- .../repos/builtin/packages/libtiff/package.py | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/var/spack/repos/builtin/packages/libtiff/package.py b/var/spack/repos/builtin/packages/libtiff/package.py index 2b1778292653e0..f1f337bbcf5bb4 100644 --- a/var/spack/repos/builtin/packages/libtiff/package.py +++ b/var/spack/repos/builtin/packages/libtiff/package.py @@ -40,21 +40,26 @@ class Libtiff(CMakePackage, AutotoolsPackage): license("libtiff") - version("4.6.0", sha256="88b3979e6d5c7e32b50d7ec72fb15af724f6ab2cbf7e10880c360a77e4b5d99a") - version("4.5.1", sha256="d7f38b6788e4a8f5da7940c5ac9424f494d8a79eba53d555f4a507167dca5e2b") - version("4.5.0", sha256="c7a1d9296649233979fa3eacffef3fa024d73d05d589cb622727b5b08c423464") - version("4.4.0", sha256="917223b37538959aca3b790d2d73aa6e626b688e02dcda272aec24c2f498abed") - version("4.3.0", sha256="0e46e5acb087ce7d1ac53cf4f56a09b221537fc86dfc5daaad1c2e89e1b37ac8") - version("4.2.0", sha256="eb0484e568ead8fa23b513e9b0041df7e327f4ee2d22db5a533929dfc19633cb") - version("4.1.0", sha256="5d29f32517dadb6dbcd1255ea5bbc93a2b54b94fbf83653b4d65c7d6775b8634") - version("4.0.10", sha256="2c52d11ccaf767457db0c46795d9c7d1a8d8f76f68b0b800a3dfe45786b996e4") - version("4.0.9", sha256="6e7bdeec2c310734e734d19aae3a71ebe37a4d842e0e23dbb1b8921c0026cfcd") - version("4.0.8", sha256="59d7a5a8ccd92059913f246877db95a2918e6c04fb9d43fd74e5c3390dac2910") - version("4.0.7", sha256="9f43a2cfb9589e5cecaa66e16bf87f814c945f22df7ba600d63aac4632c4f019") - version("4.0.6", sha256="4d57a50907b510e3049a4bba0d7888930fdfc16ce49f1bf693e5b6247370d68c") - version("4.0.5", sha256="e25eaa83ed7fab43ddd278b9b14d91a406a4b674cedc776adb95535f897f309c") - version("4.0.4", sha256="8cb1d90c96f61cdfc0bcf036acc251c9dbe6320334da941c7a83cfe1576ef890") - version("3.9.7", sha256="f5d64dd4ce61c55f5e9f6dc3920fbe5a41e02c2e607da7117a35eb5c320cef6a") + version("4.7.0", sha256="67160e3457365ab96c5b3286a0903aa6e78bdc44c4bc737d2e486bcecb6ba976") + with default_args(deprecated=True): + # https://nvd.nist.gov/vuln/detail/CVE-2024-7006 + version("4.6.0", sha256="88b3979e6d5c7e32b50d7ec72fb15af724f6ab2cbf7e10880c360a77e4b5d99a") + version("4.5.1", sha256="d7f38b6788e4a8f5da7940c5ac9424f494d8a79eba53d555f4a507167dca5e2b") + version("4.5.0", sha256="c7a1d9296649233979fa3eacffef3fa024d73d05d589cb622727b5b08c423464") + version("4.4.0", sha256="917223b37538959aca3b790d2d73aa6e626b688e02dcda272aec24c2f498abed") + version("4.3.0", sha256="0e46e5acb087ce7d1ac53cf4f56a09b221537fc86dfc5daaad1c2e89e1b37ac8") + version("4.2.0", sha256="eb0484e568ead8fa23b513e9b0041df7e327f4ee2d22db5a533929dfc19633cb") + version("4.1.0", sha256="5d29f32517dadb6dbcd1255ea5bbc93a2b54b94fbf83653b4d65c7d6775b8634") + version( + "4.0.10", sha256="2c52d11ccaf767457db0c46795d9c7d1a8d8f76f68b0b800a3dfe45786b996e4" + ) + version("4.0.9", sha256="6e7bdeec2c310734e734d19aae3a71ebe37a4d842e0e23dbb1b8921c0026cfcd") + version("4.0.8", sha256="59d7a5a8ccd92059913f246877db95a2918e6c04fb9d43fd74e5c3390dac2910") + version("4.0.7", sha256="9f43a2cfb9589e5cecaa66e16bf87f814c945f22df7ba600d63aac4632c4f019") + version("4.0.6", sha256="4d57a50907b510e3049a4bba0d7888930fdfc16ce49f1bf693e5b6247370d68c") + version("4.0.5", sha256="e25eaa83ed7fab43ddd278b9b14d91a406a4b674cedc776adb95535f897f309c") + version("4.0.4", sha256="8cb1d90c96f61cdfc0bcf036acc251c9dbe6320334da941c7a83cfe1576ef890") + version("3.9.7", sha256="f5d64dd4ce61c55f5e9f6dc3920fbe5a41e02c2e607da7117a35eb5c320cef6a") depends_on("c", type="build") # generated depends_on("cxx", type="build") # generated From d2f1e2992719beb4d8f56a1be267073e75c3741a Mon Sep 17 00:00:00 2001 From: Tom Scogland Date: Tue, 15 Oct 2024 19:04:33 -0700 Subject: [PATCH 16/28] Fix neovim on Darwin (#46905) * lua: update luarocks resource to 3.11.1 We have kept an older 3.8 for some time, but that now uses an incorrect value for the deployment target for macos, causing builds for bundles to succeed but in such a way that they can't be linked to applications by `ld` but only loaded by dlopen. This fixes that, and also generally updates the tool. * lua-luajit-openresty: add new version fix LUA_PATH Adds a newer version of openresty's luajor, and adds the slightly odd extra share path they use that contains the `jit.*` modules. Without that, things that use bytecode-saving and other jit routines (like neovim) fail. * lua-lpeg: fix lpeg build to work for neovim on OSX Normally luarocks builds all lua libraries as bundles on macos, this makes sense, but means they can't then be linked by LD into executables the way neovim expects to do. I'm not sure how this ever worked, if it did. This patch adds the appropriate variables to have luarocks build the library as a shared librar, and subsequently fix the id with install_name_tool (the built-in functionality for this does not trigger). This also adds a symlink from `liblpeg.dylib` to `lpeg.so` because neovim will not build on macos without it. See corresponding upstream pull request at https://github.com/neovim/neovim/pull/30749 --- .../builtin/packages/lua-lpeg/package.py | 36 +++++++++++++++++++ .../packages/lua-luajit-openresty/package.py | 14 ++++++-- .../repos/builtin/packages/lua/package.py | 4 +-- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/var/spack/repos/builtin/packages/lua-lpeg/package.py b/var/spack/repos/builtin/packages/lua-lpeg/package.py index c15539ae83f2d6..2615c4a9c8b5bf 100644 --- a/var/spack/repos/builtin/packages/lua-lpeg/package.py +++ b/var/spack/repos/builtin/packages/lua-lpeg/package.py @@ -4,6 +4,9 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import os + +import spack.build_systems.lua from spack.package import * @@ -32,3 +35,36 @@ class LuaLpeg(LuaPackage): ) depends_on("lua-lang@:5.1.9", when="@:0.12.1 ^[virtuals=lua-lang] lua") + + +class LuaBuilder(spack.build_systems.lua.LuaBuilder): + # without this, the resulting library cannot be linked by a normal link phase, the + # way neovim expects to link it, works fine with lua loads though, + # * replaces `-bundle` from the default flags with `-shared` + @when("platform=darwin") + def generate_luarocks_config(self, pkg, spec, prefix): + path = super().generate_luarocks_config(pkg, spec, prefix) + + with open(path, "a") as cfg: + cfg.write( + """ + + variables = { + LIBFLAG = "-shared -fPIC -undefined dynamic_lookup -all_load" + } + """ + ) + + return path + + # Builds searching for lpeg with darwin conventions can't find it without a dylib + # symlink, neovim is an example + @run_after("install", when="platform=darwin") + def create_dylib_link_and_fix_id(self): + lpeg_so = find(self.prefix, "lpeg.so") + assert len(lpeg_so) >= 1 + dylib_path = os.path.join(self.prefix.lib, "liblpeg.dylib") + symlink(lpeg_so[0], dylib_path) + # can't use spack.filesystem.fix_darwin_install_name for this, doesn't work + install_name_tool = which("install_name_tool", required=True) + install_name_tool("-id", dylib_path, dylib_path) diff --git a/var/spack/repos/builtin/packages/lua-luajit-openresty/package.py b/var/spack/repos/builtin/packages/lua-luajit-openresty/package.py index 7d39c701578336..1f8356270f2820 100644 --- a/var/spack/repos/builtin/packages/lua-luajit-openresty/package.py +++ b/var/spack/repos/builtin/packages/lua-luajit-openresty/package.py @@ -18,13 +18,13 @@ class LuaLuajitOpenresty(LuaImplPackage): license("MIT") version( - "2.1-20230410", sha256="77bbcbb24c3c78f51560017288f3118d995fe71240aa379f5818ff6b166712ff" + "2.1-20240626", sha256="1e53822a1105df216b9657ccb0293a152ac5afd875abc848453bfa353ca8181b" ) version( - "2.1-20220111", sha256="1ad2e34b111c802f9d0cdf019e986909123237a28c746b21295b63c9e785d9c3" + "2.1-20230410", sha256="77bbcbb24c3c78f51560017288f3118d995fe71240aa379f5818ff6b166712ff" ) version( - "2.1-20230410", sha256="77bbcbb24c3c78f51560017288f3118d995fe71240aa379f5818ff6b166712ff" + "2.1-20220111", sha256="1ad2e34b111c802f9d0cdf019e986909123237a28c746b21295b63c9e785d9c3" ) depends_on("c", type="build") # generated @@ -64,3 +64,11 @@ def edit(self, spec, prefix): # that unwinding symbols are not included by libc, this is necessary # on some platforms for the final link stage to work src_makefile.filter("^TARGET_LD = .*", f"TARGET_LD = {spack_cxx}") + + def setup_run_environment(self, env): + env.prepend_path( + "LUA_PATH", + os.path.join(self.spec.prefix, "share", f"luajit-{self.version[0:2]}", "?.lua"), + separator=";", + ) + super().setup_run_environment(env) diff --git a/var/spack/repos/builtin/packages/lua/package.py b/var/spack/repos/builtin/packages/lua/package.py index d27e6dafa9b2c2..683657882359f0 100644 --- a/var/spack/repos/builtin/packages/lua/package.py +++ b/var/spack/repos/builtin/packages/lua/package.py @@ -64,8 +64,8 @@ def lua_share_dir(self): resource( name="luarocks", - url="https://luarocks.github.io/luarocks/releases/" "luarocks-3.8.0.tar.gz", - sha256="56ab9b90f5acbc42eb7a94cf482e6c058a63e8a1effdf572b8b2a6323a06d923", + url="https://luarocks.github.io/luarocks/releases/luarocks-3.11.1.tar.gz", + sha256="c3fb3d960dffb2b2fe9de7e3cb004dc4d0b34bb3d342578af84f84325c669102", destination="luarocks", placement="luarocks", ) From 64f90c38be76399d1133be08254190fdefd06263 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Wed, 16 Oct 2024 09:09:52 +0200 Subject: [PATCH 17/28] unit-tests: oci/integration_test.py (#47006) Signed-off-by: Massimiliano Culpo --- lib/spack/spack/test/oci/integration_test.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/spack/spack/test/oci/integration_test.py b/lib/spack/spack/test/oci/integration_test.py index 85673e953aa148..98c1258cd2c8c1 100644 --- a/lib/spack/spack/test/oci/integration_test.py +++ b/lib/spack/spack/test/oci/integration_test.py @@ -69,8 +69,8 @@ def test_buildcache_tag(install_mockery, mock_fetch, mutable_mock_env_path): """Tests whether we can create an OCI image from a full environment with multiple roots.""" env("create", "test") with ev.read("test"): - install("--add", "libelf") - install("--add", "trivial-install-test-package") + install("--fake", "--add", "libelf") + install("--fake", "--add", "trivial-install-test-package") registry = InMemoryOCIRegistry("example.com") @@ -83,7 +83,7 @@ def test_buildcache_tag(install_mockery, mock_fetch, mutable_mock_env_path): name = ImageReference.from_string("example.com/image:full_env") with ev.read("test") as e: - specs = e.all_specs() + specs = [x for x in e.all_specs() if not x.external] manifest, config = get_manifest_and_config(name) @@ -100,7 +100,7 @@ def test_buildcache_tag(install_mockery, mock_fetch, mutable_mock_env_path): name = ImageReference.from_string("example.com/image:single_spec") manifest, config = get_manifest_and_config(name) - assert len(manifest["layers"]) == 1 + assert len(manifest["layers"]) == len([x for x in libelf.traverse() if not x.external]) def test_buildcache_push_with_base_image_command(mutable_database, tmpdir): @@ -347,6 +347,10 @@ def put_manifest(base_images, checksums, image_ref, tmpdir, extra_config, annota for s in mpileaks.traverse(): if s.name in without_manifest: continue + + if s.external: + continue + # This should not raise a 404. manifest, _ = get_manifest_and_config(image.with_tag(default_tag(s))) @@ -358,6 +362,10 @@ def put_manifest(base_images, checksums, image_ref, tmpdir, extra_config, annota for s in mpileaks.traverse(): if s.name in without_manifest: continue + + if s.external: + continue + expected_digests = { pkg_to_own_digest[t.name] for t in s.traverse(deptype=("link", "run"), root=True) From 8c70912b118ee65f073960b9e2f8a6bc95fae290 Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Wed, 16 Oct 2024 09:11:53 +0200 Subject: [PATCH 18/28] Update release documentation (#46991) --- lib/spack/docs/developer_guide.rst | 227 +++++++++++++--------------- lib/spack/docs/images/pr-commit.png | Bin 44592 -> 0 bytes lib/spack/docs/images/projects.png | Bin 69075 -> 0 bytes 3 files changed, 107 insertions(+), 120 deletions(-) delete mode 100644 lib/spack/docs/images/pr-commit.png delete mode 100644 lib/spack/docs/images/projects.png diff --git a/lib/spack/docs/developer_guide.rst b/lib/spack/docs/developer_guide.rst index 134f0f540f63c8..f538f75206644c 100644 --- a/lib/spack/docs/developer_guide.rst +++ b/lib/spack/docs/developer_guide.rst @@ -712,27 +712,27 @@ Release branches ^^^^^^^^^^^^^^^^ There are currently two types of Spack releases: :ref:`major releases -` (``0.17.0``, ``0.18.0``, etc.) and :ref:`point releases -` (``0.17.1``, ``0.17.2``, ``0.17.3``, etc.). Here is a +` (``0.21.0``, ``0.22.0``, etc.) and :ref:`patch releases +` (``0.22.1``, ``0.22.2``, ``0.22.3``, etc.). Here is a diagram of how Spack release branches work:: - o branch: develop (latest version, v0.19.0.dev0) + o branch: develop (latest version, v0.23.0.dev0) | o - | o branch: releases/v0.18, tag: v0.18.1 + | o branch: releases/v0.22, tag: v0.22.1 o | - | o tag: v0.18.0 + | o tag: v0.22.0 o | | o |/ o | o - | o branch: releases/v0.17, tag: v0.17.2 + | o branch: releases/v0.21, tag: v0.21.2 o | - | o tag: v0.17.1 + | o tag: v0.21.1 o | - | o tag: v0.17.0 + | o tag: v0.21.0 o | | o |/ @@ -743,8 +743,8 @@ requests target ``develop``. The ``develop`` branch will report that its version is that of the next **major** release with a ``.dev0`` suffix. Each Spack release series also has a corresponding branch, e.g. -``releases/v0.18`` has ``0.18.x`` versions of Spack, and -``releases/v0.17`` has ``0.17.x`` versions. A major release is the first +``releases/v0.22`` has ``v0.22.x`` versions of Spack, and +``releases/v0.21`` has ``v0.21.x`` versions. A major release is the first tagged version on a release branch. Minor releases are back-ported from develop onto release branches. This is typically done by cherry-picking bugfix commits off of ``develop``. @@ -774,27 +774,40 @@ for more details. Scheduling work for releases ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -We schedule work for releases by creating `GitHub projects -`_. At any time, there may be -several open release projects. For example, below are two releases (from -some past version of the page linked above): +We schedule work for **major releases** through `milestones +`_ and `GitHub Projects +`_, while **patch releases** use `labels +`_. -.. image:: images/projects.png +There is only one milestone open at a time. Its name corresponds to the next major version, for +example ``v0.23``. Important issues and pull requests should be assigned to this milestone by +core developers, so that they are not forgotten at the time of release. The milestone is closed +when the release is made, and a new milestone is created for the next major release. -This image shows one release in progress for ``0.15.1`` and another for -``0.16.0``. Each of these releases has a project board containing issues -and pull requests. GitHub shows a status bar with completed work in -green, work in progress in purple, and work not started yet in gray, so -it's fairly easy to see progress. +Bug reports in GitHub issues are automatically labelled ``bug`` and ``triage``. Spack developers +assign one of the labels ``impact-low``, ``impact-medium`` or ``impact-high``. This will make the +issue appear in the `Triaged bugs `_ project board. +Important issues should be assigned to the next milestone as well, so they appear at the top of +the project board. -Spack's project boards are not firm commitments so we move work between -releases frequently. If we need to make a release and some tasks are not -yet done, we will simply move them to the next minor or major release, rather -than delaying the release to complete them. +Spack's milestones are not firm commitments so we move work between releases frequently. If we +need to make a release and some tasks are not yet done, we will simply move them to the next major +release milestone, rather than delaying the release to complete them. -For more on using GitHub project boards, see `GitHub's documentation -`_. +^^^^^^^^^^^^^^^^^^^^^ +Backporting bug fixes +^^^^^^^^^^^^^^^^^^^^^ +When a bug is fixed in the ``develop`` branch, it is often necessary to backport the fix to one +(or more) of the ``release/vX.Y`` branches. Only the release manager is responsible for doing +backports, but Spack maintainers are responsible for labelling pull requests (and issues if no bug +fix is available yet) with ``vX.Y.Z`` labels. The label should correspond to the next patch version +that the bug fix should be backported to. + +Backports are done publicly by the release manager using a pull request named ``Backports vX.Y.Z``. +This pull request is opened from the ``backports/vX.Y.Z`` branch, targets the ``releases/vX.Y`` +branch and contains a (growing) list of cherry-picked commits from the ``develop`` branch. +Typically there are one or two backport pull requests open at any given time. .. _major-releases: @@ -802,25 +815,21 @@ For more on using GitHub project boards, see `GitHub's documentation Making major releases ^^^^^^^^^^^^^^^^^^^^^ -Assuming a project board has already been created and all required work -completed, the steps to make the major release are: - -#. Create two new project boards: +Assuming all required work from the milestone is completed, the steps to make the major release +are: - * One for the next major release - * One for the next point release +#. `Create a new milestone `_ for the next major + release. -#. Move any optional tasks that are not done to one of the new project boards. +#. `Create a new label `_ for the next patch release. - In general, small bugfixes should go to the next point release. Major - features, refactors, and changes that could affect concretization should - go in the next major release. +#. Move any optional tasks that are not done to the next milestone. #. Create a branch for the release, based on ``develop``: .. code-block:: console - $ git checkout -b releases/v0.15 develop + $ git checkout -b releases/v0.23 develop For a version ``vX.Y.Z``, the branch's name should be ``releases/vX.Y``. That is, you should create a ``releases/vX.Y`` @@ -856,8 +865,8 @@ completed, the steps to make the major release are: Create a pull request targeting the ``develop`` branch, bumping the major version in ``lib/spack/spack/__init__.py`` with a ``dev0`` release segment. - For instance when you have just released ``v0.15.0``, set the version - to ``(0, 16, 0, 'dev0')`` on ``develop``. + For instance when you have just released ``v0.23.0``, set the version + to ``(0, 24, 0, 'dev0')`` on ``develop``. #. Follow the steps in :ref:`publishing-releases`. @@ -866,82 +875,52 @@ completed, the steps to make the major release are: #. Follow the steps in :ref:`announcing-releases`. -.. _point-releases: +.. _patch-releases: ^^^^^^^^^^^^^^^^^^^^^ -Making point releases +Making patch releases ^^^^^^^^^^^^^^^^^^^^^ -Assuming a project board has already been created and all required work -completed, the steps to make the point release are: - -#. Create a new project board for the next point release. - -#. Move any optional tasks that are not done to the next project board. - -#. Check out the release branch (it should already exist). - - For the ``X.Y.Z`` release, the release branch is called ``releases/vX.Y``. - For ``v0.15.1``, you would check out ``releases/v0.15``: - - .. code-block:: console - - $ git checkout releases/v0.15 - -#. If a pull request to the release branch named ``Backports vX.Y.Z`` is not already - in the project, create it. This pull request ought to be created as early as - possible when working on a release project, so that we can build the release - commits incrementally, and identify potential conflicts at an early stage. - -#. Cherry-pick each pull request in the ``Done`` column of the release - project board onto the ``Backports vX.Y.Z`` pull request. - - This is **usually** fairly simple since we squash the commits from the - vast majority of pull requests. That means there is only one commit - per pull request to cherry-pick. For example, `this pull request - `_ has three commits, but - they were squashed into a single commit on merge. You can see the - commit that was created here: - - .. image:: images/pr-commit.png - - You can easily cherry pick it like this (assuming you already have the - release branch checked out): +To make the patch release process both efficient and transparent, we use a *backports pull request* +which contains cherry-picked commits from the ``develop`` branch. The majority of the work is to +cherry-pick the bug fixes, which ideally should be done as soon as they land on ``develop``: +this ensures cherry-picking happens in order, and makes conflicts easier to resolve since the +changes are fresh in the mind of the developer. - .. code-block:: console +The backports pull request is always titled ``Backports vX.Y.Z`` and is labelled ``backports``. It +is opened from a branch named ``backports/vX.Y.Z`` and targets the ``releases/vX.Y`` branch. - $ git cherry-pick 7e46da7 +Whenever a pull request labelled ``vX.Y.Z`` is merged, cherry-pick the associated squashed commit +on ``develop`` to the ``backports/vX.Y.Z`` branch. For pull requests that were rebased (or not +squashed), cherry-pick each associated commit individually. Never force push to the +``backports/vX.Y.Z`` branch. - For pull requests that were rebased (or not squashed), you'll need to - cherry-pick each associated commit individually. +.. warning:: - .. warning:: + Sometimes you may **still** get merge conflicts even if you have + cherry-picked all the commits in order. This generally means there + is some other intervening pull request that the one you're trying + to pick depends on. In these cases, you'll need to make a judgment + call regarding those pull requests. Consider the number of affected + files and/or the resulting differences. - It is important to cherry-pick commits in the order they happened, - otherwise you can get conflicts while cherry-picking. When - cherry-picking look at the merge date, - **not** the number of the pull request or the date it was opened. + 1. If the changes are small, you might just cherry-pick it. - Sometimes you may **still** get merge conflicts even if you have - cherry-picked all the commits in order. This generally means there - is some other intervening pull request that the one you're trying - to pick depends on. In these cases, you'll need to make a judgment - call regarding those pull requests. Consider the number of affected - files and or the resulting differences. + 2. If the changes are large, then you may decide that this fix is not + worth including in a patch release, in which case you should remove + the label from the pull request. Remember that large, manual backports + are seldom the right choice for a patch release. - 1. If the dependency changes are small, you might just cherry-pick it, - too. If you do this, add the task to the release board. +When all commits are cherry-picked in the ``backports/vX.Y.Z`` branch, make the patch +release as follows: - 2. If the changes are large, then you may decide that this fix is not - worth including in a point release, in which case you should remove - the task from the release project. +#. `Create a new label `_ ``vX.Y.{Z+1}`` for the next patch + release. - 3. You can always decide to manually back-port the fix to the release - branch if neither of the above options makes sense, but this can - require a lot of work. It's seldom the right choice. +#. Replace the label ``vX.Y.Z`` with ``vX.Y.{Z+1}`` for all PRs and issues that are not done. -#. When all the commits from the project board are cherry-picked into - the ``Backports vX.Y.Z`` pull request, you can push a commit to: +#. Manually push a single commit with commit message ``Set version to vX.Y.Z`` to the + ``backports/vX.Y.Z`` branch, that both bumps the Spack version number and updates the changelog: 1. Bump the version in ``lib/spack/spack/__init__.py``. 2. Update ``CHANGELOG.md`` with a list of the changes. @@ -950,20 +929,22 @@ completed, the steps to make the point release are: release branch. See `the changelog from 0.14.1 `_. -#. Merge the ``Backports vX.Y.Z`` PR with the **Rebase and merge** strategy. This - is needed to keep track in the release branch of all the commits that were - cherry-picked. - -#. Make sure CI passes on the release branch, including: +#. Make sure CI passes on the **backports pull request**, including: * Regular unit tests * Build tests * The E4S pipeline at `gitlab.spack.io `_ - If CI does not pass, you'll need to figure out why, and make changes - to the release branch until it does. You can make more commits, modify - or remove cherry-picked commits, or cherry-pick **more** from - ``develop`` to make this happen. +#. Merge the ``Backports vX.Y.Z`` PR with the **Rebase and merge** strategy. This + is needed to keep track in the release branch of all the commits that were + cherry-picked. + +#. Make sure CI passes on the last commit of the **release branch**. + +#. In the rare case you need to include additional commits in the patch release after the backports + PR is merged, it is best to delete the last commit ``Set version to vX.Y.Z`` from the release + branch with a single force push, open a new backports PR named ``Backports vX.Y.Z (2)``, and + repeat the process. Avoid repeated force pushes to the release branch. #. Follow the steps in :ref:`publishing-releases`. @@ -1038,25 +1019,31 @@ Updating `releases/latest` If the new release is the **highest** Spack release yet, you should also tag it as ``releases/latest``. For example, suppose the highest -release is currently ``0.15.3``: +release is currently ``0.22.3``: -* If you are releasing ``0.15.4`` or ``0.16.0``, then you should tag - it with ``releases/latest``, as these are higher than ``0.15.3``. +* If you are releasing ``0.22.4`` or ``0.23.0``, then you should tag + it with ``releases/latest``, as these are higher than ``0.22.3``. * If you are making a new release of an **older** major version of - Spack, e.g. ``0.14.4``, then you should not tag it as + Spack, e.g. ``0.21.4``, then you should not tag it as ``releases/latest`` (as there are newer major versions). -To tag ``releases/latest``, do this: +To do so, first fetch the latest tag created on GitHub, since you may not have it locally: + +.. code-block:: console + + $ git fetch --force git@github.com:spack/spack vX.Y.Z + +Then tag ``vX.Y.Z`` as ``releases/latest`` and push the individual tag to GitHub. .. code-block:: console - $ git checkout releases/vX.Y # vX.Y is the new release's branch - $ git tag --force releases/latest - $ git push --force --tags + $ git tag --force releases/latest vX.Y.Z + $ git push --force git@github.com:spack/spack releases/latest -The ``--force`` argument to ``git tag`` makes ``git`` overwrite the existing -``releases/latest`` tag with the new one. +The ``--force`` argument to ``git tag`` makes ``git`` overwrite the existing ``releases/latest`` +tag with the new one. Do **not** use the ``--tags`` flag when pushing, since this will push *all* +local tags. .. _announcing-releases: diff --git a/lib/spack/docs/images/pr-commit.png b/lib/spack/docs/images/pr-commit.png deleted file mode 100644 index a87c800ef5d282bea64c30d2d34ee9e9bdaf400b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44592 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

u6^`yDUZo`+E;5t^8#)ld?1D4sfsW#Lth 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 diff --git a/lib/spack/docs/images/projects.png b/lib/spack/docs/images/projects.png deleted file mode 100644 index bd2971ff625ddbe947bf78ec5a6b320c894b029b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69075 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 Date: Wed, 16 Oct 2024 09:12:14 +0200 Subject: [PATCH 19/28] Reduce the load on clingo-cffi CI job (#46982) The purpose of this CI job is to ensure that we can use a modern clingo to concretize specs, if e.g. it was installed in a virtual environment with pip. Since there is no need to re-test unrelated parts of Spack, reduce the number of tests we run to just concretize.py --- .github/workflows/unit_tests.yaml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/unit_tests.yaml b/.github/workflows/unit_tests.yaml index 47816e3e062aa0..124d77e0b5a549 100644 --- a/.github/workflows/unit_tests.yaml +++ b/.github/workflows/unit_tests.yaml @@ -154,26 +154,27 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 with: - python-version: '3.11' + python-version: '3.13' - name: Install System packages run: | sudo apt-get -y update - sudo apt-get -y install coreutils cvs gfortran graphviz gnupg2 mercurial ninja-build kcov + sudo apt-get -y install coreutils gfortran graphviz gnupg2 - name: Install Python packages run: | - pip install --upgrade pip setuptools pytest coverage[toml] pytest-cov clingo pytest-xdist + pip install --upgrade pip setuptools pytest coverage[toml] pytest-cov clingo pip install --upgrade flake8 "isort>=4.3.5" "mypy>=0.900" "click" "black" - - name: Setup git configuration - run: | - # Need this for the git tests to succeed. - git --version - . .github/workflows/bin/setup_git.sh - name: Run unit tests (full suite with coverage) env: COVERAGE: true COVERAGE_FILE: coverage/.coverage-clingo-cffi run: | - share/spack/qa/run-unit-tests + . share/spack/setup-env.sh + spack bootstrap disable spack-install + spack bootstrap disable github-actions-v0.4 + spack bootstrap disable github-actions-v0.5 + spack bootstrap status + spack solve zlib + spack unit-test --verbose --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml lib/spack/spack/test/concretize.py - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 with: name: coverage-clingo-cffi From db6a2523d93f4ac20f704bc9741925968d452218 Mon Sep 17 00:00:00 2001 From: Sam Grayson Date: Wed, 16 Oct 2024 05:16:31 -0600 Subject: [PATCH 20/28] py-flask-sqlalchemy: add v2.5.1 (#34999) * Fix py-parsl specification * Add older version of py-flask-sqlalchemy --- .../packages/py-flask-sqlalchemy/package.py | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/var/spack/repos/builtin/packages/py-flask-sqlalchemy/package.py b/var/spack/repos/builtin/packages/py-flask-sqlalchemy/package.py index 950351e578ca41..fd243f6332e275 100644 --- a/var/spack/repos/builtin/packages/py-flask-sqlalchemy/package.py +++ b/var/spack/repos/builtin/packages/py-flask-sqlalchemy/package.py @@ -18,10 +18,19 @@ class PyFlaskSqlalchemy(PythonPackage): license("BSD-3-Clause") + # If py-slqalchemy@1.4.18: is too restrictive, consider downgrading py-flask-sqlalchemy to @2. version("3.0.2", sha256="16199f5b3ddfb69e0df2f52ae4c76aedbfec823462349dabb21a1b2e0a2b65e9") - - # https://github.com/pallets-eco/flask-sqlalchemy/blob/3.0.2/pyproject.toml - depends_on("python@3.7:", type=("build", "run")) - depends_on("py-flask@2.2:", type=("build", "run")) - depends_on("py-sqlalchemy@1.4.18:", type=("build", "run")) - depends_on("py-pdm-pep517@1:", type="build") + version("2.5.1", sha256="2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912") + + with when("@3"): + # https://github.com/pallets-eco/flask-sqlalchemy/blob/3.0.2/pyproject.toml + depends_on("python@3.7:", type=("build", "run")) + depends_on("py-flask@2.2:", type=("build", "run")) + depends_on("py-sqlalchemy@1.4.18:", type=("build", "run")) + depends_on("py-pdm-pep517@1:", type="build") + + with when("@2"): + # https://github.com/pallets-eco/flask-sqlalchemy/blob/2.5.1/setup.py + depends_on("py-flask@0.10:", type=("build", "run")) + depends_on("py-sqlalchemy@0.8.0:", type=("build", "run")) + depends_on("py-setuptools", type="build") From cbdc07248f517e5d8f8e56f5e59359794bda6757 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Wed, 16 Oct 2024 15:02:52 +0200 Subject: [PATCH 21/28] unit-tests: install.py (#47007) Signed-off-by: Massimiliano Culpo --- lib/spack/spack/test/install.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py index efaa7cc17171b6..bcbe45bf3e5e40 100644 --- a/lib/spack/spack/test/install.py +++ b/lib/spack/spack/test/install.py @@ -353,21 +353,21 @@ def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdi Test that different specs with coinciding install prefixes will fail to install. """ - projections = {"projections": {"all": "all-specs-project-to-this-prefix"}} + projections = {"projections": {"all": "one-prefix-per-package-{name}"}} with spack.store.use_store(str(tmpdir), extra_data=projections): with spack.config.override("config:checksum", False): pkg_a = Spec("libelf@0.8.13").concretized().package pkg_b = Spec("libelf@0.8.12").concretized().package - PackageInstaller([pkg_a], explicit=True).install() + PackageInstaller([pkg_a], explicit=True, fake=True).install() with pytest.raises(InstallError, match="Install prefix collision"): - PackageInstaller([pkg_b], explicit=True).install() + PackageInstaller([pkg_b], explicit=True, fake=True).install() def test_store(install_mockery, mock_fetch): spec = Spec("cmake-client").concretized() pkg = spec.package - PackageInstaller([pkg], explicit=True).install() + PackageInstaller([pkg], fake=True, explicit=True).install() @pytest.mark.disable_clean_stage_check From b573ec39201b8c66cdc888ee2912ea7ade94fe18 Mon Sep 17 00:00:00 2001 From: AMD Toolchain Support <73240730+amd-toolchain-support@users.noreply.github.com> Date: Wed, 16 Oct 2024 20:18:24 +0530 Subject: [PATCH 22/28] Update CP2K recipe for AOCC compiler (#46985) --- var/spack/repos/builtin/packages/cp2k/package.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py index 306cb55813ea0f..0a590013b1b373 100644 --- a/var/spack/repos/builtin/packages/cp2k/package.py +++ b/var/spack/repos/builtin/packages/cp2k/package.py @@ -188,9 +188,10 @@ class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage): with when("+libint"): depends_on("pkgconfig", type="build", when="@7.0:") for lmax in HFX_LMAX_RANGE: + depends_on(f"libint@2.6.0:+fortran tune=cp2k-lmax-{lmax}", when=f"@7.0: lmax={lmax}") + # AOCC only works with libint@2.6.0 depends_on( - "libint@2.6.0:+fortran tune=cp2k-lmax-{0}".format(lmax), - when="@7.0: lmax={0}".format(lmax), + f"libint@=2.6.0+fortran tune=cp2k-lmax-{lmax}", when=f"@7.0: lmax={lmax} %aocc" ) with when("+libxc"): @@ -305,6 +306,9 @@ class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage): depends_on("hipblas") depends_on("hipfft") + # The CMake build system and AOCC are not compatible as of AOCC 5 + requires("build_system=makefile", when="%aocc") + # CP2K needs compiler specific compilation flags, e.g. optflags conflicts("%apple-clang") conflicts("%clang") @@ -827,6 +831,12 @@ def fflags(var, lst): if spec.satisfies("%intel"): mkf.write(fflags("LDFLAGS_C", ldflags + ["-nofor-main"])) + if spec.satisfies("%aocc@5:"): + # ensure C based applications can be build properly + mkf.write(fflags("LDFLAGS_C", ldflags + ["-fno-fortran-main"])) + # This flag is required for the correct runtime behaviour of the code with aocc@5.0 + mkf.write(fflags("FCFLAGS", fcflags + ["-mllvm -enable-newgvn=true"])) + mkf.write("# CP2K-specific flags\n\n") mkf.write("GPUVER = {0}\n".format(gpuver)) mkf.write("DATA_DIR = {0}\n".format(prefix.share.data)) From 80b9807e1037e1d9e5a575b8dff9cfb5e5cf79ad Mon Sep 17 00:00:00 2001 From: Huston Rogers Date: Wed, 16 Oct 2024 11:03:10 -0500 Subject: [PATCH 23/28] Added miniconda update (#46997) Co-authored-by: James H. Rogers --- .../builtin/packages/miniconda3/package.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/var/spack/repos/builtin/packages/miniconda3/package.py b/var/spack/repos/builtin/packages/miniconda3/package.py index 4fdbf90436ad65..d620ce47c83c5a 100644 --- a/var/spack/repos/builtin/packages/miniconda3/package.py +++ b/var/spack/repos/builtin/packages/miniconda3/package.py @@ -10,6 +10,24 @@ from spack.util.environment import EnvironmentModifications _versions = { + "24.7.1": { + "Linux-x86_64": ( + "33442cd3813df33dcbb4a932b938ee95398be98344dff4c30f7e757cd2110e4f", + "https://repo.anaconda.com/miniconda/Miniconda3-py312_24.7.1-0-Linux-x86_64.sh", + ) + }, + "24.5.0": { + "Linux-x86_64": ( + "4b3b3b1b99215e85fd73fb2c2d7ebf318ac942a457072de62d885056556eb83e", + "https://repo.anaconda.com/miniconda/Miniconda3-py312_24.5.0-0-Linux-x86_64.sh", + ) + }, + "24.4.0": { + "Linux-x86_64": ( + "b6597785e6b071f1ca69cf7be6d0161015b96340b9a9e132215d5713408c3a7c", + "https://repo.anaconda.com/miniconda/Miniconda3-py312_24.4.0-0-Linux-x86_64.sh", + ) + }, "24.3.0": { "Linux-x86_64": ( "96a44849ff17e960eeb8877ecd9055246381c4d4f2d031263b63fa7e2e930af1", From fb53d31d09e2d8229ae529f0561207da2bd68bf3 Mon Sep 17 00:00:00 2001 From: eugeneswalker <38933153+eugeneswalker@users.noreply.github.com> Date: Wed, 16 Oct 2024 09:11:26 -0700 Subject: [PATCH 24/28] ci: use ghcr.io images instead of dockerhub hosted (#46830) --- share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml | 12 ++++++------ .../stacks/developer-tools-manylinux2014/spack.yaml | 2 +- .../stacks/e4s-neoverse-v2/spack.yaml | 2 +- .../stacks/e4s-neoverse_v1/spack.yaml | 2 +- .../cloud_pipelines/stacks/e4s-oneapi/spack.yaml | 2 +- .../stacks/e4s-rocm-external/spack.yaml | 2 +- .../gitlab/cloud_pipelines/stacks/e4s/spack.yaml | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml b/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml index dee82226cde6e3..bdd87a974410b9 100644 --- a/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml +++ b/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml @@ -308,7 +308,7 @@ default: e4s-generate: extends: [ ".e4s", ".generate-x86_64"] - image: ecpe4s/ubuntu22.04-runner-amd64-gcc-11.4:2024.03.01 + image: ghcr.io/spack/spack/ubuntu22.04-runner-amd64-gcc-11.4:2024.03.01 e4s-build: extends: [ ".e4s", ".build" ] @@ -331,7 +331,7 @@ e4s-build: e4s-neoverse-v2-generate: extends: [ ".e4s-neoverse-v2", ".generate-neoverse-v2" ] - image: ecpe4s/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 + image: ghcr.io/spack/spack/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 e4s-neoverse-v2-build: extends: [ ".e4s-neoverse-v2", ".build" ] @@ -354,7 +354,7 @@ e4s-neoverse-v2-build: e4s-neoverse_v1-generate: extends: [ ".e4s-neoverse_v1", ".generate-neoverse_v1" ] - image: ecpe4s/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 + image: ghcr.io/spack/spack/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 e4s-neoverse_v1-build: extends: [ ".e4s-neoverse_v1", ".build" ] @@ -377,7 +377,7 @@ e4s-neoverse_v1-build: e4s-rocm-external-generate: extends: [ ".e4s-rocm-external", ".generate-x86_64"] - image: ecpe4s/ubuntu22.04-runner-amd64-gcc-11.4-rocm6.2.0:2024.09.11 + image: ghcr.io/spack/spack/ubuntu22.04-runner-amd64-gcc-11.4-rocm6.2.0:2024.09.11 e4s-rocm-external-build: extends: [ ".e4s-rocm-external", ".build" ] @@ -423,7 +423,7 @@ e4s-rocm-external-build: e4s-oneapi-generate: extends: [ ".e4s-oneapi", ".generate-x86_64"] - image: ecpe4s/ubuntu22.04-runner-amd64-oneapi-2024.2:2024.09.06 + image: ghcr.io/spack/spack/ubuntu22.04-runner-amd64-oneapi-2024.2:2024.09.06 e4s-oneapi-build: extends: [ ".e4s-oneapi", ".build" ] @@ -495,7 +495,7 @@ build_systems-build: developer-tools-manylinux2014-generate: extends: [ ".developer-tools-manylinux2014", ".generate-x86_64"] - image: ecpe4s/manylinux2014:2024.03.28 + image: ghcr.io/spack/spack/manylinux2014:2024.03.28 developer-tools-manylinux2014-build: extends: [ ".developer-tools-manylinux2014", ".build" ] diff --git a/share/spack/gitlab/cloud_pipelines/stacks/developer-tools-manylinux2014/spack.yaml b/share/spack/gitlab/cloud_pipelines/stacks/developer-tools-manylinux2014/spack.yaml index 863f4a339582e8..97f408080fe7b9 100644 --- a/share/spack/gitlab/cloud_pipelines/stacks/developer-tools-manylinux2014/spack.yaml +++ b/share/spack/gitlab/cloud_pipelines/stacks/developer-tools-manylinux2014/spack.yaml @@ -93,7 +93,7 @@ spack: ci: pipeline-gen: - build-job: - image: ecpe4s/manylinux2014:2024.03.28 + image: ghcr.io/spack/spack/manylinux2014:2024.03.28 cdash: build-group: Developer Tools Manylinux2014 diff --git a/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse-v2/spack.yaml b/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse-v2/spack.yaml index a0b5cec5b6966b..531b02663d474c 100644 --- a/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse-v2/spack.yaml +++ b/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse-v2/spack.yaml @@ -241,7 +241,7 @@ spack: ci: pipeline-gen: - build-job: - image: ecpe4s/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 + image: ghcr.io/spack/spack/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 cdash: build-group: E4S ARM Neoverse V2 diff --git a/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse_v1/spack.yaml b/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse_v1/spack.yaml index 0b5de6cf163d65..bc47085c8dd7ba 100644 --- a/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse_v1/spack.yaml +++ b/share/spack/gitlab/cloud_pipelines/stacks/e4s-neoverse_v1/spack.yaml @@ -362,7 +362,7 @@ spack: ci: pipeline-gen: - build-job: - image: ecpe4s/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 + image: ghcr.io/spack/spack/ubuntu22.04-runner-arm64-gcc-11.4:2024.03.01 cdash: build-group: E4S ARM Neoverse V1 diff --git a/share/spack/gitlab/cloud_pipelines/stacks/e4s-oneapi/spack.yaml b/share/spack/gitlab/cloud_pipelines/stacks/e4s-oneapi/spack.yaml index 112afaaff46db6..4cc86363881b0b 100644 --- a/share/spack/gitlab/cloud_pipelines/stacks/e4s-oneapi/spack.yaml +++ b/share/spack/gitlab/cloud_pipelines/stacks/e4s-oneapi/spack.yaml @@ -242,7 +242,7 @@ spack: ci: pipeline-gen: - build-job: - image: ecpe4s/ubuntu22.04-runner-amd64-oneapi-2024.2:2024.09.06 + image: ghcr.io/spack/spack/ubuntu22.04-runner-amd64-oneapi-2024.2:2024.09.06 cdash: build-group: E4S OneAPI diff --git a/share/spack/gitlab/cloud_pipelines/stacks/e4s-rocm-external/spack.yaml b/share/spack/gitlab/cloud_pipelines/stacks/e4s-rocm-external/spack.yaml index f3391b7337ad72..43e792d52d6601 100644 --- a/share/spack/gitlab/cloud_pipelines/stacks/e4s-rocm-external/spack.yaml +++ b/share/spack/gitlab/cloud_pipelines/stacks/e4s-rocm-external/spack.yaml @@ -302,7 +302,7 @@ spack: ci: pipeline-gen: - build-job: - image: ecpe4s/ubuntu22.04-runner-amd64-gcc-11.4-rocm6.2.0:2024.09.11 + image: ghcr.io/spack/spack/ubuntu22.04-runner-amd64-gcc-11.4-rocm6.2.0:2024.09.11 cdash: build-group: E4S ROCm External diff --git a/share/spack/gitlab/cloud_pipelines/stacks/e4s/spack.yaml b/share/spack/gitlab/cloud_pipelines/stacks/e4s/spack.yaml index c4b870758ebbd8..8928db97ab9a84 100644 --- a/share/spack/gitlab/cloud_pipelines/stacks/e4s/spack.yaml +++ b/share/spack/gitlab/cloud_pipelines/stacks/e4s/spack.yaml @@ -376,7 +376,7 @@ spack: ci: pipeline-gen: - build-job: - image: ecpe4s/ubuntu22.04-runner-amd64-gcc-11.4:2024.03.01 + image: ghcr.io/spack/spack/ubuntu22.04-runner-amd64-gcc-11.4:2024.03.01 cdash: build-group: E4S From 49489a48151f37b285766be52197820093732f33 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Wed, 16 Oct 2024 18:35:30 +0200 Subject: [PATCH 25/28] py-pillow: add v11.0.0 (#47010) --- .../builtin/packages/py-pillow/package.py | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/var/spack/repos/builtin/packages/py-pillow/package.py b/var/spack/repos/builtin/packages/py-pillow/package.py index 7eff0630dba655..1e0e5374200cfd 100644 --- a/var/spack/repos/builtin/packages/py-pillow/package.py +++ b/var/spack/repos/builtin/packages/py-pillow/package.py @@ -9,17 +9,18 @@ class PyPillowBase(PythonPackage): """Base class for Pillow and its fork Pillow-SIMD.""" - maintainers("adamjstewart") license("HPND") + maintainers("adamjstewart") provides("pil") # These defaults correspond to Pillow defaults # https://pillow.readthedocs.io/en/stable/installation/building-from-source.html - VARIANTS_IN_SETUP_CFG = ( + VARIANTS = ( "zlib", "jpeg", "tiff", "freetype", + "raqm", "lcms", "webp", "webpmux", @@ -31,18 +32,19 @@ class PyPillowBase(PythonPackage): variant("jpeg", default=True, description="JPEG functionality") variant("tiff", default=False, description="Compressed TIFF functionality") variant("freetype", default=False, description="Type related services") + variant("raqm", when="@8.2:+freetype", default=False, description="RAQM support") variant("lcms", default=False, description="Color management") variant("webp", default=False, description="WebP format") - variant("webpmux", when="+webp", default=False, description="WebP metadata") + variant("webpmux", when="@:10+webp", default=False, description="WebP metadata") variant("jpeg2000", default=False, description="JPEG 2000 functionality") variant("imagequant", when="@3.3:", default=False, description="Improved color quantization") variant("xcb", when="@7.1:", default=False, description="X11 screengrab support") - variant("raqm", when="@8.2:", default=False, description="RAQM support") # Required dependencies # https://pillow.readthedocs.io/en/stable/installation/python-support.html with default_args(type=("build", "link", "run")): - depends_on("python@3.8:3.13", when="@10.4:") + depends_on("python@3.9:3.13", when="@11:") + depends_on("python@3.8:3.13", when="@10.4") depends_on("python@3.8:3.12", when="@10.1:10.3") depends_on("python@3.8:3.11", when="@10.0") depends_on("python@3.7:3.11", when="@9.3:9.5") @@ -54,6 +56,7 @@ class PyPillowBase(PythonPackage): # pyproject.toml with default_args(type="build"): + depends_on("py-pip@22.1:", when="@10:") depends_on("py-setuptools@67.8:", when="@10:") depends_on("py-setuptools") @@ -63,21 +66,28 @@ class PyPillowBase(PythonPackage): depends_on("jpeg", when="+jpeg") depends_on("libtiff", when="+tiff") depends_on("freetype", when="+freetype") + depends_on("libraqm", when="+raqm") depends_on("lcms@2:", when="+lcms") depends_on("libwebp", when="+webp") depends_on("libwebp+libwebpmux+libwebpdemux", when="+webpmux") depends_on("openjpeg", when="+jpeg2000") depends_on("libimagequant", when="+imagequant") depends_on("libxcb", when="+xcb") - depends_on("libraqm", when="+raqm") - # Conflicting options - conflicts("+raqm", when="~freetype") + @when("@10:") + def config_settings(self, spec, prefix): + settings = {"parallel": make_jobs} - def patch(self): - """Patch setup.py to provide library and include directories - for dependencies.""" + for variant in self.VARIANTS: + if spec.satisfies(f"+{variant}"): + settings[variant] = "enable" + elif spec.satisfies(f"~{variant}"): + settings[variant] = "disable" + return settings + + def patch(self): + """Patch setup.py to provide library and include directories for dependencies.""" library_dirs = [] include_dirs = [] for dep in self.spec.dependencies(deptype="link"): @@ -86,21 +96,40 @@ def patch(self): include_dirs.extend(query.headers.directories) setup = FileFilter("setup.py") - setup.filter("library_dirs = []", "library_dirs = {0}".format(library_dirs), string=True) - setup.filter("include_dirs = []", "include_dirs = {0}".format(include_dirs), string=True) + if self.version >= Version("11"): + setup.filter( + "library_dirs: list[str] = []", + "library_dirs = {0}".format(library_dirs), + string=True, + ) + setup.filter( + "include_dirs: list[str] = []", + "include_dirs = {0}".format(include_dirs), + string=True, + ) + else: + setup.filter( + "library_dirs = []", "library_dirs = {0}".format(library_dirs), string=True + ) + setup.filter( + "include_dirs = []", "include_dirs = {0}".format(include_dirs), string=True + ) + + if self.spec.satisfies("@:9"): - def variant_to_cfg(variant): - able = "enable" if "+" + variant in self.spec else "disable" - return "{0}_{1}=1\n".format(able, variant) + def variant_to_cfg(variant): + able = "enable" if "+" + variant in self.spec else "disable" + return "{0}_{1}=1\n".format(able, variant) - with open("setup.cfg", "a") as setup: - setup.write("[build_ext]\n") - for variant in self.VARIANTS_IN_SETUP_CFG: - setup.write(variant_to_cfg(variant)) + with open("setup.cfg", "a") as setup: + setup.write("[build_ext]\n") + for variant in self.VARIANTS: + setup.write(variant_to_cfg(variant)) - setup.write("rpath={0}\n".format(":".join(self.rpath))) - setup.write("[install]\n") + setup.write("rpath={0}\n".format(":".join(self.rpath))) + setup.write("[install]\n") + @when("@:9") def setup_build_environment(self, env): env.set("MAX_CONCURRENCY", make_jobs) @@ -114,6 +143,7 @@ class PyPillow(PyPillowBase): homepage = "https://python-pillow.org/" pypi = "pillow/pillow-10.2.0.tar.gz" + version("11.0.0", sha256="72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739") version("10.4.0", sha256="166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06") version("10.3.0", sha256="9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d") version("10.2.0", sha256="e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e") @@ -135,9 +165,10 @@ class PyPillow(PyPillowBase): version("6.2.2", sha256="db9ff0c251ed066d367f53b64827cc9e18ccea001b986d08c265e53625dab950") version("6.2.1", sha256="bf4e972a88f8841d8fdc6db1a75e0f8d763e66e3754b03006cbc3854d89f1cb1") - depends_on("c", type="build") # generated + depends_on("c", type="build") for ver in [ + "11.0.0", "10.4.0", "10.3.0", "10.2.0", From 4ff07c3918ec6db9fc910a5730847e48868fd318 Mon Sep 17 00:00:00 2001 From: Tuomas Koskela Date: Wed, 16 Oct 2024 18:10:12 +0100 Subject: [PATCH 26/28] purify: new package (#46839) Co-authored-by: Bernhard Kaindl --- .../repos/builtin/packages/purify/package.py | 73 +++++++++++++++++++ .../repos/builtin/packages/sopt/package.py | 3 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 var/spack/repos/builtin/packages/purify/package.py diff --git a/var/spack/repos/builtin/packages/purify/package.py b/var/spack/repos/builtin/packages/purify/package.py new file mode 100644 index 00000000000000..3a2fdc7c7548ad --- /dev/null +++ b/var/spack/repos/builtin/packages/purify/package.py @@ -0,0 +1,73 @@ +# Copyright 2013-2024 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) + +from spack.package import * + + +class Purify(CMakePackage): + """PURIFY is an open-source collection of routines written in C++ available under the + license below. It implements different tools and high-level to perform radio interferometric + imaging, i.e. to recover images from the Fourier measurements taken by radio interferometric + telescopes. + """ + + homepage = "https://astro-informatics.github.io/purify/" + url = "https://github.com/astro-informatics/purify/archive/refs/tags/v4.2.0.tar.gz" + git = "https://github.com/astro-informatics/purify" + + maintainers("tkoskela", "mmcleod89", "20DM") + license("GPL-2.0") + + version("4.2.0", sha256="4d674007efc727628839fb6c8864e74f22adb39ee6405d3dab273f65b31b37e6") + + variant("tests", default=True, description="Build tests") + variant("openmp", default=True, description="Enable multithreading with OpenMP") + variant("mpi", default=True, description="Enable parallelisation with MPI") + variant("benchmarks", default=False, description="Build benchmarks") + variant("docs", default=False, description="Enable multithreading with OpenMP") + variant("coverage", default=False, description="Enable code coverage") + + depends_on("cmake@3") + depends_on("eigen@3.4:3") + depends_on("libtiff@4.7:") + depends_on("fftw-api") + depends_on("yaml-cpp@0.7:") + depends_on("boost@1.82+system+filesystem") + depends_on("cfitsio@4") + depends_on("cubature@1") + depends_on("sopt~mpi", when="~mpi") + depends_on("sopt+mpi", when="+mpi") + depends_on("sopt~openmp", when="~openmp") + depends_on("sopt+openmp", when="+openmp") + depends_on("catch2@3.4:3", when="+tests") + depends_on("mpi", when="+mpi") + depends_on("benchmark@1.8~performance_counters", when="+benchmarks") + depends_on("doxygen@1.9:1.12+graphviz", when="+docs") + + def cmake_args(self): + args = [ + self.define_from_variant("docs", "docs"), + self.define_from_variant("tests", "tests"), + self.define_from_variant("benchmarks", "benchmarks"), + self.define_from_variant("openmp", "openmp"), + self.define_from_variant("dompi", "mpi"), + self.define_from_variant("coverage", "coverage"), + ] + return args + + def setup_run_environment(self, env): + if "+tests" in self.spec: + env.prepend_path("PATH", self.spec.prefix.tests) + if "+benchmarks" in self.spec: + env.prepend_path("PATH", join_path(self.spec.prefix, "benchmarks")) + + def install(self, spec, prefix): + with working_dir(self.build_directory): + make("install") + if "+tests" in spec: + install_tree("cpp/tests", spec.prefix.tests) + install_tree("data", join_path(spec.prefix, "data")) + if "+benchmarks" in spec: + install_tree("cpp/benchmarks", join_path(spec.prefix, "benchmarks")) diff --git a/var/spack/repos/builtin/packages/sopt/package.py b/var/spack/repos/builtin/packages/sopt/package.py index a71731212f430f..754cf8b0a32b84 100644 --- a/var/spack/repos/builtin/packages/sopt/package.py +++ b/var/spack/repos/builtin/packages/sopt/package.py @@ -33,11 +33,12 @@ class Sopt(CMakePackage): depends_on("cmake@3") depends_on("eigen@3.4") - depends_on("libtiff@4") + depends_on("libtiff@4.7:") depends_on("mpi", when="+mpi") depends_on("catch2@3.4:3", when="+tests") depends_on("benchmark@1.8~performance_counters", when="+benchmarks") depends_on("onnx@1.16:", when="+onnxrt") + depends_on("py-onnxruntime@1.17.1:", when="+onnxrt") depends_on("doxygen@1.8:1.12+graphviz", when="+docs") patch( From 5611523bafba56017a80619cdc948b84fe15e030 Mon Sep 17 00:00:00 2001 From: Chris Green Date: Wed, 16 Oct 2024 12:18:46 -0500 Subject: [PATCH 27/28] `ftgl`: Handle char/unsigned char API change with the update to freetype@2.13.3 (#47003) * [ftgl] Restrict GCC 14+ patch to apply only to GCC 14+ The patch added by #46927 should only be applied where it is needed: with GCC 11 it causes a compilation failure where none previously existed. * Fix the contraint for applying unsiged char patch to ^freetype@2.13.3: --------- Co-authored-by: Bernhard Kaindl --- .../repos/builtin/packages/ftgl/package.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/var/spack/repos/builtin/packages/ftgl/package.py b/var/spack/repos/builtin/packages/ftgl/package.py index 202aba4fd1df12..3798f8457db3be 100644 --- a/var/spack/repos/builtin/packages/ftgl/package.py +++ b/var/spack/repos/builtin/packages/ftgl/package.py @@ -18,15 +18,12 @@ class Ftgl(CMakePackage): version("2.4.0", commit="483639219095ad080538e07ceb5996de901d4e74") version("2.3.1", commit="3c0fdf367824b6381f29df3d8b4590240db62ab7") - depends_on("c", type="build") # generated - depends_on("cxx", type="build") # generated + depends_on("c", type="build") + depends_on("cxx", type="build") - # FIXME: Doc generation is broken in upstream build system - # variant('doc', default=False, description='Build the documentation') variant("shared", default=True, description="Build as a shared library") depends_on("cmake@2.8:", type="build") - # depends_on('doxygen', type='build', when='+doc') -- FIXME, see above depends_on("pkgconfig", type="build") depends_on("gl") depends_on("glu") @@ -34,16 +31,24 @@ class Ftgl(CMakePackage): # Fix oversight in CMakeLists patch("remove-ftlibrary-from-sources.diff", when="@:2.4.0") - # Fix gcc14 compilation error due to type mismatch in FTContour + + # As reported by Khem Raj in + # https://github.com/kraj/ftgl/commit/37ed7d606a0dfecdcb4ab0c26d1b0132cd96d5fa + # freetype 2.13.3 changed the type of many external chars to unsigned char! patch( "https://patch-diff.githubusercontent.com/raw/frankheckenbach/ftgl/pull/20.patch?full_index=1", sha256="e2a0810fbf68403931bef4fbfda22e010e01421c92eeaa45f62e4e47f2381ebd", - when="@2.4.0", + when="^freetype@2.13.3:", ) def cmake_args(self): spec = self.spec args = ["-DBUILD_SHARED_LIBS={0}".format(spec.satisfies("+shared"))] + + # To not fail the build for 'char/unsigned char' conversion errors, + # downgrade them to warnings in general to not fail the build: + args.append("-DCMAKE_CXX_FLAGS=-fpermissive") + if "darwin" in self.spec.architecture: args.append("-DCMAKE_MACOSX_RPATH=ON") return args From e1ea9e12a651e8d224c1ed30331f6dbb3f3dbc9f Mon Sep 17 00:00:00 2001 From: AMD Toolchain Support <73240730+amd-toolchain-support@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:55:51 +0530 Subject: [PATCH 28/28] extrae: Add single mpi lib variant (#46918) Extrae normally separates the C and MPI fortran interception libs, but for mixed C/Fortran applications a combined lib is needed. Co-authored-by: fpanichi Co-authored-by: Bernhard Kaindl --- var/spack/repos/builtin/packages/extrae/package.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/var/spack/repos/builtin/packages/extrae/package.py b/var/spack/repos/builtin/packages/extrae/package.py index 299f58621431a5..c5e10097d4c8fd 100644 --- a/var/spack/repos/builtin/packages/extrae/package.py +++ b/var/spack/repos/builtin/packages/extrae/package.py @@ -92,6 +92,12 @@ class Extrae(AutotoolsPackage): depends_on("cuda", when="+cupti") conflicts("+cupti", when="~cuda", msg="CUPTI requires CUDA") + variant( + "single-mpi-lib", + default=False, + description="Enable single MPI instrumentation library that supports both Fortran and C", + ) + def configure_args(self): spec = self.spec if spec.satisfies("^[virtuals=mpi] intel-oneapi-mpi"): @@ -137,6 +143,8 @@ def configure_args(self): make.add_default_arg("CXXFLAGS=%s" % self.compiler.cxx11_flag) args.append("CXXFLAGS=%s" % self.compiler.cxx11_flag) + args.extend(self.enable_or_disable("single-mpi-lib")) + return args def flag_handler(self, name, flags):