Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
589e70e
Fix variant propagation with exception to spec
RikkiButler20 Jun 21, 2023
d1c9054
Add test for all unify options in env
RikkiButler20 Jun 26, 2023
c4247ee
Make sure variants are propagated w/o using path
RikkiButler20 Jun 28, 2023
285944c
Remove unnecessary additions to tests
RikkiButler20 Jun 28, 2023
be60ed8
Propagate when concretizing separately
RikkiButler20 Jul 17, 2023
39199ba
[@spackbot] updating style on behalf of RikkiButler20
RikkiButler20 Jul 17, 2023
31dbf82
Create propagation namedtuple
RikkiButler20 Jul 18, 2023
4d6e7f1
[@spackbot] updating style on behalf of RikkiButler20
RikkiButler20 Jul 18, 2023
79c3066
Only propagate the specified variant
RikkiButler20 Aug 17, 2023
b96a16b
Propagation to work with new concretizer
RikkiButler20 Aug 24, 2023
a6f7b4f
Test that only specified variant propagates
RikkiButler20 Aug 28, 2023
328f7ee
Remove extra spaces
RikkiButler20 Aug 29, 2023
4e00cc0
Remove unnneeded file
RikkiButler20 Sep 6, 2023
9a116a6
Test should only run if using clingo
RikkiButler20 Oct 5, 2023
2ed52ce
Create new mock packages
RikkiButler20 Oct 5, 2023
95a5558
Update lib/spack/spack/test/concretize.py
RikkiButler20 Oct 5, 2023
ea8dad7
Revert AbstractVariant change
RikkiButler20 Oct 9, 2023
5a6b22d
ci: pull E4S images from github instead of dockerhub (#40307)
scottwittenburg Oct 4, 2023
981f9ec
Improve build isolation in PythonPipBuilder (#40224)
haampie Oct 4, 2023
ba88655
exago: add and logging variant. (#40188)
Oct 5, 2023
fc2eb6a
cray rhel: disable due to runner issues (#40324)
haampie Oct 5, 2023
906ef36
whizard: Make sure to detect LCIO if requested (#40316)
tmadlener Oct 5, 2023
7830144
Revert "cray rhel: disable due to runner issues (#40324)" (#40335)
eugeneswalker Oct 5, 2023
ff53810
Make "minimal" the default duplicate strategy (#39621)
alalazo Oct 6, 2023
8819652
py-setuptools: sdist + rpath patch backport (#40205)
haampie Oct 8, 2023
fb90a20
py-jupyter-packaging: remove duplicate packages (#38671)
adamjstewart Oct 10, 2023
69062c2
spack buildcache: fix a typo in a function call (#40446)
alalazo Oct 11, 2023
8d20b18
build(deps): bump mypy from 1.5.1 to 1.6.0 in /lib/spack/docs (#40424)
dependabot[bot] Oct 11, 2023
e2d8a49
clingo: fix build with Python 3.12 (#40154)
haampie Oct 12, 2023
a21a685
Add mpi_f08 variant to CP2K (#40574)
RMeli Oct 17, 2023
96ae941
Allow / in GitVersion (#39398)
scheibelp Oct 17, 2023
409015f
ASP-based solver: single Spec instance per dag hash (#39590)
alalazo Oct 19, 2023
0263579
gitlab ci: Rework how mirrors are configured (#39939)
scottwittenburg Oct 19, 2023
e1b5ef8
Improve setup build / run / test environment (#35737)
haampie Oct 19, 2023
157b1e7
gromacs +cp2k: build in CI (#40494)
haampie Oct 20, 2023
8bb32b5
concretize separately: show concretization time per spec as they conc…
haampie Oct 20, 2023
04204a1
Add Score-P 8.3 and dependencies (#40478)
wrwilliams Oct 22, 2023
cbc8df4
libtheora: fix GitLab patch (#40657)
michaelkuhn Oct 23, 2023
a303148
ci: don't put compilers in config (#40700)
haampie Oct 25, 2023
034ca1b
PyTorch: patch breakpad dependency (#40648)
adamjstewart Oct 25, 2023
f70e10e
Paraview 5.12 prep (#40527)
mathstuf Oct 25, 2023
aca88ee
modules: hide implicit modulefiles (#36619)
xdelaruelle Oct 26, 2023
a3d4bf1
spack checksum [email protected], use as version filter (#39694)
haampie Oct 26, 2023
4598980
Update spack package for [email protected] release (#40614)
ryandanehy Oct 26, 2023
8badda1
ci: spack compiler find should list extra config scopes (#40727)
haampie Oct 27, 2023
30b3ca9
OCI buildcache (#38358)
haampie Oct 27, 2023
00c8d3a
ASP-based solver: avoid cycles in clingo using hidden directive (#40720)
alalazo Oct 30, 2023
6d46cab
py-pandas: add v2.1.2 (#40734)
adamjstewart Oct 30, 2023
82d912e
linaro-forge: add v23.0.4 (#40772)
RichardBuntLinaro Oct 30, 2023
a9edc5b
ci: print colored specs in concretization progress (#40711)
haampie Oct 30, 2023
478e3e8
squashfuse: add version 0.5.0 (#40775)
aweits Oct 30, 2023
a75cd94
spack checksum: improve signature (#40800)
haampie Oct 31, 2023
3408b4a
Merge upstream
RikkiButler20 Nov 21, 2023
0077783
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Jan 11, 2024
f9196ec
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Jan 25, 2024
cad19a6
Fix conflict
RikkiButler20 Jan 30, 2024
a0800ae
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Feb 7, 2024
5edec1a
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Feb 16, 2024
671c053
Remove PropagateValue
RikkiButler20 Feb 16, 2024
8f187ce
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Feb 22, 2024
876c33a
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Feb 26, 2024
60fce34
Merge upstream
RikkiButler20 Mar 14, 2024
54c6009
Merge conflict
RikkiButler20 Mar 18, 2024
b004143
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Mar 20, 2024
2968f18
Pull upstream
RikkiButler20 Jul 24, 2024
679d43e
Merge branch 'develop' of https://github.com/RikkiButler20/spack into…
RikkiButler20 Jul 24, 2024
5adec3e
Merge remote-tracking branch 'upstream/develop' into develop
RikkiButler20 Jul 2, 2024
3d06458
build(deps): bump mypy in /.github/workflows/requirements/style
dependabot[bot] Aug 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/requirements/style/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ black==24.8.0
clingo==5.7.1
flake8==7.1.1
isort==5.13.2
mypy==1.8.0
mypy==1.11.1
types-six==1.16.21.20240513
vermin==1.6.0
125 changes: 125 additions & 0 deletions lib/spack/docs/binary_caches.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,131 @@ Or you can directly edit the ``mirrors.yaml`` configuration file:

See also :ref:`mirrors`.

-----------------------------------------
OCI / Docker V2 registries as build cache
-----------------------------------------

Spack can also use OCI or Docker V2 registries such as Dockerhub, Quay.io,
Github Packages, GitLab Container Registry, JFrog Artifactory, and others
as build caches. This is a convenient way to share binaries using public
infrastructure, or to cache Spack built binaries in Github Actions and
GitLab CI.

To get started, configure an OCI mirror using ``oci://`` as the scheme,
and optionally specify a username and password (or personal access token):

.. code-block:: console

$ spack mirror add --oci-username username --oci-password password my_registry oci://example.com/my_image

Spack follows the naming conventions of Docker, with Dockerhub as the default
registry. To use Dockerhub, you can omit the registry domain:

.. code-block:: console

$ spack mirror add --oci-username username --oci-password password my_registry oci://username/my_image

From here, you can use the mirror as any other build cache:

.. code-block:: console

$ spack buildcache push my_registry <specs...> # push to the registry
$ spack install <specs...> # install from the registry

A unique feature of buildcaches on top of OCI registries is that it's incredibly
easy to generate get a runnable container image with the binaries installed. This
is a great way to make applications available to users without requiring them to
install Spack -- all you need is Docker, Podman or any other OCI-compatible container
runtime.

To produce container images, all you need to do is add the ``--base-image`` flag
when pushing to the build cache:

.. code-block:: console

$ spack buildcache push --base-image ubuntu:20.04 my_registry ninja
Pushed to example.com/my_image:ninja-1.11.1-yxferyhmrjkosgta5ei6b4lqf6bxbscz.spack

$ docker run -it example.com/my_image:ninja-1.11.1-yxferyhmrjkosgta5ei6b4lqf6bxbscz.spack
root@e4c2b6f6b3f4:/# ninja --version
1.11.1

If ``--base-image`` is not specified, distroless images are produced. In practice,
you won't be able to run these as containers, since they don't come with libc and
other system dependencies. However, they are still compatible with tools like
``skopeo``, ``podman``, and ``docker`` for pulling and pushing.

.. note::
The docker ``overlayfs2`` storage driver is limited to 128 layers, above which a
``max depth exceeded`` error may be produced when pulling the image. There
are `alternative drivers <https://docs.docker.com/storage/storagedriver/>`_.

------------------------------------
Using a buildcache in GitHub Actions
------------------------------------

GitHub Actions is a popular CI/CD platform for building and testing software,
but each CI job has limited resources, making from source builds too slow for
many applications. Spack build caches can be used to share binaries between CI
runs, speeding up CI significantly.

A typical workflow is to include a ``spack.yaml`` environment in your repository
that specifies the packages to install:

.. code-block:: yaml

spack:
specs: [pkg-x, pkg-y]
packages:
all:
require: target=x86_64_v2
mirrors:
github_packages: oci://ghcr.io/<user>/<repo>

And a GitHub action that sets up Spack, installs packages from the build cache
or from sources, and pushes newly built binaries to the build cache:

.. code-block:: yaml

name: Install Spack packages

on: push

env:
SPACK_COLOR: always

jobs:
example:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install Spack
run: |
git clone --depth=1 https://github.com/spack/spack.git
echo "$PWD/spack/bin/" >> "$GITHUB_PATH"

- name: Concretize
run: spack -e . concretize

- name: Install
run: spack -e . install --no-check-signature --fail-fast

- name: Push to buildcache
run: |
spack -e . mirror set --oci-username <user> --oci-password "${{ secrets.GITHUB_TOKEN }}" github_packages
spack -e . buildcache push --base-image ubuntu:22.04 --unsigned --update-index github_packages
if: always()

The first time this action runs, it will build the packages from source and
push them to the build cache. Subsequent runs will pull the binaries from the
build cache. The concretizer will ensure that prebuilt binaries are favored
over source builds.

The build cache entries appear in the GitHub Packages section of your repository,
and contain instructions for pulling and running them with ``docker`` or ``podman``.

----------
Relocation
----------
Expand Down
29 changes: 29 additions & 0 deletions lib/spack/spack/build_systems/oneapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,35 @@ def libs(self):
return find_libraries("*", self.component_prefix.sdk.lib64)


class IntelOneApiLibraryPackageWithSdk(IntelOneApiPackage):
"""Base class for Intel oneAPI library packages with SDK components.

Contains some convenient default implementations for libraries
that expose functionality in sdk subdirectories.
Implement the method directly in the package if something
different is needed.

"""

@property
def include(self):
return join_path(self.component_prefix, "sdk", "include")

@property
def headers(self):
return find_headers("*", self.include, recursive=True)

@property
def lib(self):
lib_path = join_path(self.component_prefix, "sdk", "lib64")
lib_path = lib_path if isdir(lib_path) else dirname(lib_path)
return lib_path

@property
def libs(self):
return find_libraries("*", root=self.lib, shared=True, recursive=True)


class IntelOneApiStaticLibraryList:
"""Provides ld_flags when static linking is needed

Expand Down
69 changes: 69 additions & 0 deletions lib/spack/spack/build_systems/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,51 @@ def libs(self) -> LibraryList:
raise NoLibrariesError(msg.format(self.spec.name, platlib, purelib))


def fixup_shebangs(path: str, old_interpreter: bytes, new_interpreter: bytes):
# Recurse into the install prefix and fixup shebangs
exe = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
dirs = [path]
hardlinks = set()

while dirs:
with os.scandir(dirs.pop()) as entries:
for entry in entries:
if entry.is_dir(follow_symlinks=False):
dirs.append(entry.path)
continue

# Only consider files, not symlinks
if not entry.is_file(follow_symlinks=False):
continue

lstat = entry.stat(follow_symlinks=False)

# Skip over files that are not executable
if not (lstat.st_mode & exe):
continue

# Don't modify hardlinks more than once
if lstat.st_nlink > 1:
key = (lstat.st_ino, lstat.st_dev)
if key in hardlinks:
continue
hardlinks.add(key)

# Finally replace shebangs if any.
with open(entry.path, "rb+") as f:
contents = f.read(2)
if contents != b"#!":
continue
contents += f.read()

if old_interpreter not in contents:
continue

f.seek(0)
f.write(contents.replace(old_interpreter, new_interpreter))
f.truncate()


@spack.builder.builder("python_pip")
class PythonPipBuilder(BaseBuilder):
phases = ("install",)
Expand Down Expand Up @@ -536,4 +581,28 @@ def install(self, pkg: PythonPackage, spec: Spec, prefix: Prefix) -> None:
with fs.working_dir(self.build_directory):
pip(*args)

@spack.builder.run_after("install")
def fixup_shebangs_pointing_to_build(self):
"""When installing a package using an external python, we use a temporary virtual
environment which improves build isolation. The downside is that pip produces shebangs
that point to the temporary virtual environment. This method fixes them up to point to the
underlying Python."""
# No need to fixup shebangs if no build venv was used. (this post install function also
# runs when install was overridden in another package, so check existence of the venv path)
if not os.path.exists(self._build_venv_path):
return

# Use sys.executable, since that's what pip uses.
interpreter = (
lambda python: python("-c", "import sys; print(sys.executable)", output=str)
.strip()
.encode("utf-8")
)

fixup_shebangs(
path=self.spec.prefix,
old_interpreter=interpreter(self._build_venv_python),
new_interpreter=interpreter(self.spec["python"].command),
)

spack.builder.run_after("install")(execute_install_time_tests)
6 changes: 6 additions & 0 deletions lib/spack/spack/cmd/checksum.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ def setup_parser(subparser):
" `spack checksum [email protected]` autodetects versions 1.2.0 to 1.2.13 from the remote\n"
" `spack checksum zlib 1.2.13` checksums exact version 1.2.13 directly without search\n"
)
arguments.add_common_arguments(subparser, ["jobs"])
subparser.epilog = (
"examples:\n"
" `spack checksum [email protected]` autodetects versions 1.2.0 to 1.2.13 from the remote\n"
" `spack checksum zlib 1.2.13` checksums exact version 1.2.13 directly without search\n"
)


def checksum(parser, args):
Expand Down
13 changes: 13 additions & 0 deletions lib/spack/spack/modules/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,19 @@ def hidden(self):

return hidden_as_implicit

@property
def hidden(self):
"""Returns True if the module has been hidden, False otherwise."""

conf = self.module.configuration(self.name)

hidden_as_implicit = not self.explicit and conf.get("hide_implicits", False)

if hidden_as_implicit:
tty.debug(f"\tHIDDEN_AS_IMPLICIT : {self.spec.cshort_spec}")

return hidden_as_implicit

@property
def context(self):
return self.conf.get("context", {})
Expand Down
11 changes: 11 additions & 0 deletions lib/spack/spack/modules/lmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ def modulerc(self):
"""Returns the modulerc file associated with current module file"""
return os.path.join(os.path.dirname(self.filename), f".modulerc.{self.extension}")

@property
def modulerc(self):
"""Returns the modulerc file associated with current module file"""
return os.path.join(
os.path.dirname(self.filename), ".".join([".modulerc", self.extension])
)

def token_to_path(self, name, value):
"""Transforms a hierarchy token into the corresponding path part.

Expand Down Expand Up @@ -481,6 +488,10 @@ class LmodModulefileWriter(BaseModuleFileWriter):

hide_cmd_format = 'hide_version("%s")'

modulerc_header: list = []

hide_cmd_format = 'hide_version("%s")'


class CoreCompilersNotFoundError(spack.error.SpackError, KeyError):
"""Error raised if the key 'core_compilers' has not been specified
Expand Down
2 changes: 1 addition & 1 deletion lib/spack/spack/test/cmd/pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def test_pkg_grep(mock_packages, capfd):
output, _ = capfd.readouterr()
assert output.strip() == "\n".join(
spack.repo.PATH.get_pkg_class(name).module.__file__
for name in ["splice-a", "splice-h", "splice-t", "splice-vh", "splice-z"]
for name in ["splice-a", "splice-b", "splice-h", "splice-t", "splice-vh", "splice-z"]
)

# ensure that this string isn't fouhnd
Expand Down
3 changes: 2 additions & 1 deletion lib/spack/spack/test/concretize.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import spack.util.libc
import spack.variant as vt
from spack.concretize import find_spec
from spack.main import SpackCommand
from spack.spec import CompilerSpec, Spec
from spack.version import Version, VersionList, ver

Expand Down Expand Up @@ -1589,7 +1590,7 @@ def test_non_default_provider_of_multiple_virtuals(self):
@pytest.mark.regression("27237")
@pytest.mark.parametrize(
"spec_str,expect_installed",
[("mpich", True), ("mpich+debug", False), ("mpich~debug", True)],
[("mpich", True), ("mpich+debug", False), ("mpich~debug", True), ("mpich++debug", False)],
)
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
def test_concrete_specs_are_not_modified_on_reuse(
Expand Down
4 changes: 4 additions & 0 deletions lib/spack/spack/user_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import os
import re
import sys
from contextlib import contextmanager
from typing import Callable

from llnl.util.lang import nullcontext

import spack.build_environment
import spack.config
Expand Down
8 changes: 4 additions & 4 deletions lib/spack/spack/variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,19 +255,19 @@ def __init__(self, name, value, propagate=False):
self.value = value

@staticmethod
def from_node_dict(name, value):
def from_node_dict(name, value, propagate=False):
"""Reconstruct a variant from a node dict."""
if isinstance(value, list):
# read multi-value variants in and be faithful to the YAML
mvar = MultiValuedVariant(name, ())
mvar = MultiValuedVariant(name, (), propagate)
mvar._value = tuple(value)
mvar._original_value = mvar._value
return mvar

elif str(value).upper() == "TRUE" or str(value).upper() == "FALSE":
return BoolValuedVariant(name, value)
return BoolValuedVariant(name, value, propagate)

return SingleValuedVariant(name, value)
return SingleValuedVariant(name, value, propagate)

def yaml_entry(self):
"""Returns a key, value tuple suitable to be an entry in a yaml dict.
Expand Down
Loading