Compare commits

..

2 Commits

Author SHA1 Message Date
Harmen Stoppels
10acffc92e fix incorrect type annotation of spack.provider_index._IndexBase.providers 2025-01-29 17:38:13 +01:00
Harmen Stoppels
f95e246355 index: avoid quadratic complexity through bulk update 2025-01-29 17:14:34 +01:00
245 changed files with 1009 additions and 871 deletions

View File

@@ -40,17 +40,17 @@ jobs:
# 1: Platforms to build for # 1: Platforms to build for
# 2: Base image (e.g. ubuntu:22.04) # 2: Base image (e.g. ubuntu:22.04)
dockerfile: [[amazon-linux, 'linux/amd64,linux/arm64', 'amazonlinux:2'], dockerfile: [[amazon-linux, 'linux/amd64,linux/arm64', 'amazonlinux:2'],
[centos-stream9, 'linux/amd64,linux/arm64', 'centos:stream9'], [centos-stream9, 'linux/amd64,linux/arm64,linux/ppc64le', 'centos:stream9'],
[leap15, 'linux/amd64,linux/arm64', 'opensuse/leap:15'], [leap15, 'linux/amd64,linux/arm64,linux/ppc64le', 'opensuse/leap:15'],
[ubuntu-focal, 'linux/amd64,linux/arm64', 'ubuntu:20.04'], [ubuntu-focal, 'linux/amd64,linux/arm64,linux/ppc64le', 'ubuntu:20.04'],
[ubuntu-jammy, 'linux/amd64,linux/arm64', 'ubuntu:22.04'], [ubuntu-jammy, 'linux/amd64,linux/arm64,linux/ppc64le', 'ubuntu:22.04'],
[ubuntu-noble, 'linux/amd64,linux/arm64', 'ubuntu:24.04'], [ubuntu-noble, 'linux/amd64,linux/arm64,linux/ppc64le', 'ubuntu:24.04'],
[almalinux8, 'linux/amd64,linux/arm64', 'almalinux:8'], [almalinux8, 'linux/amd64,linux/arm64,linux/ppc64le', 'almalinux:8'],
[almalinux9, 'linux/amd64,linux/arm64', 'almalinux:9'], [almalinux9, 'linux/amd64,linux/arm64,linux/ppc64le', 'almalinux:9'],
[rockylinux8, 'linux/amd64,linux/arm64', 'rockylinux:8'], [rockylinux8, 'linux/amd64,linux/arm64', 'rockylinux:8'],
[rockylinux9, 'linux/amd64,linux/arm64', 'rockylinux:9'], [rockylinux9, 'linux/amd64,linux/arm64', 'rockylinux:9'],
[fedora39, 'linux/amd64,linux/arm64', 'fedora:39'], [fedora39, 'linux/amd64,linux/arm64,linux/ppc64le', 'fedora:39'],
[fedora40, 'linux/amd64,linux/arm64', 'fedora:40']] [fedora40, 'linux/amd64,linux/arm64,linux/ppc64le', 'fedora:40']]
name: Build ${{ matrix.dockerfile[0] }} name: Build ${{ matrix.dockerfile[0] }}
if: github.repository == 'spack/spack' if: github.repository == 'spack/spack'
steps: steps:

View File

@@ -272,9 +272,9 @@ often lists dependencies and the flags needed to locate them. The
"environment variables" section lists environment variables that the "environment variables" section lists environment variables that the
build system uses to pass flags to the compiler and linker. build system uses to pass flags to the compiler and linker.
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
Adding flags to configure Addings flags to configure
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
For most of the flags you encounter, you will want a variant to For most of the flags you encounter, you will want a variant to
optionally enable/disable them. You can then optionally pass these optionally enable/disable them. You can then optionally pass these
@@ -285,7 +285,7 @@ function like so:
def configure_args(self): def configure_args(self):
args = [] args = []
...
if self.spec.satisfies("+mpi"): if self.spec.satisfies("+mpi"):
args.append("--enable-mpi") args.append("--enable-mpi")
else: else:
@@ -299,10 +299,7 @@ Alternatively, you can use the :ref:`enable_or_disable <autotools_enable_or_dis
.. code-block:: python .. code-block:: python
def configure_args(self): def configure_args(self):
args = [] return [self.enable_or_disable("mpi")]
...
args.extend(self.enable_or_disable("mpi"))
return args
Note that we are explicitly disabling MPI support if it is not Note that we are explicitly disabling MPI support if it is not
@@ -347,14 +344,7 @@ typically used to enable or disable some feature within the package.
default=False, default=False,
description="Memchecker support for debugging [degrades performance]" description="Memchecker support for debugging [degrades performance]"
) )
... config_args.extend(self.enable_or_disable("memchecker"))
def configure_args(self):
args = []
...
args.extend(self.enable_or_disable("memchecker"))
return args
In this example, specifying the variant ``+memchecker`` will generate In this example, specifying the variant ``+memchecker`` will generate
the following configuration options: the following configuration options:

View File

@@ -361,6 +361,7 @@ and the tags associated with the class of runners to build on.
* ``.linux_neoverse_n1`` * ``.linux_neoverse_n1``
* ``.linux_neoverse_v1`` * ``.linux_neoverse_v1``
* ``.linux_neoverse_v2`` * ``.linux_neoverse_v2``
* ``.linux_power``
* ``.linux_skylake`` * ``.linux_skylake``
* ``.linux_x86_64`` * ``.linux_x86_64``
* ``.linux_x86_64_v4`` * ``.linux_x86_64_v4``

View File

@@ -112,19 +112,6 @@ the original but may concretize differently in the presence of different
explicit or default configuration settings (e.g., a different version of explicit or default configuration settings (e.g., a different version of
Spack or for a different user account). Spack or for a different user account).
Environments created from a manifest will copy any included configs
from relative paths inside the environment. Relative paths from
outside the environment will cause errors, and absolute paths will be
kept absolute. For example, if ``spack.yaml`` includes:
.. code-block:: yaml
spack:
include: [./config.yaml]
then the created environment will have its own copy of the file
``config.yaml`` copied from the location in the original environment.
Create an environment from a ``spack.lock`` file using: Create an environment from a ``spack.lock`` file using:
.. code-block:: console .. code-block:: console
@@ -173,7 +160,7 @@ accepts. If an environment already exists then spack will simply activate it
and ignore the create-specific flags. and ignore the create-specific flags.
.. code-block:: console .. code-block:: console
$ spack env activate --create -p myenv $ spack env activate --create -p myenv
# ... # ...
# [creates if myenv does not exist yet] # [creates if myenv does not exist yet]
@@ -437,8 +424,8 @@ Developing Packages in a Spack Environment
The ``spack develop`` command allows one to develop Spack packages in The ``spack develop`` command allows one to develop Spack packages in
an environment. It requires a spec containing a concrete version, and an environment. It requires a spec containing a concrete version, and
will configure Spack to install the package from local source. will configure Spack to install the package from local source.
If a version is not provided from the command line interface then spack If a version is not provided from the command line interface then spack
will automatically pick the highest version the package has defined. will automatically pick the highest version the package has defined.
This means any infinity versions (``develop``, ``main``, ``stable``) will be This means any infinity versions (``develop``, ``main``, ``stable``) will be
preferred in this selection process. preferred in this selection process.
@@ -448,9 +435,9 @@ set, and Spack will ensure the package and its dependents are rebuilt
any time the environment is installed if the package's local source any time the environment is installed if the package's local source
code has been modified. Spack's native implementation to check for modifications code has been modified. Spack's native implementation to check for modifications
is to check if ``mtime`` is newer than the installation. is to check if ``mtime`` is newer than the installation.
A custom check can be created by overriding the ``detect_dev_src_change`` method A custom check can be created by overriding the ``detect_dev_src_change`` method
in your package class. This is particularly useful for projects using custom spack repo's in your package class. This is particularly useful for projects using custom spack repo's
to drive development and want to optimize performance. to drive development and want to optimize performance.
Spack ensures that all instances of a Spack ensures that all instances of a
developed package in the environment are concretized to match the developed package in the environment are concretized to match the
@@ -466,7 +453,7 @@ Further development on ``foo`` can be tested by re-installing the environment,
and eventually committed and pushed to the upstream git repo. and eventually committed and pushed to the upstream git repo.
If the package being developed supports out-of-source builds then users can use the If the package being developed supports out-of-source builds then users can use the
``--build_directory`` flag to control the location and name of the build directory. ``--build_directory`` flag to control the location and name of the build directory.
This is a shortcut to set the ``package_attributes:build_directory`` in the This is a shortcut to set the ``package_attributes:build_directory`` in the
``packages`` configuration (see :ref:`assigning-package-attributes`). ``packages`` configuration (see :ref:`assigning-package-attributes`).
The supplied location will become the build-directory for that package in all future builds. The supplied location will become the build-directory for that package in all future builds.

View File

@@ -668,7 +668,7 @@ def copy(src, dest, _permissions=False):
_permissions (bool): for internal use only _permissions (bool): for internal use only
Raises: Raises:
OSError: if *src* does not match any files or directories IOError: if *src* does not match any files or directories
ValueError: if *src* matches multiple files but *dest* is ValueError: if *src* matches multiple files but *dest* is
not a directory not a directory
""" """
@@ -679,7 +679,7 @@ def copy(src, dest, _permissions=False):
files = glob.glob(src) files = glob.glob(src)
if not files: if not files:
raise OSError("No such file or directory: '{0}'".format(src)) raise IOError("No such file or directory: '{0}'".format(src))
if len(files) > 1 and not os.path.isdir(dest): if len(files) > 1 and not os.path.isdir(dest):
raise ValueError( raise ValueError(
"'{0}' matches multiple files but '{1}' is not a directory".format(src, dest) "'{0}' matches multiple files but '{1}' is not a directory".format(src, dest)
@@ -710,7 +710,7 @@ def install(src, dest):
dest (str): the destination file or directory dest (str): the destination file or directory
Raises: Raises:
OSError: if *src* does not match any files or directories IOError: if *src* does not match any files or directories
ValueError: if *src* matches multiple files but *dest* is ValueError: if *src* matches multiple files but *dest* is
not a directory not a directory
""" """
@@ -748,7 +748,7 @@ def copy_tree(
_permissions (bool): for internal use only _permissions (bool): for internal use only
Raises: Raises:
OSError: if *src* does not match any files or directories IOError: if *src* does not match any files or directories
ValueError: if *src* is a parent directory of *dest* ValueError: if *src* is a parent directory of *dest*
""" """
if _permissions: if _permissions:
@@ -762,7 +762,7 @@ def copy_tree(
files = glob.glob(src) files = glob.glob(src)
if not files: if not files:
raise OSError("No such file or directory: '{0}'".format(src)) raise IOError("No such file or directory: '{0}'".format(src))
# For Windows hard-links and junctions, the source path must exist to make a symlink. Add # For Windows hard-links and junctions, the source path must exist to make a symlink. Add
# all symlinks to this list while traversing the tree, then when finished, make all # all symlinks to this list while traversing the tree, then when finished, make all
@@ -843,7 +843,7 @@ def install_tree(src, dest, symlinks=True, ignore=None):
ignore (typing.Callable): function indicating which files to ignore ignore (typing.Callable): function indicating which files to ignore
Raises: Raises:
OSError: if *src* does not match any files or directories IOError: if *src* does not match any files or directories
ValueError: if *src* is a parent directory of *dest* ValueError: if *src* is a parent directory of *dest*
""" """
copy_tree(src, dest, symlinks=symlinks, ignore=ignore, _permissions=True) copy_tree(src, dest, symlinks=symlinks, ignore=ignore, _permissions=True)

View File

@@ -308,7 +308,7 @@ class LinkTree:
def __init__(self, source_root): def __init__(self, source_root):
if not os.path.exists(source_root): if not os.path.exists(source_root):
raise OSError("No such file or directory: '%s'", source_root) raise IOError("No such file or directory: '%s'", source_root)
self._root = source_root self._root = source_root

View File

@@ -391,7 +391,7 @@ def _poll_lock(self, op: int) -> bool:
return True return True
except OSError as e: except IOError as e:
# EAGAIN and EACCES == locked by another process (so try again) # EAGAIN and EACCES == locked by another process (so try again)
if e.errno not in (errno.EAGAIN, errno.EACCES): if e.errno not in (errno.EAGAIN, errno.EACCES):
raise raise

View File

@@ -918,7 +918,7 @@ def _writer_daemon(
try: try:
if stdin_file.read(1) == "v": if stdin_file.read(1) == "v":
echo = not echo echo = not echo
except OSError as e: except IOError as e:
# If SIGTTIN is ignored, the system gives EIO # If SIGTTIN is ignored, the system gives EIO
# to let the caller know the read failed b/c it # to let the caller know the read failed b/c it
# was in the bg. Ignore that too. # was in the bg. Ignore that too.
@@ -1013,7 +1013,7 @@ def wrapped(*args, **kwargs):
while True: while True:
try: try:
return function(*args, **kwargs) return function(*args, **kwargs)
except OSError as e: except IOError as e:
if e.errno == errno.EINTR: if e.errno == errno.EINTR:
continue continue
raise raise

View File

@@ -459,16 +459,8 @@ def cmake(
"""Runs ``cmake`` in the build directory""" """Runs ``cmake`` in the build directory"""
# skip cmake phase if it is an incremental develop build # skip cmake phase if it is an incremental develop build
# These are the files that will re-run CMake that are generated from a successful
# configure step
primary_generator = _extract_primary_generator(self.generator)
if primary_generator == "Unix Makefiles":
configure_artifact = "Makefile"
elif primary_generator == "Ninja":
configure_artifact = "ninja.build"
if spec.is_develop and os.path.isfile( if spec.is_develop and os.path.isfile(
os.path.join(self.build_directory, configure_artifact) os.path.join(self.build_directory, "CMakeCache.txt")
): ):
return return

View File

@@ -110,7 +110,10 @@ def external_find(args):
# Note that KeyboardInterrupt does not subclass Exception # Note that KeyboardInterrupt does not subclass Exception
# (so CTRL-C will terminate the program as expected). # (so CTRL-C will terminate the program as expected).
skip_msg = "Skipping manifest and continuing with other external checks" skip_msg = "Skipping manifest and continuing with other external checks"
if isinstance(e, OSError) and e.errno in (errno.EPERM, errno.EACCES): if (isinstance(e, IOError) or isinstance(e, OSError)) and e.errno in [
errno.EPERM,
errno.EACCES,
]:
# The manifest file does not have sufficient permissions enabled: # The manifest file does not have sufficient permissions enabled:
# print a warning and keep going # print a warning and keep going
tty.warn("Unable to read manifest due to insufficient permissions.", skip_msg) tty.warn("Unable to read manifest due to insufficient permissions.", skip_msg)

View File

@@ -177,15 +177,16 @@ def test_run(args):
matching = spack.store.STORE.db.query_local(spec, hashes=hashes, explicit=explicit) matching = spack.store.STORE.db.query_local(spec, hashes=hashes, explicit=explicit)
if spec and not matching: if spec and not matching:
tty.warn("No {0}installed packages match spec {1}".format(explicit_str, spec)) tty.warn("No {0}installed packages match spec {1}".format(explicit_str, spec))
"""
TODO: Need to write out a log message and/or CDASH Testing
output that package not installed IF continue to process
these issues here.
# TODO: Need to write out a log message and/or CDASH Testing if args.log_format:
# output that package not installed IF continue to process # Proceed with the spec assuming the test process
# these issues here. # to ensure report package as skipped (e.g., for CI)
specs_to_test.append(spec)
# if args.log_format: """
# # Proceed with the spec assuming the test process
# # to ensure report package as skipped (e.g., for CI)
# specs_to_test.append(spec)
specs_to_test.extend(matching) specs_to_test.extend(matching)

View File

@@ -581,7 +581,7 @@ def _error_on_nonempty_view_dir(new_root):
# Check if the target path lexists # Check if the target path lexists
try: try:
st = os.lstat(new_root) st = os.lstat(new_root)
except OSError: except (IOError, OSError):
return return
# Empty directories are fine # Empty directories are fine
@@ -861,7 +861,7 @@ def regenerate(self, concrete_roots: List[Spec]) -> None:
): ):
try: try:
shutil.rmtree(old_root) shutil.rmtree(old_root)
except OSError as e: except (IOError, OSError) as e:
msg = "Failed to remove old view at %s\n" % old_root msg = "Failed to remove old view at %s\n" % old_root
msg += str(e) msg += str(e)
tty.warn(msg) tty.warn(msg)
@@ -2554,7 +2554,7 @@ def is_latest_format(manifest):
try: try:
with open(manifest, encoding="utf-8") as f: with open(manifest, encoding="utf-8") as f:
data = syaml.load(f) data = syaml.load(f)
except OSError: except (OSError, IOError):
return True return True
top_level_key = _top_level_key(data) top_level_key = _top_level_key(data)
changed = spack.schema.env.update(data[top_level_key]) changed = spack.schema.env.update(data[top_level_key])
@@ -2634,32 +2634,6 @@ def _ensure_env_dir():
shutil.copy(envfile, target_manifest) shutil.copy(envfile, target_manifest)
# Copy relative path includes that live inside the environment dir
try:
manifest = EnvironmentManifestFile(environment_dir)
except Exception:
# error handling for bad manifests is handled on other code paths
return
includes = manifest[TOP_LEVEL_KEY].get("include", [])
for include in includes:
if os.path.isabs(include):
continue
abspath = pathlib.Path(os.path.normpath(environment_dir / include))
common_path = pathlib.Path(os.path.commonpath([environment_dir, abspath]))
if common_path != environment_dir:
tty.debug(f"Will not copy relative include from outside environment: {include}")
continue
orig_abspath = os.path.normpath(envfile.parent / include)
if not os.path.exists(orig_abspath):
tty.warn(f"Included file does not exist; will not copy: '{include}'")
continue
fs.touchp(abspath)
shutil.copy(orig_abspath, abspath)
class EnvironmentManifestFile(collections.abc.Mapping): class EnvironmentManifestFile(collections.abc.Mapping):
"""Manages the in-memory representation of a manifest file, and its synchronization """Manages the in-memory representation of a manifest file, and its synchronization

View File

@@ -187,7 +187,7 @@ def path_for_extension(target_name: str, *, paths: List[str]) -> str:
if name == target_name: if name == target_name:
return path return path
else: else:
raise OSError('extension "{0}" not found'.format(target_name)) raise IOError('extension "{0}" not found'.format(target_name))
def get_module(cmd_name): def get_module(cmd_name):

View File

@@ -427,7 +427,7 @@ def needs_file(spec, file):
try: try:
with open(manifest_file, "r", encoding="utf-8") as f: with open(manifest_file, "r", encoding="utf-8") as f:
manifest = s_json.load(f) manifest = s_json.load(f)
except OSError: except (OSError, IOError):
# if we can't load it, assume it doesn't know about the file. # if we can't load it, assume it doesn't know about the file.
manifest = {} manifest = {}
return test_path in manifest return test_path in manifest
@@ -831,7 +831,7 @@ def get_spec_from_file(filename):
try: try:
with open(filename, "r", encoding="utf-8") as f: with open(filename, "r", encoding="utf-8") as f:
return spack.spec.Spec.from_yaml(f) return spack.spec.Spec.from_yaml(f)
except OSError: except IOError:
return None return None

View File

@@ -26,7 +26,7 @@ def is_shared_library_elf(filepath):
with open(filepath, "rb") as f: with open(filepath, "rb") as f:
elf = parse_elf(f, interpreter=True, dynamic_section=True) elf = parse_elf(f, interpreter=True, dynamic_section=True)
return elf.has_pt_dynamic and (elf.has_soname or not elf.has_pt_interp) return elf.has_pt_dynamic and (elf.has_soname or not elf.has_pt_interp)
except (OSError, ElfParsingError): except (IOError, OSError, ElfParsingError):
return False return False

View File

@@ -166,7 +166,7 @@ def filter_shebangs_in_directory(directory, filenames=None):
# Only look at executable, non-symlink files. # Only look at executable, non-symlink files.
try: try:
st = os.lstat(path) st = os.lstat(path)
except OSError: except (IOError, OSError):
continue continue
if stat.S_ISLNK(st.st_mode) or stat.S_ISDIR(st.st_mode) or not st.st_mode & is_exe: if stat.S_ISLNK(st.st_mode) or stat.S_ISDIR(st.st_mode) or not st.st_mode & is_exe:

View File

@@ -163,7 +163,7 @@ def format_help_sections(self, level):
# lazily add all commands to the parser when needed. # lazily add all commands to the parser when needed.
add_all_commands(self) add_all_commands(self)
# Print help on subcommands in neatly formatted sections. """Print help on subcommands in neatly formatted sections."""
formatter = self._get_formatter() formatter = self._get_formatter()
# Create a list of subcommand actions. Argparse internals are nasty! # Create a list of subcommand actions. Argparse internals are nasty!

View File

@@ -13,17 +13,6 @@
# import most common types used in packages # import most common types used in packages
from typing import Dict, List, Optional from typing import Dict, List, Optional
class tty:
import llnl.util.tty as _tty
debug = _tty.debug
error = _tty.error
info = _tty.info
msg = _tty.msg
warn = _tty.warn
from llnl.util.filesystem import ( from llnl.util.filesystem import (
FileFilter, FileFilter,
FileList, FileList,
@@ -60,6 +49,7 @@ class tty:
) )
from llnl.util.symlink import symlink from llnl.util.symlink import symlink
# These props will be overridden when the build env is set up.
from spack.build_environment import MakeExecutable from spack.build_environment import MakeExecutable
from spack.build_systems.aspell_dict import AspellDictPackage from spack.build_systems.aspell_dict import AspellDictPackage
from spack.build_systems.autotools import AutotoolsPackage from spack.build_systems.autotools import AutotoolsPackage
@@ -146,10 +136,8 @@ class tty:
) )
from spack.phase_callbacks import run_after, run_before from spack.phase_callbacks import run_after, run_before
from spack.spec import Spec from spack.spec import Spec
from spack.util.environment import EnvironmentModifications
from spack.util.executable import Executable, ProcessError, which, which_string from spack.util.executable import Executable, ProcessError, which, which_string
from spack.util.filesystem import fix_darwin_install_name from spack.util.filesystem import fix_darwin_install_name
from spack.util.prefix import Prefix
from spack.variant import any_combination_of, auto_or_any_combination_of, disjoint_sets from spack.variant import any_combination_of, auto_or_any_combination_of, disjoint_sets
from spack.version import Version, ver from spack.version import Version, ver

View File

@@ -66,6 +66,10 @@
] ]
FLAG_HANDLER_TYPE = Callable[[str, Iterable[str]], FLAG_HANDLER_RETURN_TYPE] FLAG_HANDLER_TYPE = Callable[[str, Iterable[str]], FLAG_HANDLER_RETURN_TYPE]
"""Allowed URL schemes for spack packages."""
_ALLOWED_URL_SCHEMES = ["http", "https", "ftp", "file", "git"]
#: Filename for the Spack build/install log. #: Filename for the Spack build/install log.
_spack_build_logfile = "spack-build-out.txt" _spack_build_logfile = "spack-build-out.txt"

View File

@@ -6,7 +6,7 @@
import os import os
import pathlib import pathlib
import sys import sys
from typing import Any, Dict, Optional, Tuple, Type, Union from typing import Any, Dict, Optional, Set, Tuple, Type, Union
import llnl.util.filesystem import llnl.util.filesystem
from llnl.url import allowed_archive from llnl.url import allowed_archive
@@ -503,36 +503,38 @@ def patch_for_package(self, sha256: str, pkg: "spack.package_base.PackageBase")
patch_dict["sha256"] = sha256 patch_dict["sha256"] = sha256
return from_dict(patch_dict, repository=self.repository) return from_dict(patch_dict, repository=self.repository)
def update_package(self, pkg_fullname: str) -> None: def update_packages(self, pkgs_fullname: Set[str]) -> None:
"""Update the patch cache. """Update the patch cache.
Args: Args:
pkg_fullname: package to update. pkg_fullname: package to update.
""" """
# remove this package from any patch entries that reference it. # remove this package from any patch entries that reference it.
empty = [] if self.index:
for sha256, package_to_patch in self.index.items(): empty = []
remove = [] for sha256, package_to_patch in self.index.items():
for fullname, patch_dict in package_to_patch.items(): remove = []
if patch_dict["owner"] == pkg_fullname: for fullname, patch_dict in package_to_patch.items():
remove.append(fullname) if patch_dict["owner"] in pkgs_fullname:
remove.append(fullname)
for fullname in remove: for fullname in remove:
package_to_patch.pop(fullname) package_to_patch.pop(fullname)
if not package_to_patch: if not package_to_patch:
empty.append(sha256) empty.append(sha256)
# remove any entries that are now empty # remove any entries that are now empty
for sha256 in empty: for sha256 in empty:
del self.index[sha256] del self.index[sha256]
# update the index with per-package patch indexes # update the index with per-package patch indexes
pkg_cls = self.repository.get_pkg_class(pkg_fullname) for pkg_fullname in pkgs_fullname:
partial_index = self._index_patches(pkg_cls, self.repository) pkg_cls = self.repository.get_pkg_class(pkg_fullname)
for sha256, package_to_patch in partial_index.items(): partial_index = self._index_patches(pkg_cls, self.repository)
p2p = self.index.setdefault(sha256, {}) for sha256, package_to_patch in partial_index.items():
p2p.update(package_to_patch) p2p = self.index.setdefault(sha256, {})
p2p.update(package_to_patch)
def update(self, other: "PatchCache") -> None: def update(self, other: "PatchCache") -> None:
"""Update this cache with the contents of another. """Update this cache with the contents of another.

View File

@@ -2,7 +2,7 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Classes and functions to manage providers of virtual dependencies""" """Classes and functions to manage providers of virtual dependencies"""
from typing import Dict, List, Optional, Set from typing import Dict, Iterable, List, Optional, Set, Union
import spack.error import spack.error
import spack.spec import spack.spec
@@ -26,7 +26,7 @@ class _IndexBase:
#: Calling providers_for(spec) will find specs that provide a #: Calling providers_for(spec) will find specs that provide a
#: matching implementation of MPI. Derived class need to construct #: matching implementation of MPI. Derived class need to construct
#: this attribute according to the semantics above. #: this attribute according to the semantics above.
providers: Dict[str, Dict[str, Set[str]]] providers: Dict[str, Dict["spack.spec.Spec", Set["spack.spec.Spec"]]]
def providers_for(self, virtual_spec): def providers_for(self, virtual_spec):
"""Return a list of specs of all packages that provide virtual """Return a list of specs of all packages that provide virtual
@@ -99,66 +99,56 @@ def __init__(
self.repository = repository self.repository = repository
self.restrict = restrict self.restrict = restrict
self.providers = {} self.providers = {}
if specs:
self.update_packages(specs)
specs = specs or [] def update_packages(self, specs: Iterable[Union[str, "spack.spec.Spec"]]):
for spec in specs:
if not isinstance(spec, spack.spec.Spec):
spec = spack.spec.Spec(spec)
if self.repository.is_virtual_safe(spec.name):
continue
self.update(spec)
def update(self, spec):
"""Update the provider index with additional virtual specs. """Update the provider index with additional virtual specs.
Args: Args:
spec: spec potentially providing additional virtual specs spec: spec potentially providing additional virtual specs
""" """
if not isinstance(spec, spack.spec.Spec): for spec in specs:
spec = spack.spec.Spec(spec) if not isinstance(spec, spack.spec.Spec):
spec = spack.spec.Spec(spec)
if not spec.name: if not spec.name or self.repository.is_virtual_safe(spec.name):
# Empty specs do not have a package # Only non-virtual packages with name can provide virtual specs.
return continue
msg = "cannot update an index passing the virtual spec '{}'".format(spec.name) pkg_provided = self.repository.get_pkg_class(spec.name).provided
assert not self.repository.is_virtual_safe(spec.name), msg for provider_spec_readonly, provided_specs in pkg_provided.items():
for provided_spec in provided_specs:
# TODO: fix this comment.
# We want satisfaction other than flags
provider_spec = provider_spec_readonly.copy()
provider_spec.compiler_flags = spec.compiler_flags.copy()
pkg_provided = self.repository.get_pkg_class(spec.name).provided if spec.intersects(provider_spec, deps=False):
for provider_spec_readonly, provided_specs in pkg_provided.items(): provided_name = provided_spec.name
for provided_spec in provided_specs:
# TODO: fix this comment.
# We want satisfaction other than flags
provider_spec = provider_spec_readonly.copy()
provider_spec.compiler_flags = spec.compiler_flags.copy()
if spec.intersects(provider_spec, deps=False): provider_map = self.providers.setdefault(provided_name, {})
provided_name = provided_spec.name if provided_spec not in provider_map:
provider_map[provided_spec] = set()
provider_map = self.providers.setdefault(provided_name, {}) if self.restrict:
if provided_spec not in provider_map: provider_set = provider_map[provided_spec]
provider_map[provided_spec] = set()
if self.restrict: # If this package existed in the index before,
provider_set = provider_map[provided_spec] # need to take the old versions out, as they're
# now more constrained.
old = {s for s in provider_set if s.name == spec.name}
provider_set.difference_update(old)
# If this package existed in the index before, # Now add the new version.
# need to take the old versions out, as they're provider_set.add(spec)
# now more constrained.
old = set([s for s in provider_set if s.name == spec.name])
provider_set.difference_update(old)
# Now add the new version. else:
provider_set.add(spec) # Before putting the spec in the map, constrain
# it so that it provides what was asked for.
else: constrained = spec.copy()
# Before putting the spec in the map, constrain constrained.constrain(provider_spec)
# it so that it provides what was asked for. provider_map[provided_spec].add(constrained)
constrained = spec.copy()
constrained.constrain(provider_spec)
provider_map[provided_spec].add(constrained)
def to_json(self, stream=None): def to_json(self, stream=None):
"""Dump a JSON representation of this object. """Dump a JSON representation of this object.
@@ -193,14 +183,13 @@ def merge(self, other):
spdict[provided_spec] = spdict[provided_spec].union(opdict[provided_spec]) spdict[provided_spec] = spdict[provided_spec].union(opdict[provided_spec])
def remove_provider(self, pkg_name): def remove_providers(self, pkgs_fullname: Set[str]):
"""Remove a provider from the ProviderIndex.""" """Remove a provider from the ProviderIndex."""
empty_pkg_dict = [] empty_pkg_dict = []
for pkg, pkg_dict in self.providers.items(): for pkg, pkg_dict in self.providers.items():
empty_pset = [] empty_pset = []
for provided, pset in pkg_dict.items(): for provided, pset in pkg_dict.items():
same_name = set(p for p in pset if p.fullname == pkg_name) pset.difference_update(pkgs_fullname)
pset.difference_update(same_name)
if not pset: if not pset:
empty_pset.append(provided) empty_pset.append(provided)

View File

@@ -465,7 +465,7 @@ def read(self, stream):
"""Read this index from a provided file object.""" """Read this index from a provided file object."""
@abc.abstractmethod @abc.abstractmethod
def update(self, pkg_fullname): def update(self, pkgs_fullname: Set[str]):
"""Update the index in memory with information about a package.""" """Update the index in memory with information about a package."""
@abc.abstractmethod @abc.abstractmethod
@@ -482,8 +482,8 @@ def _create(self):
def read(self, stream): def read(self, stream):
self.index = spack.tag.TagIndex.from_json(stream, self.repository) self.index = spack.tag.TagIndex.from_json(stream, self.repository)
def update(self, pkg_fullname): def update(self, pkgs_fullname: Set[str]):
self.index.update_package(pkg_fullname.split(".")[-1]) self.index.update_packages({p.split(".")[-1] for p in pkgs_fullname})
def write(self, stream): def write(self, stream):
self.index.to_json(stream) self.index.to_json(stream)
@@ -498,15 +498,14 @@ def _create(self):
def read(self, stream): def read(self, stream):
self.index = spack.provider_index.ProviderIndex.from_json(stream, self.repository) self.index = spack.provider_index.ProviderIndex.from_json(stream, self.repository)
def update(self, pkg_fullname): def update(self, pkgs_fullname: Set[str]):
name = pkg_fullname.split(".")[-1]
is_virtual = ( is_virtual = (
not self.repository.exists(name) or self.repository.get_pkg_class(name).virtual lambda name: not self.repository.exists(name)
or self.repository.get_pkg_class(name).virtual
) )
if is_virtual: non_virtual_pkgs_fullname = {p for p in pkgs_fullname if not is_virtual(p.split(".")[-1])}
return self.index.remove_providers(non_virtual_pkgs_fullname)
self.index.remove_provider(pkg_fullname) self.index.update_packages(non_virtual_pkgs_fullname)
self.index.update(pkg_fullname)
def write(self, stream): def write(self, stream):
self.index.to_json(stream) self.index.to_json(stream)
@@ -531,8 +530,8 @@ def read(self, stream):
def write(self, stream): def write(self, stream):
self.index.to_json(stream) self.index.to_json(stream)
def update(self, pkg_fullname): def update(self, pkgs_fullname: Set[str]):
self.index.update_package(pkg_fullname) self.index.update_packages(pkgs_fullname)
class RepoIndex: class RepoIndex:
@@ -622,9 +621,7 @@ def _build_index(self, name: str, indexer: Indexer):
if new_index_mtime != index_mtime: if new_index_mtime != index_mtime:
needs_update = self.checker.modified_since(new_index_mtime) needs_update = self.checker.modified_since(new_index_mtime)
for pkg_name in needs_update: indexer.update({f"{self.namespace}.{pkg_name}" for pkg_name in needs_update})
indexer.update(f"{self.namespace}.{pkg_name}")
indexer.write(new) indexer.write(new)
return indexer.index return indexer.index
@@ -1041,7 +1038,7 @@ def _read_config(self) -> Dict[str, str]:
return yaml_data["repo"] return yaml_data["repo"]
except OSError: except IOError:
tty.die(f"Error reading {self.config_file} when opening {self.root}") tty.die(f"Error reading {self.config_file} when opening {self.root}")
def get(self, spec: "spack.spec.Spec") -> "spack.package_base.PackageBase": def get(self, spec: "spack.spec.Spec") -> "spack.package_base.PackageBase":
@@ -1369,7 +1366,7 @@ def create_repo(root, namespace=None, subdir=packages_dir_name):
if subdir != packages_dir_name: if subdir != packages_dir_name:
config.write(f" subdirectory: '{subdir}'\n") config.write(f" subdirectory: '{subdir}'\n")
except OSError as e: except (IOError, OSError) as e:
# try to clean up. # try to clean up.
if existed: if existed:
shutil.rmtree(config_path, ignore_errors=True) shutil.rmtree(config_path, ignore_errors=True)

View File

@@ -4726,10 +4726,7 @@ def __str__(self):
bool_keys = [] bool_keys = []
kv_keys = [] kv_keys = []
for key in sorted_keys: for key in sorted_keys:
if isinstance(self[key].value, bool): bool_keys.append(key) if isinstance(self[key].value, bool) else kv_keys.append(key)
bool_keys.append(key)
else:
kv_keys.append(key)
# add spaces before and after key/value variants. # add spaces before and after key/value variants.
string = io.StringIO() string = io.StringIO()

View File

@@ -5,6 +5,7 @@
import collections import collections
import copy import copy
from collections.abc import Mapping from collections.abc import Mapping
from typing import Set
import spack.error import spack.error
import spack.repo import spack.repo
@@ -110,23 +111,20 @@ def merge(self, other):
spkgs, opkgs = self.tags[tag], other.tags[tag] spkgs, opkgs = self.tags[tag], other.tags[tag]
self.tags[tag] = sorted(list(set(spkgs + opkgs))) self.tags[tag] = sorted(list(set(spkgs + opkgs)))
def update_package(self, pkg_name): def update_packages(self, pkg_names: Set[str]):
"""Updates a package in the tag index. """Updates a package in the tag index."""
Args:
pkg_name (str): name of the package to be removed from the index
"""
pkg_cls = self.repository.get_pkg_class(pkg_name)
# Remove the package from the list of packages, if present # Remove the package from the list of packages, if present
for pkg_list in self._tag_dict.values(): for pkg_list in self._tag_dict.values():
if pkg_name in pkg_list: if pkg_names.isdisjoint(pkg_list):
pkg_list.remove(pkg_name) continue
pkg_list[:] = [pkg for pkg in pkg_list if pkg not in pkg_names]
# Add it again under the appropriate tags # Add it again under the appropriate tags
for tag in getattr(pkg_cls, "tags", []): for pkg_name in pkg_names:
tag = tag.lower() pkg_cls = self.repository.get_pkg_class(pkg_name)
self._tag_dict[tag].append(pkg_cls.name) for tag in getattr(pkg_cls, "tags", []):
tag = tag.lower()
self._tag_dict[tag].append(pkg_cls.name)
class TagIndexError(spack.error.SpackError): class TagIndexError(spack.error.SpackError):

View File

@@ -328,14 +328,16 @@ def test_get_spec_filter_list(mutable_mock_env_path, mutable_mock_repo):
e1.add("hypre") e1.add("hypre")
e1.concretize() e1.concretize()
# Concretizing the above environment results in the following graphs: """
Concretizing the above environment results in the following graphs:
# mpileaks -> mpich (provides mpi virtual dep of mpileaks) mpileaks -> mpich (provides mpi virtual dep of mpileaks)
# -> callpath -> dyninst -> libelf -> callpath -> dyninst -> libelf
# -> libdwarf -> libelf -> libdwarf -> libelf
# -> mpich (provides mpi dep of callpath) -> mpich (provides mpi dep of callpath)
# hypre -> openblas-with-lapack (provides lapack and blas virtual deps of hypre) hypre -> openblas-with-lapack (provides lapack and blas virtual deps of hypre)
"""
touched = ["libdwarf"] touched = ["libdwarf"]

View File

@@ -1038,58 +1038,6 @@ def test_init_from_yaml(environment_from_manifest):
assert not e2.specs_by_hash assert not e2.specs_by_hash
def test_init_from_yaml_relative_includes(tmp_path):
files = [
"relative_copied/packages.yaml",
"./relative_copied/compilers.yaml",
"repos.yaml",
"./config.yaml",
]
manifest = f"""
spack:
specs: []
include: {files}
"""
e1_path = tmp_path / "e1"
e1_manifest = e1_path / "spack.yaml"
fs.mkdirp(e1_path)
with open(e1_manifest, "w", encoding="utf-8") as f:
f.write(manifest)
for f in files:
fs.touchp(e1_path / f)
e2 = _env_create("test2", init_file=e1_manifest)
for f in files:
assert os.path.exists(os.path.join(e2.path, f))
def test_init_from_yaml_relative_includes_outside_env(tmp_path):
files = ["../outside_env_not_copied/repos.yaml"]
manifest = f"""
spack:
specs: []
include: {files}
"""
# subdir to ensure parent of environment dir is not shared
e1_path = tmp_path / "e1_subdir" / "e1"
e1_manifest = e1_path / "spack.yaml"
fs.mkdirp(e1_path)
with open(e1_manifest, "w", encoding="utf-8") as f:
f.write(manifest)
for f in files:
fs.touchp(e1_path / f)
with pytest.raises(spack.config.ConfigFileError, match="Detected 1 missing include"):
_ = _env_create("test2", init_file=e1_manifest)
def test_env_view_external_prefix(tmp_path, mutable_database, mock_packages): def test_env_view_external_prefix(tmp_path, mutable_database, mock_packages):
fake_prefix = tmp_path / "a-prefix" fake_prefix = tmp_path / "a-prefix"
fake_bin = fake_prefix / "bin" fake_bin = fake_prefix / "bin"

View File

@@ -139,7 +139,7 @@ def test_gc_except_specific_environments(mutable_database, mutable_mock_env_path
def test_gc_except_nonexisting_dir_env(mutable_database, mutable_mock_env_path, tmpdir): def test_gc_except_nonexisting_dir_env(mutable_database, mutable_mock_env_path, tmpdir):
output = gc("-ye", tmpdir.strpath, fail_on_error=False) output = gc("-ye", tmpdir.strpath, fail_on_error=False)
assert "No such environment" in output assert "No such environment" in output
assert gc.returncode == 1 gc.returncode == 1
@pytest.mark.db @pytest.mark.db

View File

@@ -26,9 +26,9 @@ def test_manpath_trailing_colon(
else ("--sh", "export %s=%s", ";") else ("--sh", "export %s=%s", ";")
) )
# Test that the commands generated by load add the MANPATH prefix """Test that the commands generated by load add the MANPATH prefix
# inspections. Also test that Spack correctly preserves the default/existing inspections. Also test that Spack correctly preserves the default/existing
# manpath search path via a trailing colon manpath search path via a trailing colon"""
install("mpileaks") install("mpileaks")
sh_out = load(shell, "mpileaks") sh_out = load(shell, "mpileaks")
@@ -81,9 +81,7 @@ def extract_value(output, variable):
# Finally, do we list them in topo order? # Finally, do we list them in topo order?
for i, pkg in enumerate(pkgs): for i, pkg in enumerate(pkgs):
assert {s.name for s in mpileaks_spec[pkg].traverse(direction="parents")}.issubset( set(s.name for s in mpileaks_spec[pkg].traverse(direction="parents")) in set(pkgs[:i])
pkgs[: i + 1]
)
# Lastly, do we keep track that mpileaks was loaded? # Lastly, do we keep track that mpileaks was loaded?
assert ( assert (

View File

@@ -1,6 +1,17 @@
# Copyright Spack Project Developers. See COPYRIGHT file for details. # Copyright Spack Project Developers. See COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import pathlib
import pytest
import spack.concretize
import spack.config
import spack.environment as ev
import spack.paths
import spack.repo
import spack.spec
import spack.util.spack_yaml as syaml
""" """
These tests include the following package DAGs: These tests include the following package DAGs:
@@ -31,18 +42,6 @@
y y
""" """
import pathlib
import pytest
import spack.concretize
import spack.config
import spack.environment as ev
import spack.paths
import spack.repo
import spack.spec
import spack.util.spack_yaml as syaml
@pytest.fixture @pytest.fixture
def test_repo(mutable_config, monkeypatch, mock_stage): def test_repo(mutable_config, monkeypatch, mock_stage):

View File

@@ -458,7 +458,7 @@ def test_log_install_without_build_files(install_mockery):
spec = spack.concretize.concretize_one("trivial-install-test-package") spec = spack.concretize.concretize_one("trivial-install-test-package")
# Attempt installing log without the build log file # Attempt installing log without the build log file
with pytest.raises(OSError, match="No such file or directory"): with pytest.raises(IOError, match="No such file or directory"):
spack.installer.log(spec.package) spack.installer.log(spec.package)

View File

@@ -470,7 +470,7 @@ def _repoerr(repo, name):
# The call to install_tree will raise the exception since not mocking # The call to install_tree will raise the exception since not mocking
# creation of dependency package files within *install* directories. # creation of dependency package files within *install* directories.
with pytest.raises(OSError, match=path if sys.platform != "win32" else ""): with pytest.raises(IOError, match=path if sys.platform != "win32" else ""):
inst.dump_packages(spec, path) inst.dump_packages(spec, path)
# Now try the error path, which requires the mock directory structure # Now try the error path, which requires the mock directory structure

View File

@@ -82,7 +82,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(OSError, match="No such file or directory"): with pytest.raises(IOError, match="No such file or directory"):
fs.copy("source/none", "dest") fs.copy("source/none", "dest")
def test_multiple_src_file_dest(self, stage): def test_multiple_src_file_dest(self, stage):
@@ -139,7 +139,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(OSError, match="No such file or directory"): with pytest.raises(IOError, match="No such file or directory"):
fs.install("source/none", "dest") fs.install("source/none", "dest")
def test_multiple_src_file_dest(self, stage): def test_multiple_src_file_dest(self, stage):
@@ -220,7 +220,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(OSError, match="No such file or directory"): with pytest.raises(IOError, match="No such file or directory"):
fs.copy_tree("source/none", "dest") fs.copy_tree("source/none", "dest")
def test_parent_dir(self, stage): def test_parent_dir(self, stage):
@@ -301,7 +301,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(OSError, match="No such file or directory"): with pytest.raises(IOError, match="No such file or directory"):
fs.install_tree("source/none", "dest") fs.install_tree("source/none", "dest")
def test_parent_dir(self, stage): def test_parent_dir(self, stage):

View File

@@ -93,26 +93,28 @@
pass pass
#: This is a list of filesystem locations to test locks in. Paths are """This is a list of filesystem locations to test locks in. Paths are
#: expanded so that %u is replaced with the current username. '~' is also expanded so that %u is replaced with the current username. '~' is also
#: legal and will be expanded to the user's home directory. legal and will be expanded to the user's home directory.
#:
#: Tests are skipped for directories that don't exist, so you'll need to Tests are skipped for directories that don't exist, so you'll need to
#: update this with the locations of NFS, Lustre, and other mounts on your update this with the locations of NFS, Lustre, and other mounts on your
#: system. system.
"""
locations = [ locations = [
tempfile.gettempdir(), tempfile.gettempdir(),
os.path.join("/nfs/tmp2/", getpass.getuser()), os.path.join("/nfs/tmp2/", getpass.getuser()),
os.path.join("/p/lscratch*/", getpass.getuser()), os.path.join("/p/lscratch*/", getpass.getuser()),
] ]
#: This is the longest a failed multiproc test will take. """This is the longest a failed multiproc test will take.
#: Barriers will time out and raise an exception after this interval. Barriers will time out and raise an exception after this interval.
#: In MPI mode, barriers don't time out (they hang). See mpi_multiproc_test. In MPI mode, barriers don't time out (they hang). See mpi_multiproc_test.
"""
barrier_timeout = 5 barrier_timeout = 5
#: This is the lock timeout for expected failures. """This is the lock timeout for expected failures.
#: This may need to be higher for some filesystems. This may need to be higher for some filesystems."""
lock_fail_timeout = 0.1 lock_fail_timeout = 0.1
@@ -284,8 +286,9 @@ def wait(self):
comm.Barrier() # barrier after each MPI test. comm.Barrier() # barrier after each MPI test.
#: ``multiproc_test()`` should be called by tests below. """``multiproc_test()`` should be called by tests below.
#: ``multiproc_test()`` will work for either MPI runs or for local runs. ``multiproc_test()`` will work for either MPI runs or for local runs.
"""
multiproc_test = mpi_multiproc_test if mpi else local_multiproc_test multiproc_test = mpi_multiproc_test if mpi else local_multiproc_test
@@ -1336,7 +1339,7 @@ def test_poll_lock_exception(tmpdir, monkeypatch, err_num, err_msg):
"""Test poll lock exception handling.""" """Test poll lock exception handling."""
def _lockf(fd, cmd, len, start, whence): def _lockf(fd, cmd, len, start, whence):
raise OSError(err_num, err_msg) raise IOError(err_num, err_msg)
with tmpdir.as_cwd(): with tmpdir.as_cwd():
lockfile = "lockfile" lockfile = "lockfile"
@@ -1348,7 +1351,7 @@ def _lockf(fd, cmd, len, start, whence):
if err_num in [errno.EAGAIN, errno.EACCES]: if err_num in [errno.EAGAIN, errno.EACCES]:
assert not lock._poll_lock(fcntl.LOCK_EX) assert not lock._poll_lock(fcntl.LOCK_EX)
else: else:
with pytest.raises(OSError, match=err_msg): with pytest.raises(IOError, match=err_msg):
lock._poll_lock(fcntl.LOCK_EX) lock._poll_lock(fcntl.LOCK_EX)
monkeypatch.undo() monkeypatch.undo()

View File

@@ -238,7 +238,10 @@ def test_exclude(self, modulefile_content, module_configuration, host_architectu
assert len([x for x in content if "module load " in x]) == 1 assert len([x for x in content if "module load " in x]) == 1
with pytest.raises(FileNotFoundError): # Catch "Exception" to avoid using FileNotFoundError on Python 3
# and IOError on Python 2 or common bases like EnvironmentError
# which are not officially documented
with pytest.raises(Exception):
modulefile_content(f"callpath target={host_architecture_str}") modulefile_content(f"callpath target={host_architecture_str}")
content = modulefile_content(f"zmpi target={host_architecture_str}") content = modulefile_content(f"zmpi target={host_architecture_str}")

View File

@@ -132,8 +132,7 @@ def test_reporters_extract_skipped(state):
parts = spack.reporters.extract.extract_test_parts("fake", outputs) parts = spack.reporters.extract.extract_test_parts("fake", outputs)
assert len(parts) == 1 assert len(parts) == 1
parts[0]["completed"] == expected
assert parts[0]["completed"] == spack.reporters.extract.completed["skipped"]
def test_reporters_skip_new(): def test_reporters_skip_new():

View File

@@ -198,7 +198,7 @@ def script_dir(sbang_line):
], ],
) )
def test_shebang_interpreter_regex(shebang, interpreter): def test_shebang_interpreter_regex(shebang, interpreter):
assert sbang.get_interpreter(shebang) == interpreter sbang.get_interpreter(shebang) == interpreter
def test_shebang_handling(script_dir, sbang_line): def test_shebang_handling(script_dir, sbang_line):

View File

@@ -428,29 +428,31 @@ def test_copy_through_spec_build_interface(self):
c2 = s["mpileaks"]["mpileaks"].copy() c2 = s["mpileaks"]["mpileaks"].copy()
assert c0 == c1 == c2 == s assert c0 == c1 == c2 == s
# Here is the graph with deptypes labeled (assume all packages have a 'dt' """
# prefix). Arrows are marked with the deptypes ('b' for 'build', 'l' for Here is the graph with deptypes labeled (assume all packages have a 'dt'
# 'link', 'r' for 'run'). prefix). Arrows are marked with the deptypes ('b' for 'build', 'l' for
'link', 'r' for 'run').
# use -bl-> top use -bl-> top
# top -b-> build1 top -b-> build1
# top -bl-> link1 top -bl-> link1
# top -r-> run1 top -r-> run1
# build1 -b-> build2 build1 -b-> build2
# build1 -bl-> link2 build1 -bl-> link2
# build1 -r-> run2 build1 -r-> run2
# link1 -bl-> link3 link1 -bl-> link3
# run1 -bl-> link5 run1 -bl-> link5
# run1 -r-> run3 run1 -r-> run3
# link3 -b-> build2 link3 -b-> build2
# link3 -bl-> link4 link3 -bl-> link4
# run3 -b-> build3 run3 -b-> build3
"""
@pytest.mark.parametrize( @pytest.mark.parametrize(
"spec_str,deptypes,expected", "spec_str,deptypes,expected",

View File

@@ -125,7 +125,7 @@ def check_expand_archive(stage, stage_name, expected_file_list):
assert os.path.isfile(fn) assert os.path.isfile(fn)
with open(fn, encoding="utf-8") as _file: with open(fn, encoding="utf-8") as _file:
assert _file.read() == contents _file.read() == contents
def check_fetch(stage, stage_name): def check_fetch(stage, stage_name):

View File

@@ -154,7 +154,6 @@ def test_tag_no_tags(mock_packages):
def test_tag_update_package(mock_packages): def test_tag_update_package(mock_packages):
mock_index = mock_packages.tag_index mock_index = mock_packages.tag_index
index = spack.tag.TagIndex(repository=mock_packages) index = spack.tag.TagIndex(repository=mock_packages)
for name in spack.repo.all_package_names(): index.update_packages(set(spack.repo.all_package_names()))
index.update_package(name)
ensure_tags_results_equal(mock_index.tags, index.tags) ensure_tags_results_equal(mock_index.tags, index.tags)

View File

@@ -20,7 +20,12 @@
datadir = os.path.join(spack_root, "lib", "spack", "spack", "test", "data", "compression") datadir = os.path.join(spack_root, "lib", "spack", "spack", "test", "data", "compression")
ext_archive = {ext: f"Foo.{ext}" for ext in llnl.url.ALLOWED_ARCHIVE_TYPES if "TAR" not in ext} ext_archive = {}
[
ext_archive.update({ext: ".".join(["Foo", ext])})
for ext in llnl.url.ALLOWED_ARCHIVE_TYPES
if "TAR" not in ext
]
# Spack does not use Python native handling for tarballs or zip # Spack does not use Python native handling for tarballs or zip
# Don't test tarballs or zip in native test # Don't test tarballs or zip in native test
native_archive_list = [ native_archive_list = [

View File

@@ -204,13 +204,13 @@ def test_no_editor():
def assert_exec(exe, args): def assert_exec(exe, args):
assert False assert False
with pytest.raises(OSError, match=r"No text editor found.*"): with pytest.raises(EnvironmentError, match=r"No text editor found.*"):
ed.editor("/path/to/file", exec_fn=assert_exec) ed.editor("/path/to/file", exec_fn=assert_exec)
def assert_exec(exe, args): def assert_exec(exe, args):
return False return False
with pytest.raises(OSError, match=r"No text editor found.*"): with pytest.raises(EnvironmentError, match=r"No text editor found.*"):
ed.editor("/path/to/file", exec_fn=assert_exec) ed.editor("/path/to/file", exec_fn=assert_exec)
@@ -220,5 +220,5 @@ def test_exec_fn_executable(editor_var, good_exe, bad_exe):
assert ed.editor(exec_fn=ed.executable) assert ed.editor(exec_fn=ed.executable)
os.environ[editor_var] = bad_exe os.environ[editor_var] = bad_exe
with pytest.raises(OSError, match=r"No text editor found.*"): with pytest.raises(EnvironmentError, match=r"No text editor found.*"):
ed.editor(exec_fn=ed.executable) ed.editor(exec_fn=ed.executable)

View File

@@ -9,7 +9,7 @@
defined by the EDITOR environment variable if VISUAL is not set or the defined by the EDITOR environment variable if VISUAL is not set or the
specified editor fails (e.g. no DISPLAY for a graphical editor). If specified editor fails (e.g. no DISPLAY for a graphical editor). If
neither variable is set, we fall back to one of several common editors, neither variable is set, we fall back to one of several common editors,
raising an OSError if we are unable to find one. raising an EnvironmentError if we are unable to find one.
""" """
import os import os
import shlex import shlex
@@ -141,7 +141,7 @@ def try_env_var(var):
return True return True
# Fail if nothing could be found # Fail if nothing could be found
raise OSError( raise EnvironmentError(
"No text editor found! Please set the VISUAL and/or EDITOR " "No text editor found! Please set the VISUAL and/or EDITOR "
"environment variable(s) to your preferred text editor." "environment variable(s) to your preferred text editor."
) )

View File

@@ -46,7 +46,7 @@ def _process_ld_so_conf_queue(queue):
try: try:
with open(p, "rb") as f: with open(p, "rb") as f:
lines = f.readlines() lines = f.readlines()
except OSError: except (IOError, OSError):
continue continue
for line in lines: for line in lines:
@@ -132,7 +132,7 @@ def host_dynamic_linker_search_paths():
if os.path.exists(possible_conf): if os.path.exists(possible_conf):
conf_file = possible_conf conf_file = possible_conf
except (OSError, elf_utils.ElfParsingError): except (IOError, OSError, elf_utils.ElfParsingError):
pass pass
# Note: ld_so_conf doesn't error if the file does not exist. # Note: ld_so_conf doesn't error if the file does not exist.

View File

@@ -59,6 +59,11 @@ default:
SPACK_TARGET_PLATFORM: "linux" SPACK_TARGET_PLATFORM: "linux"
SPACK_TARGET_ARCH: "aarch64" SPACK_TARGET_ARCH: "aarch64"
.linux_power:
variables:
SPACK_TARGET_PLATFORM: "linux"
SPACK_TARGET_ARCH: "ppc64le"
.win64-msvc2019: .win64-msvc2019:
variables: variables:
SPACK_TARGET_PLATFORM: "win64" SPACK_TARGET_PLATFORM: "win64"
@@ -347,6 +352,35 @@ e4s-oneapi-build:
- artifacts: True - artifacts: True
job: e4s-oneapi-generate job: e4s-oneapi-generate
########################################
# E4S on Power
########################################
.e4s-power-generate-tags-and-image:
image: { "name": "ghcr.io/spack/ubuntu20.04-runner-ppc64-gcc-11.4:2023.08.01", "entrypoint": [""] }
tags: ["spack", "public", "large", "ppc64le"]
.e4s-power:
extends: [".linux_power"]
variables:
SPACK_CI_STACK_NAME: e4s-power
e4s-power-generate:
extends: [ ".e4s-power", ".generate-x86_64", ".e4s-power-generate-tags-and-image"]
variables:
# Override concretization pool for metal runners
SPACK_CONCRETIZE_JOBS: 16
e4s-power-build:
extends: [ ".e4s-power", ".build" ]
trigger:
include:
- artifact: jobs_scratch_dir/cloud-ci-pipeline.yml
job: e4s-power-generate
strategy: depend
needs:
- artifacts: True
job: e4s-power-generate
######################################### #########################################
# Build tests for different build-systems # Build tests for different build-systems
######################################### #########################################

View File

@@ -0,0 +1,22 @@
ci:
pipeline-gen:
- build-job:
tags: ["ppc64le"]
# Power runners overrides the default script
# - don't download make
# - no intermediate keys
script::
- uname -a || true
- grep -E 'vendor|model name' /proc/cpuinfo 2>/dev/null | sort -u || head -n10 /proc/cpuinfo 2>/dev/null || true
- nproc
- . "./share/spack/setup-env.sh"
- spack --version
- spack arch
- cd ${SPACK_CONCRETE_ENV_DIR}
- spack env activate --without-view .
- if [ -n "$SPACK_BUILD_JOBS" ]; then spack config add "config:build_jobs:$SPACK_BUILD_JOBS"; fi
- spack config add "config:install_tree:projections:${SPACK_JOB_SPEC_PKG_NAME}:'morepadding/{architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}'"
- mkdir -p ${SPACK_ARTIFACTS_ROOT}/user_data
- if [[ -r /mnt/key/e4s.gpg ]]; then spack gpg trust /mnt/key/e4s.gpg; fi
- if [[ -r /mnt/key/spack_public_key.gpg ]]; then spack gpg trust /mnt/key/spack_public_key.gpg; fi
- spack --color=always --backtrace ci rebuild > >(tee ${SPACK_ARTIFACTS_ROOT}/user_data/pipeline_out.txt) 2> >(tee ${SPACK_ARTIFACTS_ROOT}/user_data/pipeline_err.txt >&2)

View File

@@ -0,0 +1,3 @@
concretizer:
targets:
granularity: generic

View File

@@ -0,0 +1,271 @@
spack:
view: false
concretizer:
reuse: false
unify: false
packages:
all:
require: "%gcc@9.4.0 target=ppc64le"
compiler: [gcc@9.4.0]
providers:
blas: [openblas]
mpi: [mpich]
variants: +mpi cuda_arch=70
binutils:
variants: +ld +gold +headers +libiberty ~nls
hdf5:
variants: +fortran +hl +shared
libfabric:
variants: fabrics=sockets,tcp,udp,rxm
openblas:
variants: threads=openmp
trilinos:
variants: +amesos +amesos2 +anasazi +aztec +belos +boost +epetra +epetraext
+ifpack +ifpack2 +intrepid +intrepid2 +isorropia +kokkos +ml +minitensor +muelu
+nox +piro +phalanx +rol +rythmos +sacado +stk +shards +shylu +stokhos +stratimikos
+teko +tempus +tpetra +trilinoscouplings +zoltan +zoltan2 +superlu-dist gotype=long_long
xz:
variants: +pic
mpi:
require: mpich
mpich:
require: '~wrapperrpath ~hwloc %gcc@9.4.0 target=ppc64le'
ncurses:
require: '@6.3 +termlib %gcc@9.4.0 target=ppc64le'
faodel:
require: "~tcmalloc %gcc@9.4.0 target=ppc64le"
tbb:
require: intel-tbb
vtk-m:
require: "+examples %gcc@9.4.0 target=ppc64le"
cuda:
require: "@11.4.4 %gcc@9.4.0 target=ppc64le"
paraview:
require: "+examples %gcc@9.4.0 target=ppc64le"
specs:
# CPU
- adios
- alquimia
- aml
- amrex
- arborx
- argobots
- axom
- bolt
- boost
- bricks
- butterflypack
- cabana
- caliper
- chai
- chapel ~rocm ~cuda
- charliecloud
- conduit
- cp2k +mpi
- datatransferkit
- drishti
- dxt-explorer
- dyninst
- exaworks
- fftx
- flecsi
- flit
- flux-core
- fortrilinos
- gasnet
- ginkgo
- globalarrays
- gmp
- gotcha
- gptune
- gromacs +cp2k ^cp2k +mpi build_system=cmake
- h5bench
- hdf5-vol-async
- hdf5-vol-cache
- hdf5-vol-log
- heffte +fftw
- hpctoolkit
- hpx networking=mpi
- hypre
- kokkos +openmp
- kokkos-kernels +openmp
- laghos
- lammps
- lbann
- legion
- libnrm
- libquo
- libunwind
- loki
- mercury
- metall
- mfem
- mgard +serial +openmp +timing +unstructured ~cuda
- mpark-variant
- mpifileutils ~xattr
- nccmp
- nco
- netlib-scalapack
- nrm
- nvhpc
- nwchem
- omega-h
- openfoam
- openmpi
- openpmd-api
- papi
- papyrus
- paraview ~cuda ~rocm
- parsec ~cuda
- pdt
- petsc
- plasma
- plumed
- precice
- pruners-ninja
- pumi
- py-amrex
- py-h5py
- py-jupyterhub
- py-libensemble
- py-petsc4py
- qthreads scheduler=distrib
- quantum-espresso
- raja
- rempi
- scr
- slate ~cuda
- slepc
- stc
- strumpack ~slate
- sundials
- superlu
- superlu-dist
- swig@4.0.2-fortran
- sz3
- tasmanian
- tau +mpi +python # +syscall fails: https://github.com/spack/spack/pull/40830#issuecomment-1790799772; tau: has issue with `spack env depfile` build
- trilinos +amesos +amesos2 +anasazi +aztec +belos +boost +epetra +epetraext +ifpack +ifpack2 +intrepid +intrepid2 +isorropia +kokkos +ml +minitensor +muelu +nox +piro +phalanx +rol +rythmos +sacado +stk +shards +shylu +stokhos +stratimikos +teko +tempus +tpetra +trilinoscouplings +zoltan +zoltan2 +superlu-dist gotype=long_long
- turbine
- umap
- umpire
- upcxx
- wannier90
- warpx +python
- wps
- wrf
- xyce +mpi +shared +pymi +pymi_static_tpls
# INCLUDED IN ECP DAV CPU
- adios2
- ascent
- darshan-runtime
- darshan-util
- faodel
- hdf5
- libcatalyst
- parallel-netcdf
- py-cinemasci
- sz
- unifyfs
- veloc
# - visit # libext, libxkbfile, libxrender, libxt, silo (https://github.com/spack/spack/issues/39538), cairo
- vtk-m
- zfp
# - ecp-data-vis-sdk ~cuda ~rocm +adios2 +ascent +cinema +darshan +faodel +hdf5 ~paraview +pnetcdf +sz +unifyfs +veloc ~visit +vtkm +zfp # +visit: libext, libxkbfile, libxrender, libxt, silo (https://github.com/spack/spack/issues/39538), cairo
# --
# - dealii # fltk: https://github.com/spack/spack/issues/38791
# - geopm-runtime # cairo: *** No autoreconf found, please install it ***
# - glvis # glvis: https://github.com/spack/spack/issues/42839
# - libpressio +bitgrooming +bzip2 ~cuda ~cusz +fpzip +hdf5 +libdistributed +lua +openmp +python +sz +sz3 +unix +zfp # py-numcodecs: gcc: error: unrecognized command line option '-mno-sse2'; did you mean '-mno-isel'? gcc: error: unrecognized command line option '-mno-avx2'
# - phist +mpi # ghost@develop: gcc-9: error: unrecognized command line option '-march=native'; did you mean '-mcpu=native'?
# - variorum # variorum: https://github.com/spack/spack/issues/38786
# PYTHON PACKAGES
- opencv +python3
- py-jax
- py-jupyterlab
- py-matplotlib
- py-mpi4py
- py-notebook
- py-numba
- py-numpy
- py-openai
- py-pandas
- py-plotly
- py-pooch
- py-pytest
- py-scikit-learn
- py-scipy
- py-seaborn
# - py-horovod # py-torch, py-tensorflow
# - py-tensorflow # error
# - py-torch # error
# CUDA NOARCH
- bricks +cuda
- cabana +cuda ^kokkos +wrapper +cuda_lambda +cuda cuda_arch=70
- flux-core +cuda
- hpctoolkit +cuda
- papi +cuda
- tau +mpi +cuda
# --
# - legion +cuda # legion: needs NVIDIA driver
# CUDA 70
- amrex +cuda cuda_arch=70
- arborx +cuda cuda_arch=70 ^kokkos +wrapper
- caliper +cuda cuda_arch=70
- chai +cuda cuda_arch=70 ^umpire ~shared
- ecp-data-vis-sdk ~rocm +adios2 ~ascent +hdf5 +vtkm +zfp ~paraview +cuda cuda_arch=70
- exago +mpi +python +raja +hiop ~rocm +cuda cuda_arch=70 ~ipopt ^hiop@1.0.0 ~sparse +mpi +raja ~rocm +cuda cuda_arch=70 #^raja@0.14.0
- flecsi +cuda cuda_arch=70
- ginkgo +cuda cuda_arch=70
- gromacs +cuda cuda_arch=70
- heffte +cuda cuda_arch=70
- hpx +cuda cuda_arch=70
- hypre +cuda cuda_arch=70
- kokkos +wrapper +cuda cuda_arch=70
- kokkos-kernels +cuda cuda_arch=70 ^kokkos +wrapper +cuda cuda_arch=70
- magma +cuda cuda_arch=70
- mfem +cuda cuda_arch=70
- mgard +serial +openmp +timing +unstructured +cuda cuda_arch=70
- omega-h +cuda cuda_arch=70
- parsec +cuda cuda_arch=70
- petsc +cuda cuda_arch=70
- raja +cuda cuda_arch=70
- slate +cuda cuda_arch=70
- slepc +cuda cuda_arch=70
- strumpack ~slate +cuda cuda_arch=70
- sundials +cuda cuda_arch=70
- superlu-dist +cuda cuda_arch=70
- tasmanian +cuda cuda_arch=70
- umpire ~shared +cuda cuda_arch=70
# INCLUDED IN ECP DAV CUDA
- adios2 +cuda cuda_arch=70
# - ascent +cuda cuda_arch=70 # ascent: https://github.com/spack/spack/issues/38045
- paraview +cuda cuda_arch=70
- vtk-m +cuda cuda_arch=70
- zfp +cuda cuda_arch=70
# --
# - axom +cuda cuda_arch=70 # axom: https://github.com/spack/spack/issues/29520
# - cp2k +mpi +cuda cuda_arch=70 # dbcsr
# - cusz +cuda cuda_arch=70 # cusz: https://github.com/spack/spack/issues/38787
# - dealii +cuda cuda_arch=70 # fltk: https://github.com/spack/spack/issues/38791
# - lammps +cuda cuda_arch=70 # lammps: needs NVIDIA driver
# - lbann +cuda cuda_arch=70 # lbann: https://github.com/spack/spack/issues/38788
# - libpressio +bitgrooming +bzip2 +fpzip +hdf5 +libdistributed +lua +openmp +python +sz +sz3 +unix +zfp +json +remote +netcdf +cusz +mgard +cuda cuda_arch=70 ^cusz +cuda cuda_arch=70 # depends_on("cuda@11.7.1:", when="+cuda")
# - py-torch +cuda cuda_arch=70 # skipped
# - trilinos +cuda cuda_arch=70 # trilinos: https://github.com/trilinos/Trilinos/issues/11630
# - upcxx +cuda cuda_arch=70 # upcxx: needs NVIDIA driver
ci:
pipeline-gen:
- build-job:
image: ghcr.io/spack/ubuntu20.04-runner-ppc64-gcc-11.4:2023.08.01
cdash:
build-group: E4S Power

View File

@@ -100,8 +100,10 @@ def install(self, spec, prefix):
for ext in exts: for ext in exts:
glob_str = os.path.join(pth, ext) glob_str = os.path.join(pth, ext)
files = glob.glob(glob_str) files = glob.glob(glob_str)
for x in files: [
shutil.copy( shutil.copy(
os.path.join(self._7z_src_dir, x), os.path.join(self._7z_src_dir, x),
os.path.join(prefix, os.path.basename(x)), os.path.join(prefix, os.path.basename(x)),
) )
for x in files
]

View File

@@ -179,7 +179,7 @@ def configure_args(self):
if spec.satisfies("@:8"): if spec.satisfies("@:8"):
oapp("--with-dft-flavor=atompaw+libxc") oapp("--with-dft-flavor=atompaw+libxc")
else: else:
oapp("--without-wannier90") "--without-wannier90",
if spec.satisfies("+mpi"): if spec.satisfies("+mpi"):
oapp(f"CC={spec['mpi'].mpicc}") oapp(f"CC={spec['mpi'].mpicc}")

View File

@@ -5,8 +5,11 @@
import inspect import inspect
import os import os
import llnl.util.tty as tty
import spack.pkg.builtin.openfoam as openfoam import spack.pkg.builtin.openfoam as openfoam
from spack.package import * from spack.package import *
from spack.version import Version
class Additivefoam(Package): class Additivefoam(Package):

View File

@@ -202,8 +202,8 @@ def configure_args(self):
args.append("--enable-void-return-complex") args.append("--enable-void-return-complex")
if spec.satisfies("@3.0:3.1 %aocc"): if spec.satisfies("@3.0:3.1 %aocc"):
# To enable Fortran to C calling convention for complex types when compiling with """To enabled Fortran to C calling convention for
# aocc flang complex types when compiling with aocc flang"""
args.append("--enable-f2c-dotc") args.append("--enable-f2c-dotc")
if spec.satisfies("@3.0.1: +ilp64"): if spec.satisfies("@3.0.1: +ilp64"):

View File

@@ -140,7 +140,8 @@ def cmake_args(self):
if spec.satisfies("+torch"): if spec.satisfies("+torch"):
args.append("-DWITH_TORCH=On") args.append("-DWITH_TORCH=On")
args.append( args.append(
"-DTorch_DIR={0}/lib/python{1}/site-packages/torch/share/cmake/Torch".format( "-DTorch_DIR={0}/lib/python{1}/site-packages"
"/torch/share/cmake/Torch".format(
spec["py-torch"].prefix, spec["python"].version.up_to(2) spec["py-torch"].prefix, spec["python"].version.up_to(2)
) )
) )

View File

@@ -6,6 +6,7 @@
from os.path import split from os.path import split
from spack.package import * from spack.package import *
from spack.util.environment import EnvironmentModifications
class Anaconda3(Package): class Anaconda3(Package):

View File

@@ -2,6 +2,7 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
from llnl.util import tty
from spack.package import * from spack.package import *
from spack.pkg.builtin.llvm import LlvmDetection from spack.pkg.builtin.llvm import LlvmDetection

View File

@@ -5,6 +5,7 @@
import os import os
from spack.package import * from spack.package import *
from spack.util.environment import EnvironmentModifications
class AoclDa(CMakePackage): class AoclDa(CMakePackage):

View File

@@ -6,6 +6,8 @@
import os import os
import socket import socket
import llnl.util.tty as tty
from spack.build_systems.cmake import CMakeBuilder from spack.build_systems.cmake import CMakeBuilder
from spack.package import * from spack.package import *

View File

@@ -3,6 +3,8 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import llnl.util.tty as tty
from spack.package import * from spack.package import *
from spack.util.environment import set_env from spack.util.environment import set_env

View File

@@ -54,7 +54,7 @@ class Armcomputelibrary(SConsPackage):
variant( variant(
"multi_isa", "multi_isa",
default=False, default=False,
description="Build Multi ISA binary version of library. Note works only for armv8.2-a.", description="Build Multi ISA binary version of library." " Note works only for armv8.2-a.",
) )
variant( variant(
"target_arch", "target_arch",

View File

@@ -9,6 +9,8 @@
import sys import sys
from os import environ as env from os import environ as env
import llnl.util.tty as tty
from spack.package import * from spack.package import *

View File

@@ -61,7 +61,7 @@ class Atlas(Package):
"tune_cpu", "tune_cpu",
default=-1, default=-1,
multi=False, multi=False,
description="Number of threads to tune to, -1 for autodetect, 0 for no threading", description="Number of threads to tune to, " "-1 for autodetect, 0 for no threading",
) )
conflicts( conflicts(

View File

@@ -8,9 +8,9 @@
def async_api_validator(pkg_name, variant_name, values): def async_api_validator(pkg_name, variant_name, values):
if "none" in values and len(values) != 1: if "none" in values and len(values) != 1:
raise SpackError("The value 'none' is not usable with other async_api values.") raise SpackError("The value 'none' is not usable" " with other async_api values.")
if "intel_cppr" in values and "cray_dw" in values: if "intel_cppr" in values and "cray_dw" in values:
raise SpackError("The 'intel_cppr' and 'cray_dw' asynchronous APIs are incompatible.") raise SpackError("The 'intel_cppr' and 'cray_dw' asynchronous" " APIs are incompatible.")
class Axl(CMakePackage): class Axl(CMakePackage):

View File

@@ -376,7 +376,9 @@ def initconfig_hardware_entries(self):
if "+fortran" in spec and self.is_fortran_compiler("xlf"): if "+fortran" in spec and self.is_fortran_compiler("xlf"):
# Grab lib directory for the current fortran compiler # Grab lib directory for the current fortran compiler
libdir = pjoin(os.path.dirname(os.path.dirname(self.compiler.fc)), "lib") libdir = pjoin(os.path.dirname(os.path.dirname(self.compiler.fc)), "lib")
description = "Adds a missing rpath for libraries associated with the fortran compiler" description = (
"Adds a missing rpath for libraries " "associated with the fortran compiler"
)
linker_flags = "${BLT_EXE_LINKER_FLAGS} -Wl,-rpath," + libdir linker_flags = "${BLT_EXE_LINKER_FLAGS} -Wl,-rpath," + libdir

View File

@@ -42,7 +42,7 @@ class Bcftools(AutotoolsPackage):
variant( variant(
"libgsl", "libgsl",
default=False, default=False,
description="build options that require the GNU scientific library", description="build options that require the GNU scientific " "library",
) )
variant( variant(

View File

@@ -5,6 +5,8 @@
import glob import glob
import os import os
import llnl.util.tty as tty
from spack.package import * from spack.package import *
from spack.pkg.builtin.boost import Boost from spack.pkg.builtin.boost import Boost

View File

@@ -160,11 +160,8 @@ class Binutils(AutotoolsPackage, GNUMirrorPackage):
with when("platform=darwin"): with when("platform=darwin"):
conflicts("+gold", msg="Binutils cannot build linkers on macOS") conflicts("+gold", msg="Binutils cannot build linkers on macOS")
# 2.41 doesn't seem to have any problems.
conflicts( conflicts(
"libs=shared", "libs=shared", when="@2.37:2.40", msg="https://github.com/spack/spack/issues/35817"
when="@2.37:2.40,2.42:",
msg="https://github.com/spack/spack/issues/35817",
) )
conflicts( conflicts(

View File

@@ -38,7 +38,7 @@ def llnl_link_helpers(options, spec, compiler):
options.append(cmake_cache_string("BLT_EXE_LINKER_FLAGS", flags, description)) options.append(cmake_cache_string("BLT_EXE_LINKER_FLAGS", flags, description))
if "cce" in compiler.cxx: if "cce" in compiler.cxx:
description = "Adds a missing rpath for libraries associated with the fortran compiler" description = "Adds a missing rpath for libraries " "associated with the fortran compiler"
# Here is where to find libs that work for fortran # Here is where to find libs that work for fortran
libdir = "/opt/cray/pe/cce/{0}/cce-clang/x86_64/lib".format(compiler.version) libdir = "/opt/cray/pe/cce/{0}/cce-clang/x86_64/lib".format(compiler.version)
linker_flags = "${{BLT_EXE_LINKER_FLAGS}} -Wl,-rpath,{0}".format(libdir) linker_flags = "${{BLT_EXE_LINKER_FLAGS}} -Wl,-rpath,{0}".format(libdir)

View File

@@ -4,6 +4,8 @@
import os import os
import llnl.util.tty as tty
from spack.package import * from spack.package import *
from spack.package_test import compare_output from spack.package_test import compare_output
from spack.pkg.builtin.boost import Boost from spack.pkg.builtin.boost import Boost
@@ -40,7 +42,9 @@ class Bohrium(CMakePackage, CudaPackage):
variant("node", default=True, description="Build the node vector engine manager") variant("node", default=True, description="Build the node vector engine manager")
variant("proxy", default=False, description="Build the proxy vector engine manager") variant("proxy", default=False, description="Build the proxy vector engine manager")
variant( variant(
"python", default=True, description="Build the numpy-like bridge to enable use from python" "python",
default=True,
description="Build the numpy-like bridge " "to enable use from python",
) )
variant("cbridge", default=True, description="Build the bridge interface towards plain C") variant("cbridge", default=True, description="Build the bridge interface towards plain C")

View File

@@ -237,7 +237,7 @@ def libs(self):
values=("global", "protected", "hidden"), values=("global", "protected", "hidden"),
default="hidden", default="hidden",
multi=False, multi=False,
description="Default symbol visibility in compiled libraries (1.69.0 or later)", description="Default symbol visibility in compiled libraries " "(1.69.0 or later)",
) )
# Unicode support # Unicode support

View File

@@ -53,7 +53,7 @@ class Bzip2(Package, SourcewarePackage):
@classmethod @classmethod
def determine_version(cls, exe): def determine_version(cls, exe):
output = Executable(exe)("--help", output=str, error=str) output = Executable(exe)("--help", output=str, error=str)
match = re.search(r"bzip2, a block-sorting file compressor. Version ([^,]+)", output) match = re.search(r"bzip2, a block-sorting file compressor." " Version ([^,]+)", output)
return match.group(1) if match else None return match.group(1) if match else None
# override default implementation # override default implementation

View File

@@ -71,7 +71,7 @@ class Care(CachedCMakePackage, CudaPackage, ROCmPackage):
variant( variant(
"implicit_conversions", "implicit_conversions",
default=False, default=False,
description="Enable implicit conversions to/from raw pointers", description="Enable implicit" "conversions to/from raw pointers",
) )
variant("tests", default=False, description="Build tests") variant("tests", default=False, description="Build tests")
variant("benchmarks", default=False, description="Build benchmarks.") variant("benchmarks", default=False, description="Build benchmarks.")

View File

@@ -61,7 +61,7 @@ class CcsQcd(MakefilePackage):
def edit(self, spec, prefix): def edit(self, spec, prefix):
if spec.satisfies("%gcc") and spec.satisfies("arch=aarch64:"): if spec.satisfies("%gcc") and spec.satisfies("arch=aarch64:"):
chgopt = ( chgopt = (
"FFLAGS =-O3 -ffixed-line-length-132 -g -fopenmp -mcmodel=large -funderscoring" "FFLAGS =-O3 -ffixed-line-length-132 -g -fopenmp" " -mcmodel=large -funderscoring"
) )
filter_file( filter_file(
"FFLAGS =.*", "FFLAGS =.*",

View File

@@ -19,11 +19,6 @@ class Cdo(AutotoolsPackage):
maintainers("skosukhin", "Try2Code") maintainers("skosukhin", "Try2Code")
version(
"2.5.0",
sha256="e865c05c1b52fd76b80e33421554db81b38b75210820bdc40e8690f4552f68e2",
url="https://code.mpimet.mpg.de/attachments/download/29786/cdo-2.5.0.tar.gz",
)
version( version(
"2.4.4", "2.4.4",
sha256="49f50bd18dacd585e9518cfd4f55548f692426edfb3b27ddcd1c653eab53d063", sha256="49f50bd18dacd585e9518cfd4f55548f692426edfb3b27ddcd1c653eab53d063",

View File

@@ -131,7 +131,7 @@ class Cgal(CMakePackage):
conflicts( conflicts(
"~header_only", "~header_only",
when="@:4.9", when="@:4.9",
msg="Header only builds became optional in 4.9, default thereafter", msg="Header only builds became optional in 4.9," " default thereafter",
) )
def url_for_version(self, version): def url_for_version(self, version):

View File

@@ -351,7 +351,7 @@ def install(self, spec, prefix):
# This is a Charm++ limitation; it would lead to a # This is a Charm++ limitation; it would lead to a
# build error # build error
raise InstallError( raise InstallError(
"The +tcp variant requires the backend=netlrts communication mechanism" "The +tcp variant requires " "the backend=netlrts communication mechanism"
) )
options.append("tcp") options.append("tcp")
if spec.satisfies("+omp"): if spec.satisfies("+omp"):
@@ -396,7 +396,7 @@ def install(self, spec, prefix):
copy(filepath, tmppath) copy(filepath, tmppath)
os.remove(filepath) os.remove(filepath)
os.rename(tmppath, filepath) os.rename(tmppath, filepath)
except OSError: except (IOError, OSError):
pass pass
tmp_path = join_path(builddir, "tmp") tmp_path = join_path(builddir, "tmp")

View File

@@ -8,6 +8,7 @@
import spack.user_environment import spack.user_environment
from spack.package import * from spack.package import *
from spack.pkg.builtin.clingo import Clingo from spack.pkg.builtin.clingo import Clingo
from spack.util.environment import EnvironmentModifications
class ClingoBootstrap(Clingo): class ClingoBootstrap(Clingo):

View File

@@ -30,13 +30,11 @@ class Cmake(Package):
license("BSD-3-Clause") license("BSD-3-Clause")
version("master", branch="master") version("master", branch="master")
version("3.31.5", sha256="66fb53a145648be56b46fa9e8ccade3a4d0dfc92e401e52ce76bdad1fea43d27")
version("3.31.4", sha256="a6130bfe75f5ba5c73e672e34359f7c0a1931521957e8393a5c2922c8b0f7f25") version("3.31.4", sha256="a6130bfe75f5ba5c73e672e34359f7c0a1931521957e8393a5c2922c8b0f7f25")
version("3.31.3", sha256="fac45bc6d410b49b3113ab866074888d6c9e9dc81a141874446eb239ac38cb87") version("3.31.3", sha256="fac45bc6d410b49b3113ab866074888d6c9e9dc81a141874446eb239ac38cb87")
version("3.31.2", sha256="42abb3f48f37dbd739cdfeb19d3712db0c5935ed5c2aef6c340f9ae9114238a2") version("3.31.2", sha256="42abb3f48f37dbd739cdfeb19d3712db0c5935ed5c2aef6c340f9ae9114238a2")
version("3.31.1", sha256="c4fc2a9bd0cd5f899ccb2fb81ec422e175090bc0de5d90e906dd453b53065719") version("3.31.1", sha256="c4fc2a9bd0cd5f899ccb2fb81ec422e175090bc0de5d90e906dd453b53065719")
version("3.31.0", sha256="300b71db6d69dcc1ab7c5aae61cbc1aa2778a3e00cbd918bc720203e311468c3") version("3.31.0", sha256="300b71db6d69dcc1ab7c5aae61cbc1aa2778a3e00cbd918bc720203e311468c3")
version("3.30.7", sha256="470e44d9c7caa3bd869ef953071b84f565b5d378d0a9eccbbbcd72031f21b9de")
version("3.30.6", sha256="a7aa25cdd8545156fe0fec95ebbd53cb2b5173a8717e227f6e8a755185c168cf") version("3.30.6", sha256="a7aa25cdd8545156fe0fec95ebbd53cb2b5173a8717e227f6e8a755185c168cf")
version("3.30.5", sha256="9f55e1a40508f2f29b7e065fa08c29f82c402fa0402da839fffe64a25755a86d") version("3.30.5", sha256="9f55e1a40508f2f29b7e065fa08c29f82c402fa0402da839fffe64a25755a86d")
version("3.30.4", sha256="c759c97274f1e7aaaafcb1f0d261f9de9bf3a5d6ecb7e2df616324a46fe704b2") version("3.30.4", sha256="c759c97274f1e7aaaafcb1f0d261f9de9bf3a5d6ecb7e2df616324a46fe704b2")

View File

@@ -31,9 +31,11 @@ def edit(self, spec, prefix):
# Replace -fopenmp with self.compiler.openmp_flag # Replace -fopenmp with self.compiler.openmp_flag
makefile.filter("-fopenmp", self.compiler.openmp_flag) makefile.filter("-fopenmp", self.compiler.openmp_flag)
# Replace CXX with CXXFLAGS # Replace CXX with CXXFLAGS
cxx11_flag = self.compiler.cxx11_flag
makefile.filter( makefile.filter(
"CXX.*=.*", rf"CXXFLAGS = -DCNVNATOR_VERSION=\"$(VERSION)\" $(OMPFLAGS) {cxx11_flag}" "CXX.*=.*",
r"CXXFLAGS = -DCNVNATOR_VERSION=\"$(VERSION)\""
" $(OMPFLAGS)"
" {0}".format(self.compiler.cxx11_flag),
) )
makefile.filter("$(CXX)", "$(CXX) $(CXXFLAGS)", string=True) makefile.filter("$(CXX)", "$(CXX) $(CXXFLAGS)", string=True)
# Replace -I$(SAMDIR) with -I$(SAMINC) # Replace -I$(SAMDIR) with -I$(SAMINC)

View File

@@ -3,6 +3,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.package import * from spack.package import *
from spack.util.environment import EnvironmentModifications
class Conda4aarch64(Package): class Conda4aarch64(Package):

View File

@@ -8,6 +8,8 @@
import socket import socket
from os import environ as env from os import environ as env
import llnl.util.tty as tty
from spack.package import * from spack.package import *

View File

@@ -78,7 +78,9 @@ def install(self, spec, prefix):
# rewrite the Makefile to use Spack's options all the time # rewrite the Makefile to use Spack's options all the time
if spec.satisfies("%gcc"): if spec.satisfies("%gcc"):
if not spec.satisfies("%gcc@6:"): if not spec.satisfies("%gcc@6:"):
raise InstallError("When using GCC, CosmoMC requires version gcc@6: for building") raise InstallError(
"When using GCC, " "CosmoMC requires version gcc@6: for building"
)
choosecomp = "ifortErr=1" # choose gfortran choosecomp = "ifortErr=1" # choose gfortran
elif spec.satisfies("%intel"): elif spec.satisfies("%intel"):
if not spec.satifies("%intel@14:"): if not spec.satifies("%intel@14:"):

View File

@@ -116,7 +116,6 @@ class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage):
variant("pytorch", default=False, description="Enable libtorch support") variant("pytorch", default=False, description="Enable libtorch support")
variant("quip", default=False, description="Enable quip support") variant("quip", default=False, description="Enable quip support")
variant("mpi_f08", default=False, description="Use MPI F08 module") variant("mpi_f08", default=False, description="Use MPI F08 module")
variant("smeagol", default=False, description="Enable libsmeagol support", when="@2025.2:")
variant( variant(
"enable_regtests", "enable_regtests",
@@ -261,8 +260,6 @@ class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage):
depends_on("plumed+mpi", when="+mpi") depends_on("plumed+mpi", when="+mpi")
depends_on("plumed~mpi", when="~mpi") depends_on("plumed~mpi", when="~mpi")
depends_on("libsmeagol", when="+smeagol")
# while we link statically against PEXSI, its own deps may be linked in # while we link statically against PEXSI, its own deps may be linked in
# dynamically, therefore can't set this as pure build-type dependency. # dynamically, therefore can't set this as pure build-type dependency.
depends_on("pexsi+fortran@0.10.0:", when="+pexsi") depends_on("pexsi+fortran@0.10.0:", when="+pexsi")
@@ -624,12 +621,6 @@ def edit(self, pkg, spec, prefix):
ldflags += [spglib.search_flags] ldflags += [spglib.search_flags]
libs.append(spglib.ld_flags) libs.append(spglib.ld_flags)
if spec.satisfies("+smeagol"):
cppflags += ["-D__SMEAGOL"]
smeagol = spec["libsmeagol"].libs
ldflags += [smeagol.search_flags]
libs.append(smeagol.ld_flags)
cc = spack_cc if "~mpi" in spec else spec["mpi"].mpicc cc = spack_cc if "~mpi" in spec else spec["mpi"].mpicc
cxx = spack_cxx if "~mpi" in spec else spec["mpi"].mpicxx cxx = spack_cxx if "~mpi" in spec else spec["mpi"].mpicxx
fc = spack_fc if "~mpi" in spec else spec["mpi"].mpifc fc = spack_fc if "~mpi" in spec else spec["mpi"].mpifc
@@ -772,8 +763,8 @@ def edit(self, pkg, spec, prefix):
"Point environment variable LIBSMM_PATH to " "Point environment variable LIBSMM_PATH to "
"the absolute path of the libsmm.a file" "the absolute path of the libsmm.a file"
) )
except OSError: except IOError:
raise OSError( raise IOError(
"The file LIBSMM_PATH pointed to does not " "The file LIBSMM_PATH pointed to does not "
"exist. Note that it must be absolute path." "exist. Note that it must be absolute path."
) )
@@ -801,10 +792,9 @@ def edit(self, pkg, spec, prefix):
mkf.write("include {0}\n".format(self.pkg["plumed"].plumed_inc)) mkf.write("include {0}\n".format(self.pkg["plumed"].plumed_inc))
mkf.write("\n# COMPILER, LINKER, TOOLS\n\n") mkf.write("\n# COMPILER, LINKER, TOOLS\n\n")
mkf.write(f"FC = {fc}\n") mkf.write(
mkf.write(f"CC = {cc}\n") "FC = {0}\n" "CC = {1}\n" "CXX = {2}\n" "LD = {3}\n".format(fc, cc, cxx, fc)
mkf.write(f"CXX = {cxx}\n") )
mkf.write(f"LD = {fc}\n")
if spec.satisfies("%intel"): if spec.satisfies("%intel"):
intel_bin_dir = ancestor(pkg.compiler.cc) intel_bin_dir = ancestor(pkg.compiler.cc)
@@ -1005,7 +995,6 @@ def cmake_args(self):
self.define_from_variant("CP2K_USE_SPLA", "spla"), self.define_from_variant("CP2K_USE_SPLA", "spla"),
self.define_from_variant("CP2K_USE_QUIP", "quip"), self.define_from_variant("CP2K_USE_QUIP", "quip"),
self.define_from_variant("CP2K_USE_MPI_F08", "mpi_f08"), self.define_from_variant("CP2K_USE_MPI_F08", "mpi_f08"),
self.define_from_variant("CP2K_USE_LIBSMEAGOL", "smeagol"),
] ]
# we force the use elpa openmp threading support. might need to be revisited though # we force the use elpa openmp threading support. might need to be revisited though

View File

@@ -7,6 +7,8 @@
import re import re
from glob import glob from glob import glob
import llnl.util.tty as tty
from spack.package import * from spack.package import *
# FIXME Remove hack for polymorphic versions # FIXME Remove hack for polymorphic versions
@@ -739,7 +741,7 @@ def install(self, spec, prefix):
os.remove("/tmp/cuda-installer.log") os.remove("/tmp/cuda-installer.log")
except OSError: except OSError:
if spec.satisfies("@10.1:"): if spec.satisfies("@10.1:"):
raise InstallError( tty.die(
"The cuda installer will segfault due to the " "The cuda installer will segfault due to the "
"presence of /tmp/cuda-installer.log " "presence of /tmp/cuda-installer.log "
"please remove the file and try again " "please remove the file and try again "

View File

@@ -153,7 +153,7 @@ class DavSdk(BundlePackage, CudaPackage, ROCmPackage):
# ParaView needs @5.11: in order to use CUDA/ROCM, therefore it is the minimum # ParaView needs @5.11: in order to use CUDA/ROCM, therefore it is the minimum
# required version since GPU capability is desired for ECP # required version since GPU capability is desired for ECP
dav_sdk_depends_on( dav_sdk_depends_on(
"paraview@5.11:+mpi+openpmd+python+kits+shared+catalyst+libcatalyst use_vtkm=on", "paraview@5.11:+mpi+openpmd+python+kits+shared+catalyst+libcatalyst" " use_vtkm=on",
when="+paraview", when="+paraview",
propagate=["adios2", "cuda", "hdf5", "rocm"] + amdgpu_target_variants + cuda_arch_variants, propagate=["adios2", "cuda", "hdf5", "rocm"] + amdgpu_target_variants + cuda_arch_variants,
) )

View File

@@ -418,16 +418,18 @@ class Dealii(CMakePackage, CudaPackage):
conflicts( conflicts(
"+adol-c", "+adol-c",
when="^trilinos+chaco", when="^trilinos+chaco",
msg="Symbol clash between the ADOL-C library and Trilinos SEACAS Chaco.", msg="Symbol clash between the ADOL-C library and " "Trilinos SEACAS Chaco.",
) )
conflicts( conflicts(
"+adol-c", "+adol-c",
when="^trilinos+exodus", when="^trilinos+exodus",
msg="Symbol clash between the ADOL-C library and Trilinos Netcdf.", msg="Symbol clash between the ADOL-C library and " "Trilinos Netcdf.",
) )
conflicts( conflicts(
"+slepc", when="~petsc", msg="It is not possible to enable slepc interfaces without petsc." "+slepc",
when="~petsc",
msg="It is not possible to enable slepc interfaces " "without petsc.",
) )
def cmake_args(self): def cmake_args(self):

View File

@@ -60,7 +60,7 @@ class Dftbplus(CMakePackage, MakefilePackage):
"chimes", "chimes",
default=False, default=False,
when="@21.2:", when="@21.2:",
description="Whether repulsive corrections via the ChIMES library should be enabled.", description="Whether repulsive corrections" "via the ChIMES library should be enabled.",
) )
variant( variant(
"elsi", "elsi",
@@ -70,7 +70,9 @@ class Dftbplus(CMakePackage, MakefilePackage):
when="+mpi", when="+mpi",
) )
variant( variant(
"gpu", default=False, description="Use the MAGMA library for GPU accelerated computation" "gpu",
default=False,
description="Use the MAGMA library " "for GPU accelerated computation",
) )
variant( variant(
"mbd", "mbd",
@@ -105,7 +107,7 @@ class Dftbplus(CMakePackage, MakefilePackage):
variant( variant(
"sockets", "sockets",
default=False, default=False,
description="Whether the socket library (external control) should be linked", description="Whether the socket library " "(external control) should be linked",
) )
variant( variant(
"transport", "transport",
@@ -128,7 +130,7 @@ class Dftbplus(CMakePackage, MakefilePackage):
"dftd3", "dftd3",
default=False, default=False,
when="@:19.1", when="@:19.1",
description="Use DftD3 dispersion library (if you need this dispersion model)", description="Use DftD3 dispersion library " "(if you need this dispersion model)",
) )
depends_on("cmake@3.16:", type="build", when="@20.1:") depends_on("cmake@3.16:", type="build", when="@20.1:")

View File

@@ -75,7 +75,8 @@ def config_docbook(self):
"--noout", "--noout",
"--add", "--add",
"public", "public",
f"-//OASIS//ENTITIES DocBook XML Additional General Entities V{version}//EN", "-//OASIS//ENTITIES DocBook XML Additional General Entities "
"V{0}//EN".format(version),
f"file://{prefix}/dbgenent.mod", f"file://{prefix}/dbgenent.mod",
docbook, docbook,
) )
@@ -115,7 +116,7 @@ def config_docbook(self):
"--noout", "--noout",
"--add", "--add",
"public", "public",
"ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN", "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow " "Relations//EN",
f"file://{ent_dir}/isoamsa.ent", f"file://{ent_dir}/isoamsa.ent",
docbook, docbook,
) )
@@ -123,7 +124,7 @@ def config_docbook(self):
"--noout", "--noout",
"--add", "--add",
"public", "public",
"ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN", "ISO 8879:1986//ENTITIES Added Math Symbols: Binary " "Operators//EN",
f"file://{ent_dir}/isoamsb.ent", f"file://{ent_dir}/isoamsb.ent",
docbook, docbook,
) )
@@ -139,7 +140,7 @@ def config_docbook(self):
"--noout", "--noout",
"--add", "--add",
"public", "public",
"ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN", "ISO 8879:1986//ENTITIES Added Math Symbols: " "Negated Relations//EN",
f"file://{ent_dir}/isoamsn.ent", f"file://{ent_dir}/isoamsn.ent",
docbook, docbook,
) )

View File

@@ -5,6 +5,8 @@
import os import os
import socket import socket
import llnl.util.tty as tty
from spack.build_systems.cmake import CMakeBuilder from spack.build_systems.cmake import CMakeBuilder
from spack.package import * from spack.package import *

View File

@@ -56,16 +56,15 @@ class Dyninst(CMakePackage):
variant( variant(
"openmp", "openmp",
default=True, default=True,
description="Enable OpenMP support for ParseAPI (version 10.0.0 or later)", description="Enable OpenMP support for ParseAPI " "(version 10.0.0 or later)",
) )
variant("static", default=False, description="Build static libraries") variant("static", default=False, description="Build static libraries")
variant("stat_dysect", default=False, description="Patch for STAT's DySectAPI") variant("stat_dysect", default=False, description="Patch for STAT's DySectAPI")
boost_libs = ( boost_libs = "+atomic+chrono+date_time+filesystem+system+thread+timer"
"+atomic+chrono+date_time+filesystem+system+thread+timer+container+random+exception" "+container+random+exception"
)
depends_on("boost@1.61.0:" + boost_libs, when="@10.1.0:") depends_on("boost@1.61.0:" + boost_libs, when="@10.1.0:")
depends_on("boost@1.61.0:1.69" + boost_libs, when="@:10.0") depends_on("boost@1.61.0:1.69" + boost_libs, when="@:10.0")

View File

@@ -123,13 +123,13 @@ class Eccodes(CMakePackage):
conflicts( conflicts(
"+netcdf", "+netcdf",
when="~tools", when="~tools",
msg="Cannot enable the NetCDF conversion tool when the command line tools are disabled", msg="Cannot enable the NetCDF conversion tool " "when the command line tools are disabled",
) )
conflicts( conflicts(
"~tools", "~tools",
when="@:2.18.0", when="@:2.18.0",
msg="The command line tools can be disabled only starting version 2.19.0", msg="The command line tools can be disabled " "only starting version 2.19.0",
) )
for center, definitions in _definitions.items(): for center, definitions in _definitions.items():

View File

@@ -65,7 +65,7 @@ class Eckit(CMakePackage):
variant( variant(
"unicode", "unicode",
default=True, default=True,
description="Enable support for Unicode characters in Yaml/JSON parsers", description="Enable support for Unicode characters in Yaml/JSON" "parsers",
) )
variant("aio", default=True, description="Enable asynchronous IO") variant("aio", default=True, description="Enable asynchronous IO")
variant("fismahigh", default=False, description="Apply patching for FISMA-high compliance") variant("fismahigh", default=False, description="Apply patching for FISMA-high compliance")

View File

@@ -170,7 +170,7 @@ class EcpDataVisSdk(BundlePackage, CudaPackage, ROCmPackage):
# ParaView needs @5.11: in order to use CUDA/ROCM, therefore it is the minimum # ParaView needs @5.11: in order to use CUDA/ROCM, therefore it is the minimum
# required version since GPU capability is desired for ECP # required version since GPU capability is desired for ECP
dav_sdk_depends_on( dav_sdk_depends_on(
"paraview@5.11:+mpi+openpmd+python+kits+shared+catalyst+libcatalyst use_vtkm=on", "paraview@5.11:+mpi+openpmd+python+kits+shared+catalyst+libcatalyst" " use_vtkm=on",
when="+paraview", when="+paraview",
propagate=["adios2", "cuda", "hdf5", "rocm"] + amdgpu_target_variants + cuda_arch_variants, propagate=["adios2", "cuda", "hdf5", "rocm"] + amdgpu_target_variants + cuda_arch_variants,
) )

View File

@@ -39,7 +39,7 @@ class Elemental(CMakePackage):
variant( variant(
"int64_blas", "int64_blas",
default=False, default=False,
description="Use 64bit integers for BLAS. Requires local build of BLAS library.", description="Use 64bit integers for BLAS." " Requires local build of BLAS library.",
) )
variant("scalapack", default=False, description="Build with ScaLAPACK library") variant("scalapack", default=False, description="Build with ScaLAPACK library")
variant( variant(
@@ -57,7 +57,7 @@ class Elemental(CMakePackage):
variant( variant(
"mpfr", "mpfr",
default=False, default=False,
description="Support GNU MPFR's arbitrary-precision floating-point arithmetic", description="Support GNU MPFR's" "arbitrary-precision floating-point arithmetic",
) )
# Note that #1712 forces us to enumerate the different blas variants # Note that #1712 forces us to enumerate the different blas variants
@@ -150,7 +150,7 @@ def cmake_args(self):
), ),
"-DCUSTOM_BLAS_SUFFIX:BOOL=TRUE", "-DCUSTOM_BLAS_SUFFIX:BOOL=TRUE",
] ]
) ),
if spec.satisfies("+scalapack"): if spec.satisfies("+scalapack"):
args.extend( args.extend(
[ [
@@ -159,7 +159,7 @@ def cmake_args(self):
), ),
"-DCUSTOM_LAPACK_SUFFIX:BOOL=TRUE", "-DCUSTOM_LAPACK_SUFFIX:BOOL=TRUE",
] ]
) ),
else: else:
math_libs = spec["lapack"].libs + spec["blas"].libs math_libs = spec["lapack"].libs + spec["blas"].libs

View File

@@ -80,7 +80,7 @@ def cmake_args(self):
avx512_suffix = "" avx512_suffix = ""
if spec.satisfies("@:3.12"): if spec.satisfies("@:3.12"):
avx512_suffix = "SKX" avx512_suffix = "SKX"
args.append(self.define("EMBREE_ISA_AVX512" + avx512_suffix, True)) args.append(self.define("EMBREE_ISA_AVX512" + avx512_suffix, True)),
if spec.satisfies("%gcc@:7"): if spec.satisfies("%gcc@:7"):
# remove unsupported -mprefer-vector-width=256, otherwise copied # remove unsupported -mprefer-vector-width=256, otherwise copied
# from common/cmake/gnu.cmake # from common/cmake/gnu.cmake

View File

@@ -48,7 +48,7 @@ def patch(self):
) )
edit = FileFilter("CMakeLists.txt") edit = FileFilter("CMakeLists.txt")
edit.filter( edit.filter(
r"\${CMAKE_CURRENT_SOURCE_DIR}/../bamtools/lib/libbamtools.a", r"\${CMAKE_CURRENT_SOURCE_DIR}/../bamtools/lib/" "libbamtools.a",
"%s" % self.spec["bamtools"].libs, "%s" % self.spec["bamtools"].libs,
) )

View File

@@ -41,7 +41,7 @@ def makefile_name(self):
elif self.spec.satisfies("platform=linux target=x86_64:"): elif self.spec.satisfies("platform=linux target=x86_64:"):
name = "Makefile.linux64_sse2" name = "Makefile.linux64_sse2"
else: else:
raise InstallError( tty.die(
"""Unsupported platform/target, must be """Unsupported platform/target, must be
Darwin (assumes 64-bit) Darwin (assumes 64-bit)
Linux x86_64 Linux x86_64

View File

@@ -31,12 +31,12 @@ class Flamemaster(CMakePackage):
variant( variant(
"bilin_omega", "bilin_omega",
default=True, default=True,
description="Compile with bilinear interpolation for collision integrals (omega)", description="Compile with bilinear interpolation" "for collision integrals (omega)",
) )
variant( variant(
"combustion", "combustion",
default=False, default=False,
description="Integrate comustion libraries for kinetics, thermodynamics, and transport", description="Integrate comustion libraries" "for kinetics, thermodynamics, and transport",
) )
variant( variant(
"fortran_code", "fortran_code",
@@ -109,7 +109,7 @@ class Flamemaster(CMakePackage):
variant( variant(
"tests", "tests",
default=False, default=False,
description="Install google-test framework for unit tests and enable units tests.", description="Install google-test framework for unit tests" "and enable units tests.",
) )
variant( variant(
"third_party_in_build_dir", "third_party_in_build_dir",

View File

@@ -63,7 +63,7 @@ class Flexi(CMakePackage):
"parabolic", "parabolic",
default=True, default=True,
description=( description=(
"Defines whether the parabolic part of the chosen system should be included or not" "Defines whether the parabolic part of the chosen system " "should be included or not"
), ),
) )
variant( variant(

View File

@@ -118,7 +118,12 @@ def cmake_args(self):
args.append("-DBUILD_SHARED_LIBS=ON") args.append("-DBUILD_SHARED_LIBS=ON")
if spec.satisfies("+pic"): if spec.satisfies("+pic"):
args.append(self.define("CMAKE_POSITION_INDEPENDENT_CODE", True)) args.extend(
[
"-DCMAKE_C_FLAGS={0}".format(self.compiler.cc_pic_flag),
"-DCMAKE_CXX_FLAGS={0}".format(self.compiler.cxx_pic_flag),
]
)
args.append("-DCMAKE_CXX_STANDARD={0}".format(spec.variants["cxxstd"].value)) args.append("-DCMAKE_CXX_STANDARD={0}".format(spec.variants["cxxstd"].value))
# Require standard at configure time to guarantee the # Require standard at configure time to guarantee the

View File

@@ -32,6 +32,8 @@
import os import os
import re import re
import llnl.util.tty as tty
from spack.package import * from spack.package import *
from spack.pkg.builtin.openfoam import ( from spack.pkg.builtin.openfoam import (
OpenfoamArch, OpenfoamArch,
@@ -39,6 +41,7 @@
rewrite_environ_files, rewrite_environ_files,
write_environ, write_environ,
) )
from spack.util.environment import EnvironmentModifications
class FoamExtend(Package): class FoamExtend(Package):
@@ -170,7 +173,7 @@ def setup_run_environment(self, env):
if minimal: if minimal:
# pre-build or minimal environment # pre-build or minimal environment
tty.info("foam-extend minimal env {0}".format(self.prefix)) tty.info("foam-extend minimal env {0}".format(self.prefix))
env.set("FOAM_INST_DIR", os.path.dirname(self.projectdir)) env.set("FOAM_INST_DIR", os.path.dirname(self.projectdir)),
env.set("FOAM_PROJECT_DIR", self.projectdir) env.set("FOAM_PROJECT_DIR", self.projectdir)
env.set("WM_PROJECT_DIR", self.projectdir) env.set("WM_PROJECT_DIR", self.projectdir)
for d in ["wmake", self.archbin]: # bin added automatically for d in ["wmake", self.archbin]: # bin added automatically

View File

@@ -66,7 +66,7 @@ class Fortrilinos(CMakePackage):
depends_on("trilinos gotype=long_long") depends_on("trilinos gotype=long_long")
# Full trilinos dependencies # Full trilinos dependencies
depends_on( depends_on(
"trilinos+amesos2+anasazi+belos+kokkos+ifpack2+muelu+nox+tpetra+stratimikos", when="+hl" "trilinos+amesos2+anasazi+belos+kokkos+ifpack2+muelu+nox+tpetra" "+stratimikos", when="+hl"
) )
@run_before("cmake") @run_before("cmake")

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