Compare commits

..

4 Commits

Author SHA1 Message Date
Harmen Stoppels
14de4b67ef . 2024-09-11 09:54:02 +02:00
Harmen Stoppels
e59363eaa1 simplify 2024-09-11 09:46:33 +02:00
Harmen Stoppels
ded4935834 detection: reduce fs pressure 2024-09-11 09:46:17 +02:00
Harmen Stoppels
c505f4f70a use packagebase 2024-09-11 09:44:08 +02:00
535 changed files with 3927 additions and 6253 deletions

View File

@@ -1,5 +1,4 @@
{
"name": "Ubuntu 20.04",
"image": "ghcr.io/spack/ubuntu20.04-runner-amd64-gcc-11.4:2023.08.01",
"postCreateCommand": "./.devcontainer/postCreateCommand.sh"
}

View File

@@ -1,5 +0,0 @@
{
"name": "Ubuntu 22.04",
"image": "ghcr.io/spack/ubuntu-22.04:v2024-05-07",
"postCreateCommand": "./.devcontainer/postCreateCommand.sh"
}

View File

@@ -40,8 +40,6 @@ jobs:
run: |
python -m pip install --upgrade pywin32
- name: Package audits (with coverage)
env:
COVERAGE_FILE: coverage/.coverage-audits-${{ matrix.system.os }}
if: ${{ inputs.with_coverage == 'true' && runner.os != 'Windows' }}
run: |
. share/spack/setup-env.sh
@@ -49,26 +47,27 @@ jobs:
coverage run $(which spack) audit configs
coverage run $(which spack) -d audit externals
coverage combine
coverage xml
- name: Package audits (without coverage)
if: ${{ inputs.with_coverage == 'false' && runner.os != 'Windows' }}
run: |
. share/spack/setup-env.sh
. share/spack/setup-env.sh
spack -d audit packages
spack -d audit configs
spack -d audit externals
- name: Package audits (without coverage)
if: ${{ runner.os == 'Windows' }}
run: |
. share/spack/setup-env.sh
. share/spack/setup-env.sh
spack -d audit packages
./share/spack/qa/validate_last_exit.ps1
spack -d audit configs
./share/spack/qa/validate_last_exit.ps1
spack -d audit externals
./share/spack/qa/validate_last_exit.ps1
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
if: ${{ inputs.with_coverage == 'true' && runner.os != 'Windows' }}
- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
if: ${{ inputs.with_coverage == 'true' }}
with:
name: coverage-audits-${{ matrix.system.os }}
path: coverage
include-hidden-files: true
flags: unittests,audits
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true

View File

@@ -84,30 +84,8 @@ jobs:
needs: [ prechecks, changes ]
uses: ./.github/workflows/unit_tests.yaml
secrets: inherit
upload-coverage:
needs: [ unit-tests, prechecks ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
fetch-depth: 0
- name: Download coverage files
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
with:
pattern: coverage-*
path: coverage
merge-multiple: true
- run: pip install --upgrade coverage
- run: ls -la coverage
- run: coverage combine -a coverage/.coverage*
- run: coverage xml
- name: "Upload coverage"
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
with:
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
all:
needs: [ upload-coverage, bootstrap ]
needs: [ unit-tests, bootstrap ]
runs-on: ubuntu-latest
steps:
- name: Success

View File

@@ -76,15 +76,14 @@ jobs:
SPACK_PYTHON: python
SPACK_TEST_PARALLEL: 2
COVERAGE: true
COVERAGE_FILE: coverage/.coverage-${{ matrix.os }}-python${{ matrix.python-version }}
UNIT_TEST_COVERAGE: ${{ matrix.python-version == '3.11' }}
run: |
share/spack/qa/run-unit-tests
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
with:
name: coverage-${{ matrix.os }}-python${{ matrix.python-version }}
path: coverage
include-hidden-files: true
flags: unittests,linux,${{ matrix.concretizer }}
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
# Test shell integration
shell:
runs-on: ubuntu-latest
@@ -113,11 +112,11 @@ jobs:
COVERAGE: true
run: |
share/spack/qa/run-shell-tests
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
with:
name: coverage-shell
path: coverage
include-hidden-files: true
flags: shelltests,linux
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
# Test RHEL8 UBI with platform Python. This job is run
# only on PRs modifying core Spack
@@ -171,14 +170,13 @@ jobs:
- name: Run unit tests (full suite with coverage)
env:
COVERAGE: true
COVERAGE_FILE: coverage/.coverage-clingo-cffi
run: |
share/spack/qa/run-unit-tests
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
with:
name: coverage-clingo-cffi
path: coverage
include-hidden-files: true
flags: unittests,linux,clingo
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
# Run unit tests on MacOS
macos:
runs-on: ${{ matrix.os }}
@@ -203,7 +201,6 @@ jobs:
- name: Run unit tests
env:
SPACK_TEST_PARALLEL: 4
COVERAGE_FILE: coverage/.coverage-${{ matrix.os }}-python${{ matrix.python-version }}
run: |
git --version
. .github/workflows/bin/setup_git.sh
@@ -212,11 +209,11 @@ jobs:
$(which spack) solve zlib
common_args=(--dist loadfile --tx '4*popen//python=./bin/spack-tmpconfig python -u ./bin/spack python' -x)
$(which spack) unit-test --verbose --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml "${common_args[@]}"
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
with:
name: coverage-${{ matrix.os }}-python${{ matrix.python-version }}
path: coverage
include-hidden-files: true
flags: unittests,macos
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
# Run unit tests on Windows
windows:
defaults:
@@ -238,13 +235,13 @@ jobs:
run: |
./.github/workflows/bin/setup_git.ps1
- name: Unit Test
env:
COVERAGE_FILE: coverage/.coverage-windows
run: |
spack unit-test -x --verbose --cov --cov-config=pyproject.toml
./share/spack/qa/validate_last_exit.ps1
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
coverage combine -a
coverage xml
- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
with:
name: coverage-windows
path: coverage
include-hidden-files: true
flags: unittests,windows
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true

View File

@@ -87,62 +87,3 @@ jobs:
spack -d bootstrap now --dev
spack style -t black
spack unit-test -V
import-check:
runs-on: ubuntu-latest
steps:
- uses: julia-actions/setup-julia@v2
with:
version: '1.10'
- uses: julia-actions/cache@v2
# PR: use the base of the PR as the old commit
- name: Checkout PR base commit
if: github.event_name == 'pull_request'
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
ref: ${{ github.event.pull_request.base.sha }}
path: old
# not a PR: use the previous commit as the old commit
- name: Checkout previous commit
if: github.event_name != 'pull_request'
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
fetch-depth: 2
path: old
- name: Checkout previous commit
if: github.event_name != 'pull_request'
run: git -C old reset --hard HEAD^
- name: Checkout new commit
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: new
- name: Install circular import checker
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
repository: haampie/circular-import-fighter
ref: 555519c6fd5564fd2eb844e7b87e84f4d12602e2
path: circular-import-fighter
- name: Install dependencies
working-directory: circular-import-fighter
run: make -j dependencies
- name: Import cycles before
working-directory: circular-import-fighter
run: make SPACK_ROOT=../old && cp solution solution.old
- name: Import cycles after
working-directory: circular-import-fighter
run: make clean-graph && make SPACK_ROOT=../new && cp solution solution.new
- name: Compare import cycles
working-directory: circular-import-fighter
run: |
edges_before="$(grep -oP 'edges to delete: \K\d+' solution.old)"
edges_after="$(grep -oP 'edges to delete: \K\d+' solution.new)"
if [ "$edges_after" -gt "$edges_before" ]; then
printf '\033[1;31mImport check failed: %s imports need to be deleted, ' "$edges_after"
printf 'previously this was %s\033[0m\n' "$edges_before"
printf 'Compare \033[1;97m"Import cycles before"\033[0m and '
printf '\033[1;97m"Import cycles after"\033[0m to see problematic imports.\n'
exit 1
else
printf '\033[1;32mImport check passed: %s <= %s\033[0m\n' "$edges_after" "$edges_before"
fi

View File

@@ -1175,17 +1175,6 @@ unspecified version, but packages can depend on other packages with
could depend on ``mpich@1.2:`` if it can only build with version
``1.2`` or higher of ``mpich``.
.. note:: Windows Spec Syntax Caveats
Windows has a few idiosyncrasies when it comes to the Spack spec syntax and the use of certain shells
Spack's spec dependency syntax uses the carat (``^``) character, however this is an escape string in CMD
so it must be escaped with an additional carat (i.e. ``^^``).
CMD also will attempt to interpret strings with ``=`` characters in them. Any spec including this symbol
must double quote the string.
Note: All of these issues are unique to CMD, they can be avoided by using Powershell.
For more context on these caveats see the related issues: `carat <https://github.com/spack/spack/issues/42833>`_ and `equals <https://github.com/spack/spack/issues/43348>`_
Below are more details about the specifiers that you can add to specs.
.. _version-specifier:

View File

@@ -5,9 +5,9 @@
.. chain:
=============================================
Chaining Spack Installations (upstreams.yaml)
=============================================
============================
Chaining Spack Installations
============================
You can point your Spack installation to another installation to use any
packages that are installed there. To register the other Spack instance,

View File

@@ -219,7 +219,6 @@ def setup(sphinx):
("py:class", "spack.install_test.Pb"),
("py:class", "spack.filesystem_view.SimpleFilesystemView"),
("py:class", "spack.traverse.EdgeAndDepth"),
("py:class", "archspec.cpu.microarchitecture.Microarchitecture"),
]
# The reST default role (used for this markup: `text`) to use for all documents.

View File

@@ -893,8 +893,9 @@ The valid variables for a ``when`` clause are:
#. ``env``. The user environment (usually ``os.environ`` in Python).
#. ``hostname``. The hostname of the system (if ``hostname`` is an
executable in the user's PATH).
#. ``hostname``. The hostname of the system.
#. ``full_hostname``. The fully qualified hostname of the system.
^^^^^^^^^^^^^^^^^^^^^^^^
SpecLists as Constraints

View File

@@ -1475,14 +1475,16 @@ in a Windows CMD prompt.
Step 3: Run and configure Spack
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
On Windows, Spack supports both primary native shells, Powershell and the traditional command prompt.
To use Spack, pick your favorite shell, and run ``bin\spack_cmd.bat`` or ``share/spack/setup-env.ps1``
(you may need to Run as Administrator) from the top-level spack
directory. This will provide a Spack enabled shell. If you receive a warning message that Python is not in your ``PATH``
To use Spack, run ``bin\spack_cmd.bat`` (you may need to Run as Administrator) from the top-level spack
directory. This will provide a Windows command prompt with an environment properly set up with Spack
and its prerequisites. If you receive a warning message that Python is not in your ``PATH``
(which may happen if you installed Python from the website and not the Windows Store) add the location
of the Python executable to your ``PATH`` now. You can permanently add Python to your ``PATH`` variable
by using the ``Edit the system environment variables`` utility in Windows Control Panel.
.. note::
Alternatively, Powershell can be used in place of CMD
To configure Spack, first run the following command inside the Spack console:
.. code-block:: console
@@ -1547,7 +1549,7 @@ and not tabs, so ensure that this is the case when editing one directly.
.. note:: Cygwin
The use of Cygwin is not officially supported by Spack and is not tested.
However Spack will not prevent this, so use if choosing to use Spack
However Spack will not throw an error, so use if choosing to use Spack
with Cygwin, know that no functionality is garunteed.
^^^^^^^^^^^^^^^^^
@@ -1561,12 +1563,21 @@ Spack console via:
spack install cpuinfo
If in the previous step, you did not have CMake or Ninja installed, running the command above should install both packages
If in the previous step, you did not have CMake or Ninja installed, running the command above should bootstrap both packages
.. note:: Spec Syntax Caveats
Windows has a few idiosyncrasies when it comes to the Spack spec syntax and the use of certain shells
See the Spack spec syntax doc for more information
"""""""""""""""""""""""""""
Windows Compatible Packages
"""""""""""""""""""""""""""
Not all spack packages currently have Windows support. Some are inherently incompatible with the
platform, and others simply have yet to be ported. To view the current set of packages with Windows
support, the list command should be used via `spack list -t windows`. If there's a package you'd like
to install on Windows but is not in that list, feel free to reach out to request the port or contribute
the port yourself.
.. note::
This is by no means a comprehensive list, some packages may have ports that were not tagged
while others may just work out of the box on Windows and have not been tagged as such.
^^^^^^^^^^^^^^
For developers
@@ -1577,3 +1588,5 @@ Python, Git, and Spack, instead of requiring the user to do so manually.
Instructions for creating the installer are at
https://github.com/spack/spack/blob/develop/lib/spack/spack/cmd/installer/README.md
Alternatively a pre-built copy of the Windows installer is available as an artifact of Spack's Windows CI
available at each run of the CI on develop or any PR.

View File

@@ -5,8 +5,8 @@ sphinx-rtd-theme==2.0.0
python-levenshtein==0.25.1
docutils==0.20.1
pygments==2.18.0
urllib3==2.2.3
pytest==8.3.3
urllib3==2.2.2
pytest==8.3.2
isort==5.13.2
black==24.8.0
flake8==7.1.1

View File

@@ -18,7 +18,7 @@
* Homepage: https://pypi.python.org/pypi/archspec
* Usage: Labeling, comparison and detection of microarchitectures
* Version: 0.2.5-dev (commit bceb39528ac49dd0c876b2e9bf3e7482e9c2be4a)
* Version: 0.2.5-dev (commit 7e6740012b897ae4a950f0bba7e9726b767e921f)
astunparse
----------------

View File

@@ -115,9 +115,6 @@ def __eq__(self, other):
and self.cpu_part == other.cpu_part
)
def __hash__(self):
return hash(self.name)
@coerce_target_names
def __ne__(self, other):
return not self == other

View File

@@ -2844,7 +2844,8 @@
"asimdrdm",
"lrcpc",
"dcpop",
"asimddp"
"asimddp",
"ssbs"
],
"compilers" : {
"gcc": [
@@ -2941,6 +2942,7 @@
"uscat",
"ilrcpc",
"flagm",
"ssbs",
"dcpodp",
"svei8mm",
"svebf16",
@@ -3008,7 +3010,7 @@
},
{
"versions": "11:",
"flags" : "-march=armv8.4-a+sve+fp16+bf16+crypto+i8mm+rng"
"flags" : "-march=armv8.4-a+sve+ssbs+fp16+bf16+crypto+i8mm+rng"
},
{
"versions": "12:",
@@ -3064,6 +3066,7 @@
"uscat",
"ilrcpc",
"flagm",
"ssbs",
"sb",
"dcpodp",
"sve2",
@@ -3176,6 +3179,7 @@
"uscat",
"ilrcpc",
"flagm",
"ssbs",
"sb",
"dcpodp",
"sve2",

View File

@@ -3,13 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
from typing import Optional
import spack.paths
import spack.util.git
#: PEP440 canonical <major>.<minor>.<micro>.<devN> string
__version__ = "0.23.0.dev0"
spack_version = __version__
@@ -26,47 +19,4 @@ def __try_int(v):
spack_version_info = tuple([__try_int(v) for v in __version__.split(".")])
def get_spack_commit() -> Optional[str]:
"""Get the Spack git commit sha.
Returns:
(str or None) the commit sha if available, otherwise None
"""
git_path = os.path.join(spack.paths.prefix, ".git")
if not os.path.exists(git_path):
return None
git = spack.util.git.git()
if not git:
return None
rev = git(
"-C",
spack.paths.prefix,
"rev-parse",
"HEAD",
output=str,
error=os.devnull,
fail_on_error=False,
)
if git.returncode != 0:
return None
match = re.match(r"[a-f\d]{7,}$", rev)
return match.group(0) if match else None
def get_version() -> str:
"""Get a descriptive version of this instance of Spack.
Outputs '<PEP440 version> (<git commit sha>)'.
The commit sha is only added when available.
"""
commit = get_spack_commit()
if commit:
return f"{spack_version} ({commit})"
return spack_version
__all__ = ["spack_version_info", "spack_version", "get_version", "get_spack_commit"]
__all__ = ["spack_version_info", "spack_version"]

View File

@@ -46,14 +46,11 @@ def _search_duplicate_compilers(error_cls):
import pickle
import re
import warnings
from typing import Iterable, List, Set, Tuple
from urllib.request import urlopen
import llnl.util.lang
import spack.builder
import spack.config
import spack.fetch_strategy
import spack.patch
import spack.repo
import spack.spec
@@ -76,9 +73,7 @@ def __init__(self, summary, details):
self.details = tuple(details)
def __str__(self):
if self.details:
return f"{self.summary}\n" + "\n".join(f" {detail}" for detail in self.details)
return self.summary
return self.summary + "\n" + "\n".join([" " + detail for detail in self.details])
def __eq__(self, other):
if self.summary != other.summary or self.details != other.details:
@@ -282,7 +277,7 @@ def _avoid_mismatched_variants(error_cls):
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
for variant in current_spec.variants.values():
# Variant does not exist at all
if variant.name not in pkg_cls.variant_names():
if variant.name not in pkg_cls.variants:
summary = (
f"Setting a preference for the '{pkg_name}' package to the "
f"non-existing variant '{variant.name}'"
@@ -291,8 +286,9 @@ def _avoid_mismatched_variants(error_cls):
continue
# Variant cannot accept this value
s = spack.spec.Spec(pkg_name)
try:
spack.variant.prevalidate_variant_value(pkg_cls, variant, strict=True)
s.update_variant_validate(variant.name, variant.value)
except Exception:
summary = (
f"Setting the variant '{variant.name}' of the '{pkg_name}' package "
@@ -662,15 +658,9 @@ def _ensure_env_methods_are_ported_to_builders(pkgs, error_cls):
errors = []
for pkg_name in pkgs:
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
# values are either Value objects (for conditional values) or the values themselves
build_system_names = set(
v.value if isinstance(v, spack.variant.Value) else v
for _, variant in pkg_cls.variant_definitions("build_system")
for v in variant.values
)
builder_cls_names = [spack.builder.BUILDER_CLS[x].__name__ for x in build_system_names]
buildsystem_variant, _ = pkg_cls.variants["build_system"]
buildsystem_names = [getattr(x, "value", x) for x in buildsystem_variant.values]
builder_cls_names = [spack.builder.BUILDER_CLS[x].__name__ for x in buildsystem_names]
module = pkg_cls.module
has_builders_in_package_py = any(
getattr(module, name, False) for name in builder_cls_names
@@ -689,88 +679,6 @@ def _ensure_env_methods_are_ported_to_builders(pkgs, error_cls):
return errors
class DeprecatedMagicGlobals(ast.NodeVisitor):
def __init__(self, magic_globals: Iterable[str]):
super().__init__()
self.magic_globals: Set[str] = set(magic_globals)
# State to track whether we're in a class function
self.depth: int = 0
self.in_function: bool = False
self.path = (ast.Module, ast.ClassDef, ast.FunctionDef)
# Defined locals in the current function (heuristically at least)
self.locals: Set[str] = set()
# List of (name, lineno) tuples for references to magic globals
self.references_to_globals: List[Tuple[str, int]] = []
def descend_in_function_def(self, node: ast.AST) -> None:
if not isinstance(node, self.path[self.depth]):
return
self.depth += 1
if self.depth == len(self.path):
self.in_function = True
super().generic_visit(node)
if self.depth == len(self.path):
self.in_function = False
self.locals.clear()
self.depth -= 1
def generic_visit(self, node: ast.AST) -> None:
# Recurse into function definitions
if self.depth < len(self.path):
return self.descend_in_function_def(node)
elif not self.in_function:
return
elif isinstance(node, ast.Global):
for name in node.names:
if name in self.magic_globals:
self.references_to_globals.append((name, node.lineno))
elif isinstance(node, ast.Assign):
# visit the rhs before lhs
super().visit(node.value)
for target in node.targets:
super().visit(target)
elif isinstance(node, ast.Name) and node.id in self.magic_globals:
if isinstance(node.ctx, ast.Load) and node.id not in self.locals:
self.references_to_globals.append((node.id, node.lineno))
elif isinstance(node.ctx, ast.Store):
self.locals.add(node.id)
else:
super().generic_visit(node)
@package_properties
def _uses_deprecated_globals(pkgs, error_cls):
"""Ensure that packages do not use deprecated globals"""
errors = []
for pkg_name in pkgs:
# some packages scheduled to be removed in v0.23 are not worth fixing.
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
if all(v.get("deprecated", False) for v in pkg_cls.versions.values()):
continue
file = spack.repo.PATH.filename_for_package_name(pkg_name)
tree = ast.parse(open(file).read())
visitor = DeprecatedMagicGlobals(("std_cmake_args",))
visitor.visit(tree)
if visitor.references_to_globals:
errors.append(
error_cls(
f"Package '{pkg_name}' uses deprecated globals",
[
f"{file}:{line} references '{name}'"
for name, line in visitor.references_to_globals
],
)
)
return errors
@package_https_directives
def _linting_package_file(pkgs, error_cls):
"""Check for correctness of links"""
@@ -937,22 +845,20 @@ def check_virtual_with_variants(spec, msg):
# check variants
dependency_variants = dep.spec.variants
for name, variant in dependency_variants.items():
for name, value in dependency_variants.items():
try:
spack.variant.prevalidate_variant_value(
dependency_pkg_cls, variant, dep.spec, strict=True
)
v, _ = dependency_pkg_cls.variants[name]
v.validate_or_raise(value, pkg_cls=dependency_pkg_cls)
except Exception as e:
summary = (
f"{pkg_name}: wrong variant used for dependency in 'depends_on()'"
)
error_msg = str(e)
if isinstance(e, KeyError):
error_msg = (
f"variant {str(e).strip()} does not exist in package {dep_name}"
f" in package '{dep_name}'"
)
error_msg += f" in package '{dep_name}'"
errors.append(
error_cls(summary=summary, details=[error_msg, f"in {filename}"])
@@ -964,38 +870,39 @@ def check_virtual_with_variants(spec, msg):
@package_directives
def _ensure_variant_defaults_are_parsable(pkgs, error_cls):
"""Ensures that variant defaults are present and parsable from cli"""
def check_variant(pkg_cls, variant, vname):
# bool is a subclass of int in python. Permitting a default that is an instance
# of 'int' means both foo=false and foo=0 are accepted. Other falsish values are
# not allowed, since they can't be parsed from CLI ('foo=')
default_is_parsable = isinstance(variant.default, int) or variant.default
if not default_is_parsable:
msg = f"Variant '{vname}' of package '{pkg_cls.name}' has an unparsable default value"
return [error_cls(msg, [])]
try:
vspec = variant.make_default()
except spack.variant.MultipleValuesInExclusiveVariantError:
msg = f"Can't create default value for variant '{vname}' in package '{pkg_cls.name}'"
return [error_cls(msg, [])]
try:
variant.validate_or_raise(vspec, pkg_cls.name)
except spack.variant.InvalidVariantValueError:
msg = "Default value of variant '{vname}' in package '{pkg.name}' is invalid"
question = "Is it among the allowed values?"
return [error_cls(msg, [question])]
return []
errors = []
for pkg_name in pkgs:
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
for vname in pkg_cls.variant_names():
for _, variant_def in pkg_cls.variant_definitions(vname):
errors.extend(check_variant(pkg_cls, variant_def, vname))
for variant_name, entry in pkg_cls.variants.items():
variant, _ = entry
default_is_parsable = (
# Permitting a default that is an instance on 'int' permits
# to have foo=false or foo=0. Other falsish values are
# not allowed, since they can't be parsed from cli ('foo=')
isinstance(variant.default, int)
or variant.default
)
if not default_is_parsable:
error_msg = "Variant '{}' of package '{}' has a bad default value"
errors.append(error_cls(error_msg.format(variant_name, pkg_name), []))
continue
try:
vspec = variant.make_default()
except spack.variant.MultipleValuesInExclusiveVariantError:
error_msg = "Cannot create a default value for the variant '{}' in package '{}'"
errors.append(error_cls(error_msg.format(variant_name, pkg_name), []))
continue
try:
variant.validate_or_raise(vspec, pkg_cls=pkg_cls)
except spack.variant.InvalidVariantValueError:
error_msg = (
"The default value of the variant '{}' in package '{}' failed validation"
)
question = "Is it among the allowed values?"
errors.append(error_cls(error_msg.format(variant_name, pkg_name), [question]))
return errors
@@ -1005,11 +912,11 @@ def _ensure_variants_have_descriptions(pkgs, error_cls):
errors = []
for pkg_name in pkgs:
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
for name in pkg_cls.variant_names():
for when, variant in pkg_cls.variant_definitions(name):
if not variant.description:
msg = f"Variant '{name}' in package '{pkg_name}' is missing a description"
errors.append(error_cls(msg, []))
for variant_name, entry in pkg_cls.variants.items():
variant, _ = entry
if not variant.description:
error_msg = "Variant '{}' in package '{}' is missing a description"
errors.append(error_cls(error_msg.format(variant_name, pkg_name), []))
return errors
@@ -1066,26 +973,29 @@ def _version_constraints_are_satisfiable_by_some_version_in_repo(pkgs, error_cls
def _analyze_variants_in_directive(pkg, constraint, directive, error_cls):
variant_exceptions = (
spack.variant.InconsistentValidationError,
spack.variant.MultipleValuesInExclusiveVariantError,
spack.variant.InvalidVariantValueError,
KeyError,
)
errors = []
variant_names = pkg.variant_names()
summary = f"{pkg.name}: wrong variant in '{directive}' directive"
filename = spack.repo.PATH.filename_for_package_name(pkg.name)
for name, v in constraint.variants.items():
if name not in variant_names:
msg = f"variant {name} does not exist in {pkg.name}"
errors.append(error_cls(summary=summary, details=[msg, f"in {filename}"]))
continue
try:
spack.variant.prevalidate_variant_value(pkg, v, constraint, strict=True)
except (
spack.variant.InconsistentValidationError,
spack.variant.MultipleValuesInExclusiveVariantError,
spack.variant.InvalidVariantValueError,
) as e:
msg = str(e).strip()
errors.append(error_cls(summary=summary, details=[msg, f"in {filename}"]))
variant, _ = pkg.variants[name]
variant.validate_or_raise(v, pkg_cls=pkg)
except variant_exceptions as e:
summary = pkg.name + ': wrong variant in "{0}" directive'
summary = summary.format(directive)
filename = spack.repo.PATH.filename_for_package_name(pkg.name)
error_msg = str(e).strip()
if isinstance(e, KeyError):
error_msg = "the variant {0} does not exist".format(error_msg)
err = error_cls(summary=summary, details=[error_msg, "in " + filename])
errors.append(err)
return errors
@@ -1123,10 +1033,9 @@ def _extracts_errors(triggers, summary):
for dname in dnames
)
for when, variants_by_name in pkg_cls.variants.items():
for vname, variant in variants_by_name.items():
summary = f"{pkg_name}: wrong 'when=' condition for the '{vname}' variant"
errors.extend(_extracts_errors([when], summary))
for vname, (variant, triggers) in pkg_cls.variants.items():
summary = f"{pkg_name}: wrong 'when=' condition for the '{vname}' variant"
errors.extend(_extracts_errors(triggers, summary))
for when, providers, details in _error_items(pkg_cls.provided):
errors.extend(

View File

@@ -33,6 +33,7 @@
from llnl.util.symlink import readlink
import spack.caches
import spack.cmd
import spack.config as config
import spack.database as spack_db
import spack.error
@@ -43,9 +44,9 @@
import spack.oci.image
import spack.oci.oci
import spack.oci.opener
import spack.paths
import spack.platforms
import spack.relocate as relocate
import spack.repo
import spack.spec
import spack.stage
import spack.store
@@ -1446,9 +1447,7 @@ def _oci_push_pkg_blob(
filename = os.path.join(tmpdir, f"{spec.dag_hash()}.tar.gz")
# Create an oci.image.layer aka tarball of the package
compressed_tarfile_checksum, tarfile_checksum = _do_create_tarball(
filename, spec.prefix, get_buildinfo_dict(spec)
)
compressed_tarfile_checksum, tarfile_checksum = spack.oci.oci.create_tarball(spec, filename)
blob = spack.oci.oci.Blob(
Digest.from_sha256(compressed_tarfile_checksum),
@@ -2698,9 +2697,6 @@ def get_keys(install=False, trust=False, force=False, mirrors=None):
for mirror in mirror_collection.values():
fetch_url = mirror.fetch_url
# TODO: oci:// does not support signing.
if fetch_url.startswith("oci://"):
continue
keys_url = url_util.join(
fetch_url, BUILD_CACHE_RELATIVE_PATH, BUILD_CACHE_KEYS_RELATIVE_PATH
)

View File

@@ -14,7 +14,6 @@
import spack.compilers
import spack.config
import spack.environment
import spack.modules
import spack.paths
import spack.platforms
import spack.repo

View File

@@ -37,16 +37,21 @@
import spack.binary_distribution
import spack.config
import spack.detection
import spack.environment
import spack.modules
import spack.paths
import spack.platforms
import spack.platforms.linux
import spack.repo
import spack.spec
import spack.store
import spack.user_environment
import spack.util.environment
import spack.util.executable
import spack.util.path
import spack.util.spack_yaml
import spack.util.url
import spack.version
from spack.installer import PackageInstaller
from ._common import _executables_in_store, _python_import, _root_spec, _try_import_from_store
from .clingo import ClingoBootstrapConcretizer
@@ -278,7 +283,7 @@ def try_import(self, module: str, abstract_spec_str: str) -> bool:
# Install the spec that should make the module importable
with spack.config.override(self.mirror_scope):
PackageInstaller([concrete_spec.package], fail_fast=True).install()
concrete_spec.package.do_install(fail_fast=True)
if _try_import_from_store(module, query_spec=concrete_spec, query_info=info):
self.last_search = info
@@ -301,7 +306,7 @@ def try_search_path(self, executables: Tuple[str], abstract_spec_str: str) -> bo
msg = "[BOOTSTRAP] Try installing '{0}' from sources"
tty.debug(msg.format(abstract_spec_str))
with spack.config.override(self.mirror_scope):
PackageInstaller([concrete_spec.package], fail_fast=True).install()
concrete_spec.package.do_install()
if _executables_in_store(executables, concrete_spec, query_info=info):
self.last_search = info
return True

View File

@@ -14,9 +14,9 @@
from llnl.util import tty
import spack.environment
import spack.spec
import spack.tengine
import spack.util.path
import spack.util.cpus
import spack.util.executable
from ._common import _root_spec
from .config import root_path, spec_for_current_python, store_path

View File

@@ -45,8 +45,6 @@
from itertools import chain
from typing import Dict, List, Set, Tuple
import archspec.cpu
import llnl.util.tty as tty
from llnl.string import plural
from llnl.util.filesystem import join_path
@@ -55,7 +53,6 @@
from llnl.util.tty.color import cescape, colorize
from llnl.util.tty.log import MultiProcessFd
import spack.build_systems._checks
import spack.build_systems.cmake
import spack.build_systems.meson
import spack.build_systems.python
@@ -64,20 +61,26 @@
import spack.config
import spack.deptypes as dt
import spack.error
import spack.multimethod
import spack.main
import spack.package_base
import spack.paths
import spack.platforms
import spack.repo
import spack.schema.environment
import spack.spec
import spack.stage
import spack.store
import spack.subprocess_context
import spack.user_environment
import spack.util.executable
import spack.util.path
import spack.util.pattern
from spack import traverse
from spack.context import Context
from spack.error import InstallError, NoHeadersError, NoLibrariesError
from spack.error import NoHeadersError, NoLibrariesError
from spack.install_test import spack_install_test_log
from spack.installer import InstallError
from spack.util.cpus import determine_number_of_jobs
from spack.util.environment import (
SYSTEM_DIR_CASE_ENTRY,
EnvironmentModifications,
@@ -360,7 +363,7 @@ def set_compiler_environment_variables(pkg, env):
_add_werror_handling(keep_werror, env)
# Set the target parameters that the compiler will add
isa_arg = optimization_flags(compiler, spec.target)
isa_arg = spec.architecture.target.optimization_flags(compiler)
env.set("SPACK_TARGET_ARGS", isa_arg)
# Trap spack-tracked compiler flags as appropriate.
@@ -405,36 +408,6 @@ def set_compiler_environment_variables(pkg, env):
return env
def optimization_flags(compiler, target):
if spack.compilers.is_mixed_toolchain(compiler):
msg = (
"microarchitecture specific optimizations are not "
"supported yet on mixed compiler toolchains [check"
f" {compiler.name}@{compiler.version} for further details]"
)
tty.debug(msg)
return ""
# Try to check if the current compiler comes with a version number or
# has an unexpected suffix. If so, treat it as a compiler with a
# custom spec.
compiler_version = compiler.version
version_number, suffix = archspec.cpu.version_components(compiler.version)
if not version_number or suffix:
try:
compiler_version = compiler.real_version
except spack.util.executable.ProcessError as e:
# log this and just return compiler.version instead
tty.debug(str(e))
try:
result = target.optimization_flags(compiler.name, compiler_version.dotted_numeric_string)
except (ValueError, archspec.cpu.UnsupportedMicroarchitecture):
result = ""
return result
def set_wrapper_variables(pkg, env):
"""Set environment variables used by the Spack compiler wrapper (which have the prefix
`SPACK_`) and also add the compiler wrappers to PATH.
@@ -482,7 +455,7 @@ def set_wrapper_variables(pkg, env):
env.set(SPACK_DEBUG, "TRUE")
env.set(SPACK_SHORT_SPEC, pkg.spec.short_spec)
env.set(SPACK_DEBUG_LOG_ID, pkg.spec.format("{name}-{hash:7}"))
env.set(SPACK_DEBUG_LOG_DIR, spack.paths.spack_working_dir)
env.set(SPACK_DEBUG_LOG_DIR, spack.main.spack_working_dir)
if spack.config.get("config:ccache"):
# Enable ccache in the compiler wrapper
@@ -589,7 +562,7 @@ def set_package_py_globals(pkg, context: Context = Context.BUILD):
module.std_meson_args = spack.build_systems.meson.MesonBuilder.std_args(pkg)
module.std_pip_args = spack.build_systems.python.PythonPipBuilder.std_args(pkg)
jobs = spack.config.determine_number_of_jobs(parallel=pkg.parallel)
jobs = determine_number_of_jobs(parallel=pkg.parallel)
module.make_jobs = jobs
# TODO: make these build deps that can be installed if not found.
@@ -815,6 +788,7 @@ def setup_package(pkg, dirty, context: Context = Context.BUILD):
# Platform specific setup goes before package specific setup. This is for setting
# defaults like MACOSX_DEPLOYMENT_TARGET on macOS.
platform = spack.platforms.by_name(pkg.spec.architecture.platform)
target = platform.target(pkg.spec.architecture.target)
platform.setup_platform_environment(pkg, env_mods)
tty.debug("setup_package: grabbing modifications from dependencies")
@@ -839,6 +813,9 @@ def setup_package(pkg, dirty, context: Context = Context.BUILD):
for mod in pkg.compiler.modules:
load_module(mod)
if target and target.module_name:
load_module(target.module_name)
load_external_modules(pkg)
implicit_rpaths = pkg.compiler.implicit_rpaths()
@@ -1162,7 +1139,7 @@ def _setup_pkg_and_run(
return_value = function(pkg, kwargs)
write_pipe.send(return_value)
except spack.error.StopPhase as e:
except StopPhase as e:
# Do not create a full ChildError from this, it's not an error
# it's a control statement.
write_pipe.send(e)
@@ -1323,7 +1300,7 @@ def exitcode_msg(p):
p.join()
# If returns a StopPhase, raise it
if isinstance(child_result, spack.error.StopPhase):
if isinstance(child_result, StopPhase):
# do not print
raise child_result
@@ -1532,6 +1509,17 @@ def _make_child_error(msg, module, name, traceback, log, log_type, context):
return ChildError(msg, module, name, traceback, log, log_type, context)
class StopPhase(spack.error.SpackError):
"""Pickle-able exception to control stopped builds."""
def __reduce__(self):
return _make_stop_phase, (self.message, self.long_message)
def _make_stop_phase(msg, long_msg):
return StopPhase(msg, long_msg)
def write_log_summary(out, log_type, log, last=None):
errors, warnings = parse_log_events(log)
nerr = len(errors)

View File

@@ -8,7 +8,7 @@
import llnl.util.lang
import spack.builder
import spack.error
import spack.installer
import spack.relocate
import spack.spec
import spack.store
@@ -34,7 +34,7 @@ def check_paths(path_list, filetype, predicate):
if not predicate(abs_path):
msg = "Install failed for {0}. No such {1} in prefix: {2}"
msg = msg.format(pkg.name, filetype, path)
raise spack.error.InstallError(msg)
raise spack.installer.InstallError(msg)
check_paths(pkg.sanity_check_is_file, "file", os.path.isfile)
check_paths(pkg.sanity_check_is_dir, "directory", os.path.isdir)
@@ -42,7 +42,7 @@ def check_paths(path_list, filetype, predicate):
ignore_file = llnl.util.lang.match_predicate(spack.store.STORE.layout.hidden_file_regexes)
if all(map(ignore_file, os.listdir(pkg.prefix))):
msg = "Install failed for {0}. Nothing was installed!"
raise spack.error.InstallError(msg.format(pkg.name))
raise spack.installer.InstallError(msg.format(pkg.name))
def apply_macos_rpath_fixups(builder: spack.builder.Builder):

View File

@@ -13,7 +13,6 @@
import spack.build_environment
import spack.builder
import spack.error
import spack.package_base
from spack.directives import build_system, conflicts, depends_on
from spack.multimethod import when
@@ -249,7 +248,7 @@ def runs_ok(script_abs_path):
# An external gnuconfig may not not have a prefix.
if gnuconfig_dir is None:
raise spack.error.InstallError(
raise spack.build_environment.InstallError(
"Spack could not find substitutes for GNU config files because no "
"prefix is available for the `gnuconfig` package. Make sure you set a "
"prefix path instead of modules for external `gnuconfig`."
@@ -269,7 +268,7 @@ def runs_ok(script_abs_path):
msg += (
" or the `gnuconfig` package prefix is misconfigured as" " an external package"
)
raise spack.error.InstallError(msg)
raise spack.build_environment.InstallError(msg)
# Filter working substitutes
candidates = [f for f in candidates if runs_ok(f)]
@@ -294,7 +293,9 @@ def runs_ok(script_abs_path):
and set the prefix to the directory containing the `config.guess` and
`config.sub` files.
"""
raise spack.error.InstallError(msg.format(", ".join(to_be_found), self.name))
raise spack.build_environment.InstallError(
msg.format(", ".join(to_be_found), self.name)
)
# Copy the good files over the bad ones
for abs_path in to_be_patched:
@@ -687,8 +688,9 @@ def _activate_or_not(
variant = variant or name
# Defensively look that the name passed as argument is among variants
if not self.pkg.has_variant(variant):
# Defensively look that the name passed as argument is among
# variants
if variant not in self.pkg.variants:
msg = '"{0}" is not a variant of "{1}"'
raise KeyError(msg.format(variant, self.pkg.name))
@@ -697,19 +699,27 @@ def _activate_or_not(
# Create a list of pairs. Each pair includes a configuration
# option and whether or not that option is activated
vdef = self.pkg.get_variant(variant)
if set(vdef.values) == set((True, False)):
variant_desc, _ = self.pkg.variants[variant]
if set(variant_desc.values) == set((True, False)):
# BoolValuedVariant carry information about a single option.
# Nonetheless, for uniformity of treatment we'll package them
# in an iterable of one element.
options = [(name, f"+{variant}" in spec)]
condition = "+{name}".format(name=variant)
options = [(name, condition in spec)]
else:
condition = "{variant}={value}"
# "feature_values" is used to track values which correspond to
# features which can be enabled or disabled as understood by the
# package's build system. It excludes values which have special
# meanings and do not correspond to features (e.g. "none")
feature_values = getattr(vdef.values, "feature_values", None) or vdef.values
options = [(value, f"{variant}={value}" in spec) for value in feature_values]
feature_values = (
getattr(variant_desc.values, "feature_values", None) or variant_desc.values
)
options = [
(value, condition.format(variant=variant, value=value) in spec)
for value in feature_values
]
# For each allowed value in the list of values
for option_value, activated in options:

View File

@@ -89,7 +89,7 @@ def define_cmake_cache_from_variant(self, cmake_var, variant=None, comment=""):
if variant is None:
variant = cmake_var.lower()
if not self.pkg.has_variant(variant):
if variant not in self.pkg.variants:
raise KeyError('"{0}" is not a variant of "{1}"'.format(variant, self.pkg.name))
if variant not in self.pkg.spec.variants:

View File

@@ -15,7 +15,6 @@
import spack.build_environment
import spack.builder
import spack.deptypes as dt
import spack.error
import spack.package_base
from spack.directives import build_system, conflicts, depends_on, variant
from spack.multimethod import when
@@ -146,7 +145,6 @@ def _values(x):
default=default,
values=_values,
description="the build system generator to use",
when="build_system=cmake",
)
for x in not_used:
conflicts(f"generator={x}")
@@ -346,7 +344,7 @@ def std_args(pkg, generator=None):
msg = "Invalid CMake generator: '{0}'\n".format(generator)
msg += "CMakePackage currently supports the following "
msg += "primary generators: '{0}'".format("', '".join(valid_primary_generators))
raise spack.error.InstallError(msg)
raise spack.package_base.InstallError(msg)
try:
build_type = pkg.spec.variants["build_type"].value
@@ -506,7 +504,7 @@ def define_from_variant(self, cmake_var, variant=None):
if variant is None:
variant = cmake_var.lower()
if not self.pkg.has_variant(variant):
if variant not in self.pkg.variants:
raise KeyError('"{0}" is not a variant of "{1}"'.format(variant, self.pkg.name))
if variant not in self.pkg.spec.variants:

View File

@@ -14,7 +14,6 @@
import spack.compiler
import spack.package_base
import spack.util.executable
# Local "type" for type hints
Path = Union[str, pathlib.Path]

View File

@@ -3,9 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import re
from typing import Iterable, List
import spack.variant
from spack.directives import conflicts, depends_on, variant
from spack.multimethod import when
@@ -47,7 +44,6 @@ class CudaPackage(PackageBase):
"87",
"89",
"90",
"90a",
)
# FIXME: keep cuda and cuda_arch separate to make usage easier until
@@ -74,27 +70,6 @@ def cuda_flags(arch_list):
for s in arch_list
]
@staticmethod
def compute_capabilities(arch_list: Iterable[str]) -> List[str]:
"""Adds a decimal place to each CUDA arch.
>>> compute_capabilities(['90', '90a'])
['9.0', '9.0a']
Args:
arch_list: A list of integer strings, optionally followed by a suffix.
Returns:
A list of float strings, optionally followed by a suffix
"""
pattern = re.compile(r"(\d+)")
capabilities = []
for arch in arch_list:
_, number, letter = re.split(pattern, arch)
number = "{0:.1f}".format(float(number) / 10.0)
capabilities.append(number + letter)
return capabilities
depends_on("cuda", when="+cuda")
# CUDA version vs Architecture

View File

@@ -22,10 +22,9 @@
install,
)
import spack.builder
import spack.error
from spack.build_environment import dso_suffix
from spack.error import InstallError
from spack.package_base import InstallError
from spack.util.environment import EnvironmentModifications
from spack.util.executable import Executable
from spack.util.prefix import Prefix

View File

@@ -15,7 +15,7 @@
import spack.util.path
from spack.build_environment import dso_suffix
from spack.directives import conflicts, license, redistribute, variant
from spack.error import InstallError
from spack.package_base import InstallError
from spack.util.environment import EnvironmentModifications
from spack.util.executable import Executable

View File

@@ -24,8 +24,6 @@
import spack.detection
import spack.multimethod
import spack.package_base
import spack.platforms
import spack.repo
import spack.spec
import spack.store
from spack.directives import build_system, depends_on, extends

View File

@@ -11,9 +11,9 @@
import spack.builder
from spack.build_environment import SPACK_NO_PARALLEL_MAKE
from spack.config import determine_number_of_jobs
from spack.directives import build_system, extends, maintainers
from spack.package_base import PackageBase
from spack.util.cpus import determine_number_of_jobs
from spack.util.environment import env_flag
from spack.util.executable import Executable, ProcessError

View File

@@ -10,7 +10,7 @@
from llnl.util import lang
import spack.error
import spack.build_environment
import spack.multimethod
#: Builder classes, as registered by the "builder" decorator
@@ -461,13 +461,15 @@ def _on_phase_start(self, instance):
# If a phase has a matching stop_before_phase attribute,
# stop the installation process raising a StopPhase
if getattr(instance, "stop_before_phase", None) == self.name:
raise spack.error.StopPhase("Stopping before '{0}' phase".format(self.name))
raise spack.build_environment.StopPhase(
"Stopping before '{0}' phase".format(self.name)
)
def _on_phase_exit(self, instance):
# If a phase has a matching last_phase attribute,
# stop the installation process raising a StopPhase
if getattr(instance, "last_phase", None) == self.name:
raise spack.error.StopPhase("Stopping at '{0}' phase".format(self.name))
raise spack.build_environment.StopPhase("Stopping at '{0}' phase".format(self.name))
def copy(self):
return copy.deepcopy(self)

View File

@@ -11,7 +11,9 @@
from llnl.util.filesystem import mkdirp
import spack.config
import spack.error
import spack.fetch_strategy
import spack.mirror
import spack.paths
import spack.util.file_cache
import spack.util.path

View File

@@ -31,7 +31,6 @@
import spack
import spack.binary_distribution as bindist
import spack.concretize
import spack.config as cfg
import spack.environment as ev
import spack.main
@@ -39,6 +38,7 @@
import spack.paths
import spack.repo
import spack.spec
import spack.stage
import spack.util.git
import spack.util.gpg as gpg_util
import spack.util.spack_yaml as syaml
@@ -1219,8 +1219,8 @@ def main_script_replacements(cmd):
# Capture the version of Spack used to generate the pipeline, that can be
# passed to `git checkout` for version consistency. If we aren't in a Git
# repository, presume we are a Spack release and use the Git tag instead.
spack_version = spack.get_version()
version_to_clone = spack.get_spack_commit() or f"v{spack.spack_version}"
spack_version = spack.main.get_version()
version_to_clone = spack.main.get_spack_commit() or f"v{spack.spack_version}"
output_object["variables"] = {
"SPACK_ARTIFACTS_ROOT": rel_artifacts_root,

View File

@@ -17,7 +17,7 @@
from llnl.util.tty.colify import colify
from llnl.util.tty.color import colorize
import spack.config # breaks a cycle.
import spack.config
import spack.environment as ev
import spack.error
import spack.extensions

View File

@@ -11,7 +11,6 @@
import llnl.util.tty.color as color
import spack.platforms
import spack.spec
description = "print architecture information about this machine"
section = "system"

View File

@@ -115,11 +115,15 @@ def audit(parser, args):
def _process_reports(reports):
for check, errors in reports:
if errors:
status = f"{len(errors)} issue{'' if len(errors) == 1 else 's'} found"
print(cl.colorize(f"{check}: @*r{{{status}}}"))
numdigits = len(str(len(errors)))
msg = "{0}: {1} issue{2} found".format(
check, len(errors), "" if len(errors) == 1 else "s"
)
header = "@*b{" + msg + "}"
print(cl.colorize(header))
for idx, error in enumerate(errors):
print(f"{idx + 1:>{numdigits}}. {error}")
print(str(idx + 1) + ". " + str(error))
raise SystemExit(1)
else:
print(cl.colorize(f"{check}: @*g{{passed}}"))
msg = "{0}: 0 issues found.".format(check)
header = "@*b{" + msg + "}"
print(cl.colorize(header))

View File

@@ -16,11 +16,11 @@
import spack.bootstrap.config
import spack.bootstrap.core
import spack.config
import spack.main
import spack.mirror
import spack.spec
import spack.stage
import spack.util.path
import spack.util.spack_yaml
from spack.cmd.common import arguments
description = "manage bootstrap configuration"

View File

@@ -23,9 +23,14 @@
import spack.error
import spack.mirror
import spack.oci.oci
import spack.oci.opener
import spack.relocate
import spack.repo
import spack.spec
import spack.stage
import spack.store
import spack.user_environment
import spack.util.crypto
import spack.util.parallel
import spack.util.url as url_util
import spack.util.web as web_util

View File

@@ -4,7 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import spack.cmd
import spack.spec
from spack.cmd.common import arguments
description = "change an existing spec in an environment"

View File

@@ -15,6 +15,7 @@
import spack.repo
import spack.spec
import spack.stage
import spack.util.crypto
import spack.util.web as web_util
from spack.cmd.common import arguments
from spack.package_base import (

View File

@@ -19,6 +19,7 @@
import spack.cmd.buildcache as buildcache
import spack.config as cfg
import spack.environment as ev
import spack.environment.depfile
import spack.hash_types as ht
import spack.mirror
import spack.util.gpg as gpg_util

View File

@@ -10,9 +10,11 @@
import llnl.util.filesystem
import llnl.util.tty as tty
import spack.bootstrap
import spack.caches
import spack.cmd
import spack.cmd.test
import spack.config
import spack.repo
import spack.stage
import spack.store
import spack.util.path

View File

@@ -17,7 +17,6 @@
from llnl.util.tty.colify import colify
import spack.cmd
import spack.config
import spack.main
import spack.paths
import spack.platforms

View File

@@ -15,6 +15,7 @@
import spack.deptypes as dt
import spack.environment as ev
import spack.mirror
import spack.modules
import spack.reporters
import spack.spec
import spack.store

View File

@@ -9,7 +9,6 @@
import llnl.util.tty as tty
import spack.cmd
import spack.spec
display_args = {"long": True, "show_flags": False, "variants": False, "indent": 4}

View File

@@ -10,6 +10,7 @@
import spack.cmd
import spack.deptypes as dt
import spack.error
import spack.paths
import spack.spec
import spack.store
from spack import build_environment, traverse

View File

@@ -82,10 +82,7 @@ def compiler_find(args):
"""
paths = args.add_paths or None
new_compilers = spack.compilers.find_compilers(
path_hints=paths,
scope=args.scope,
mixed_toolchain=args.mixed_toolchain,
max_workers=args.jobs,
path_hints=paths, scope=args.scope, mixed_toolchain=args.mixed_toolchain
)
if new_compilers:
n = len(new_compilers)

View File

@@ -13,9 +13,9 @@
import spack.config
import spack.environment as ev
import spack.error
import spack.repo
import spack.schema.env
import spack.spec
import spack.schema.packages
import spack.store
import spack.util.spack_yaml as syaml
from spack.cmd.common import arguments
@@ -256,7 +256,7 @@ def config_remove(args):
existing.pop(value, None)
else:
# This should be impossible to reach
raise spack.error.ConfigError("Config has nested non-dict values")
raise spack.config.ConfigError("Config has nested non-dict values")
spack.config.set(path, existing, scope)
@@ -340,7 +340,7 @@ def _config_change(config_path, match_spec_str=None):
if not changed:
existing_requirements = spack.config.get(key_path)
if isinstance(existing_requirements, str):
raise spack.error.ConfigError(
raise spack.config.ConfigError(
"'config change' needs to append a requirement,"
" but existing require: config is not a list"
)
@@ -536,11 +536,11 @@ def config_prefer_upstream(args):
# Get and list all the variants that differ from the default.
variants = []
for var_name, variant in spec.variants.items():
if var_name in ["patches"] or not spec.package.has_variant(var_name):
if var_name in ["patches"] or var_name not in spec.package.variants:
continue
vdef = spec.package.get_variant(var_name)
if variant.value != vdef.default:
variant_desc, _ = spec.package.variants[var_name]
if variant.value != variant_desc.default:
variants.append(str(variant))
variants.sort()
variants = " ".join(variants)

View File

@@ -13,6 +13,7 @@
import spack.repo
import spack.stage
import spack.util.web
from spack.spec import Spec
from spack.url import (
UndetectableNameError,

View File

@@ -13,12 +13,11 @@
import llnl.util.tty as tty
from llnl.util.filesystem import working_dir
import spack
import spack.config
import spack.paths
import spack.platforms
import spack.spec
import spack.store
import spack.util.git
from spack.main import get_version
from spack.util.executable import which
description = "debugging commands for troubleshooting Spack"
@@ -90,7 +89,7 @@ def report(args):
host_os = host_platform.operating_system("frontend")
host_target = host_platform.target("frontend")
architecture = spack.spec.ArchSpec((str(host_platform), str(host_os), str(host_target)))
print("* **Spack:**", spack.get_version())
print("* **Spack:**", get_version())
print("* **Python:**", platform.python_version())
print("* **Platform:**", architecture)

View File

@@ -11,6 +11,7 @@
import spack.cmd
import spack.environment as ev
import spack.package_base
import spack.repo
import spack.store
from spack.cmd.common import arguments

View File

@@ -20,7 +20,6 @@
import spack.cmd
import spack.environment as ev
import spack.installer
import spack.store
from spack.cmd.common import arguments
from spack.database import InstallStatuses
@@ -143,4 +142,4 @@ def deprecate(parser, args):
tty.die("Will not deprecate any packages.")
for dcate, dcator in zip(all_deprecate, all_deprecators):
spack.installer.deprecate(dcate, dcator, symlink)
dcate.package.do_deprecate(dcator, symlink)

View File

@@ -8,13 +8,10 @@
import llnl.util.tty as tty
import spack.build_environment
import spack.cmd
import spack.cmd.common.arguments
import spack.config
import spack.repo
from spack.cmd.common import arguments
from spack.installer import PackageInstaller
description = "developer build: build from code in current working directory"
section = "build"
@@ -132,9 +129,9 @@ def dev_build(self, args):
elif args.test == "root":
tests = [spec.name for spec in specs]
PackageInstaller(
[spec.package],
spec.package.do_install(
tests=tests,
make_jobs=args.jobs,
keep_prefix=args.keep_prefix,
install_deps=not args.ignore_deps,
verbose=not args.quiet,
@@ -142,7 +139,7 @@ def dev_build(self, args):
stop_before=args.before,
skip_patch=args.skip_patch,
stop_at=args.until,
).install()
)
# drop into the build environment of the package?
if args.shell is not None:

View File

@@ -10,6 +10,7 @@
import spack.cmd
import spack.config
import spack.fetch_strategy
import spack.package_base
import spack.repo
import spack.spec
import spack.stage

View File

@@ -12,6 +12,7 @@
import spack.cmd
import spack.environment as ev
import spack.solver.asp as asp
import spack.util.environment
import spack.util.spack_json as sjson
from spack.cmd.common import arguments

View File

@@ -21,12 +21,15 @@
import spack.cmd
import spack.cmd.common
import spack.cmd.common.arguments
import spack.cmd.install
import spack.cmd.modules
import spack.cmd.uninstall
import spack.config
import spack.environment as ev
import spack.environment.depfile as depfile
import spack.environment.environment
import spack.environment.shell
import spack.schema.env
import spack.spec
import spack.tengine
from spack.cmd.common import arguments
from spack.util.environment import EnvironmentModifications

View File

@@ -18,9 +18,9 @@
import spack.cray_manifest as cray_manifest
import spack.detection
import spack.error
import spack.package_base
import spack.repo
import spack.spec
import spack.util.environment
from spack.cmd.common import arguments
description = "manage external packages in Spack configuration"
@@ -135,9 +135,7 @@ def external_find(args):
candidate_packages = packages_to_search_for(
names=args.packages, tags=args.tags, exclude=args.exclude
)
detected_packages = spack.detection.by_path(
candidate_packages, path_hints=args.path, max_workers=args.jobs
)
detected_packages = spack.detection.by_path(candidate_packages, path_hints=args.path)
new_specs = spack.detection.update_configuration(
detected_packages, scope=args.scope, buildable=not args.not_buildable

View File

@@ -8,6 +8,7 @@
import spack.cmd
import spack.config
import spack.environment as ev
import spack.repo
import spack.traverse
from spack.cmd.common import arguments

View File

@@ -10,11 +10,10 @@
import llnl.util.tty as tty
import llnl.util.tty.color as color
import spack.bootstrap
import spack.cmd as cmd
import spack.config
import spack.environment as ev
import spack.repo
import spack.spec
import spack.store
from spack.cmd.common import arguments
from spack.database import InstallStatuses

View File

@@ -16,7 +16,6 @@
import spack.install_test
import spack.repo
import spack.spec
import spack.variant
import spack.version
from spack.cmd.common import arguments
from spack.package_base import preferred_version
@@ -49,7 +48,6 @@ def setup_parser(subparser):
options = [
("--detectable", print_detectable.__doc__),
("--maintainers", print_maintainers.__doc__),
("--namespace", print_namespace.__doc__),
("--no-dependencies", "do not " + print_dependencies.__doc__),
("--no-variants", "do not " + print_variants.__doc__),
("--no-versions", "do not " + print_versions.__doc__),
@@ -191,15 +189,6 @@ def print_maintainers(pkg, args):
color.cprint(section_title("Maintainers: ") + mnt)
def print_namespace(pkg, args):
"""output package namespace"""
repo = spack.repo.PATH.get_repo(pkg.namespace)
color.cprint("")
color.cprint(section_title("Namespace:"))
color.cprint(f" @c{{{repo.namespace}}} at {repo.root}")
def print_phases(pkg, args):
"""output installation phases"""
@@ -334,6 +323,26 @@ def _fmt_variant(variant, max_name_default_len, indent, when=None, out=None):
out.write("\n")
def _variants_by_name_when(pkg):
"""Adaptor to get variants keyed by { name: { when: { [Variant...] } }."""
# TODO: replace with pkg.variants_by_name(when=True) when unified directive dicts are merged.
variants = {}
for name, (variant, whens) in sorted(pkg.variants.items()):
for when in whens:
variants.setdefault(name, {}).setdefault(when, []).append(variant)
return variants
def _variants_by_when_name(pkg):
"""Adaptor to get variants keyed by { when: { name: Variant } }"""
# TODO: replace with pkg.variants when unified directive dicts are merged.
variants = {}
for name, (variant, whens) in pkg.variants.items():
for when in whens:
variants.setdefault(when, {})[name] = variant
return variants
def _print_variants_header(pkg):
"""output variants"""
@@ -344,22 +353,32 @@ def _print_variants_header(pkg):
color.cprint("")
color.cprint(section_title("Variants:"))
variants_by_name = _variants_by_name_when(pkg)
# Calculate the max length of the "name [default]" part of the variant display
# This lets us know where to print variant values.
max_name_default_len = max(
color.clen(_fmt_name_and_default(variant))
for name in pkg.variant_names()
for _, variant in pkg.variant_definitions(name)
for name, when_variants in variants_by_name.items()
for variants in when_variants.values()
for variant in variants
)
return max_name_default_len
return max_name_default_len, variants_by_name
def _unconstrained_ver_first(item):
"""sort key that puts specs with open version ranges first"""
spec, _ = item
return (spack.version.any_version not in spec.versions, spec)
def print_variants_grouped_by_when(pkg):
max_name_default_len = _print_variants_header(pkg)
max_name_default_len, _ = _print_variants_header(pkg)
indent = 4
for when, variants_by_name in pkg.variant_items():
variants = _variants_by_when_name(pkg)
for when, variants_by_name in sorted(variants.items(), key=_unconstrained_ver_first):
padded_values = max_name_default_len + 4
start_indent = indent
@@ -377,14 +396,15 @@ def print_variants_grouped_by_when(pkg):
def print_variants_by_name(pkg):
max_name_default_len = _print_variants_header(pkg)
max_name_default_len, variants_by_name = _print_variants_header(pkg)
max_name_default_len += 4
indent = 4
for name in pkg.variant_names():
for when, variant in pkg.variant_definitions(name):
_fmt_variant(variant, max_name_default_len, indent, when, out=sys.stdout)
sys.stdout.write("\n")
for name, when_variants in variants_by_name.items():
for when, variants in sorted(when_variants.items(), key=_unconstrained_ver_first):
for variant in variants:
_fmt_variant(variant, max_name_default_len, indent, when, out=sys.stdout)
sys.stdout.write("\n")
def print_variants(pkg, args):
@@ -502,7 +522,6 @@ def info(parser, args):
# Now output optional information in expected order
sections = [
(args.all or args.maintainers, print_maintainers),
(args.all or args.namespace, print_namespace),
(args.all or args.detectable, print_detectable),
(args.all or args.tags, print_tags),
(args.all or not args.no_versions, print_versions),

View File

@@ -13,15 +13,18 @@
from llnl.string import plural
from llnl.util import lang, tty
import spack.build_environment
import spack.cmd
import spack.config
import spack.environment as ev
import spack.fetch_strategy
import spack.package_base
import spack.paths
import spack.report
import spack.spec
import spack.store
from spack.cmd.common import arguments
from spack.error import InstallError, SpackError
from spack.error import SpackError
from spack.installer import PackageInstaller
description = "build and install packages"
@@ -284,7 +287,7 @@ def require_user_confirmation_for_overwrite(concrete_specs, args):
tty.die("Reinstallation aborted.")
def _dump_log_on_error(e: InstallError):
def _dump_log_on_error(e: spack.build_environment.InstallError):
e.print_context()
assert e.pkg, "Expected InstallError to include the associated package"
if not os.path.exists(e.pkg.log_path):
@@ -349,7 +352,7 @@ def reporter_factory(specs):
install_with_active_env(env, args, install_kwargs, reporter_factory)
else:
install_without_active_env(args, install_kwargs, reporter_factory)
except InstallError as e:
except spack.build_environment.InstallError as e:
if args.show_log_on_error:
_dump_log_on_error(e)
raise
@@ -474,5 +477,5 @@ def install_without_active_env(args, install_kwargs, reporter_factory):
installs = [s.package for s in concrete_specs]
install_kwargs["explicit"] = [s.dag_hash() for s in concrete_specs]
builder = PackageInstaller(installs, **install_kwargs)
builder = PackageInstaller(installs, install_kwargs)
builder.install()

View File

@@ -6,10 +6,11 @@
import sys
import spack.cmd
import spack.cmd.common
import spack.cmd.find
import spack.environment as ev
import spack.store
import spack.user_environment as uenv
import spack.util.environment
from spack.cmd.common import arguments
description = "add package to the user environment"

View File

@@ -8,6 +8,9 @@
from llnl.util import tty
import spack.cmd
import spack.error
import spack.package_base
import spack.repo
import spack.store
from spack.cmd.common import arguments
from spack.database import InstallStatuses

View File

@@ -17,6 +17,7 @@
import spack.mirror
import spack.repo
import spack.spec
import spack.util.path
import spack.util.web as web_util
from spack.cmd.common import arguments
from spack.error import SpackError

View File

@@ -15,7 +15,6 @@
import spack.cmd
import spack.config
import spack.error
import spack.modules
import spack.modules.common
import spack.repo
@@ -125,13 +124,13 @@ def check_module_set_name(name):
names = [k for k in modules if k != "prefix_inspections"]
if not names:
raise spack.error.ConfigError(
raise spack.config.ConfigError(
f"Module set configuration is missing. Cannot use module set '{name}'"
)
pretty_names = "', '".join(names)
raise spack.error.ConfigError(
raise spack.config.ConfigError(
f"Cannot use invalid module set '{name}'.",
f"Valid module set names are: '{pretty_names}'.",
)
@@ -173,7 +172,7 @@ def loads(module_type, specs, args, out=None):
modules = list(
(
spec,
spack.modules.get_module(
spack.modules.common.get_module(
module_type,
spec,
get_full_path=False,
@@ -222,7 +221,7 @@ def find(module_type, specs, args):
try:
modules = [
spack.modules.get_module(
spack.modules.common.get_module(
module_type,
spec,
args.full_path,
@@ -233,7 +232,7 @@ def find(module_type, specs, args):
]
modules.append(
spack.modules.get_module(
spack.modules.common.get_module(
module_type,
single_spec,
args.full_path,

View File

@@ -9,6 +9,7 @@
import spack.config
import spack.environment as ev
import spack.package_base
import spack.repo
import spack.traverse
from spack.cmd.common import arguments

View File

@@ -12,6 +12,7 @@
from llnl.util.tty.colify import colify
import spack.cmd
import spack.paths
import spack.repo
import spack.util.executable as exe
import spack.util.package_hash as ph

View File

@@ -78,8 +78,8 @@ def python(parser, args, unknown_args):
# Run user choice of interpreter
if args.python_interpreter == "ipython":
return ipython_interpreter(args)
return python_interpreter(args)
return spack.cmd.python.ipython_interpreter(args)
return spack.cmd.python.python_interpreter(args)
def ipython_interpreter(args):

View File

@@ -6,6 +6,7 @@
import llnl.util.tty as tty
import spack.cmd
import spack.repo
from spack.cmd.common import arguments
description = "revert checked out package source code"

View File

@@ -12,12 +12,11 @@
import spack
import spack.cmd
import spack.cmd.common.arguments
import spack.config
import spack.environment
import spack.hash_types as ht
import spack.package_base
import spack.solver.asp as asp
import spack.spec
from spack.cmd.common import arguments
description = "concretize a specs using an ASP solver"

View File

@@ -14,7 +14,6 @@
import spack.hash_types as ht
import spack.spec
import spack.store
import spack.traverse
from spack.cmd.common import arguments
description = "show what would be installed, given a spec"

View File

@@ -11,6 +11,8 @@
import spack.config
import spack.environment as ev
import spack.package_base
import spack.repo
import spack.stage
import spack.traverse
from spack.cmd.common import arguments

View File

@@ -9,8 +9,8 @@
import llnl.util.tty as tty
import llnl.util.tty.colify as colify
import spack.environment
import spack.repo
import spack.store
import spack.tag
description = "show package tags and associated packages"

View File

@@ -15,12 +15,11 @@
from llnl.util.tty import colify
import spack.cmd
import spack.config
import spack.environment as ev
import spack.install_test
import spack.package_base
import spack.repo
import spack.report
import spack.store
from spack.cmd.common import arguments
description = "run spack's tests for an install"

View File

@@ -10,7 +10,6 @@
from llnl.util.filesystem import working_dir
import spack
import spack.cmd
import spack.config
import spack.paths
import spack.util.git

View File

@@ -6,7 +6,6 @@
import llnl.util.tty as tty
import spack.cmd
import spack.config
from spack.cmd.common import arguments
description = "remove specs from an environment"

View File

@@ -10,8 +10,6 @@
import re
import sys
import spack.extensions
try:
import pytest
except ImportError:

View File

@@ -7,10 +7,9 @@
import sys
import spack.cmd
import spack.cmd.common
import spack.error
import spack.store
import spack.user_environment as uenv
import spack.util.environment
from spack.cmd.common import arguments
description = "remove package from the user environment"

View File

@@ -6,7 +6,6 @@
import llnl.util.tty as tty
import spack.cmd
import spack.environment as ev
import spack.store
import spack.verify

View File

@@ -202,6 +202,18 @@ class Compiler:
support for specific compilers, their possible names, arguments,
and how to identify the particular type of compiler."""
# Subclasses use possible names of C compiler
cc_names: List[str] = []
# Subclasses use possible names of C++ compiler
cxx_names: List[str] = []
# Subclasses use possible names of Fortran 77 compiler
f77_names: List[str] = []
# Subclasses use possible names of Fortran 90 compiler
fc_names: List[str] = []
# Optional prefix regexes for searching for this type of compiler.
# Prefixes are sometimes used for toolchains
prefixes: List[str] = []
@@ -607,6 +619,18 @@ def extract_version_from_output(cls, output):
def cc_version(cls, cc):
return cls.default_version(cc)
@classmethod
def cxx_version(cls, cxx):
return cls.default_version(cxx)
@classmethod
def f77_version(cls, f77):
return cls.default_version(f77)
@classmethod
def fc_version(cls, fc):
return cls.default_version(fc)
@classmethod
def search_regexps(cls, language):
# Compile all the regular expressions used for files beforehand.

View File

@@ -8,7 +8,6 @@
"""
import importlib
import os
import re
import sys
import warnings
from typing import Dict, List, Optional
@@ -26,6 +25,7 @@
import spack.platforms
import spack.repo
import spack.spec
import spack.version
from spack.operating_systems import windows_os
from spack.util.environment import get_path
from spack.util.naming import mod_to_class
@@ -243,7 +243,6 @@ def find_compilers(
*,
scope: Optional[str] = None,
mixed_toolchain: bool = False,
max_workers: Optional[int] = None,
) -> List["spack.compiler.Compiler"]:
"""Searches for compiler in the paths given as argument. If any new compiler is found, the
configuration is updated, and the list of new compiler objects is returned.
@@ -254,7 +253,6 @@ def find_compilers(
scope: configuration scope to modify
mixed_toolchain: allow mixing compilers from different toolchains if otherwise missing for
a certain language
max_workers: number of processes used to search for compilers
"""
import spack.detection
@@ -267,9 +265,7 @@ def find_compilers(
default_paths.extend(windows_os.WindowsOs().compiler_search_paths)
compiler_pkgs = spack.repo.PATH.packages_with_tags(COMPILER_TAG, full=True)
detected_packages = spack.detection.by_path(
compiler_pkgs, path_hints=default_paths, max_workers=max_workers
)
detected_packages = spack.detection.by_path(compiler_pkgs, path_hints=default_paths)
valid_compilers = {}
for name, detected in detected_packages.items():
@@ -558,7 +554,7 @@ def get_compilers(config, cspec=None, arch_spec=None):
except KeyError:
# TODO: Check if this exception handling makes sense, or if we
# TODO: need to change / refactor tests
family = str(arch_spec.target)
family = arch_spec.target
except AttributeError:
assert arch_spec is None
@@ -632,34 +628,37 @@ def is_mixed_toolchain(compiler):
Args:
compiler (spack.compiler.Compiler): a valid compiler object
"""
import spack.detection.path
executables = [
os.path.basename(compiler.cc or ""),
os.path.basename(compiler.cxx or ""),
os.path.basename(compiler.f77 or ""),
os.path.basename(compiler.fc or ""),
]
cc = os.path.basename(compiler.cc or "")
cxx = os.path.basename(compiler.cxx or "")
f77 = os.path.basename(compiler.f77 or "")
fc = os.path.basename(compiler.fc or "")
toolchains = set()
finder = spack.detection.path.ExecutablesFinder()
for compiler_cls in all_compiler_types():
# Inspect all the compiler toolchain we know. If a compiler is the
# only compiler supported there it belongs to that toolchain.
def name_matches(name, name_list):
# This is such that 'gcc' matches variations
# like 'ggc-9' etc that are found in distros
name, _, _ = name.partition("-")
return len(name_list) == 1 and name and name in name_list
for pkg_name in spack.repo.PATH.packages_with_tags(COMPILER_TAG):
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
patterns = finder.search_patterns(pkg=pkg_cls)
if not patterns:
continue
joined_pattern = re.compile(r"|".join(patterns))
if any(joined_pattern.search(exe) for exe in executables):
tty.debug(f"[TOOLCHAIN] MATCH {pkg_name}")
toolchains.add(pkg_name)
if any(
[
name_matches(cc, compiler_cls.cc_names),
name_matches(cxx, compiler_cls.cxx_names),
name_matches(f77, compiler_cls.f77_names),
name_matches(fc, compiler_cls.fc_names),
]
):
tty.debug("[TOOLCHAIN] MATCH {0}".format(compiler_cls.__name__))
toolchains.add(compiler_cls.__name__)
if len(toolchains) > 1:
if (
toolchains == {"llvm", "apple-clang", "aocc"}
toolchains == set(["Clang", "AppleClang", "Aocc"])
# Msvc toolchain uses Intel ifx
or toolchains == {"msvc", "intel-oneapi-compilers"}
or toolchains == set(["Msvc", "Dpcpp", "Oneapi"])
):
return False
tty.debug("[TOOLCHAINS] {0}".format(toolchains))
@@ -803,11 +802,12 @@ def _extract_os_and_target(spec: "spack.spec.Spec"):
if not spec.architecture:
host_platform = spack.platforms.host()
operating_system = host_platform.operating_system("default_os")
target = host_platform.target("default_target")
target = host_platform.target("default_target").microarchitecture
else:
target = spec.architecture.target
if not target:
target = spack.platforms.host().target("default_target")
target = target.microarchitecture
operating_system = spec.os
if not operating_system:

View File

@@ -13,6 +13,18 @@
class Aocc(Compiler):
# Subclasses use possible names of C compiler
cc_names = ["clang"]
# Subclasses use possible names of C++ compiler
cxx_names = ["clang++"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["flang"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["flang"]
version_argument = "--version"
@property

View File

@@ -8,6 +8,7 @@
import spack.compiler
import spack.compilers.clang
import spack.util.executable
from spack.version import Version

View File

@@ -9,6 +9,18 @@
class Arm(spack.compiler.Compiler):
# Subclasses use possible names of C compiler
cc_names = ["armclang"]
# Subclasses use possible names of C++ compiler
cxx_names = ["armclang++"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["armflang"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["armflang"]
# Named wrapper links within lib/spack/env
link_paths = {
"cc": os.path.join("arm", "armclang"),
@@ -78,3 +90,11 @@ def fc_pic_flag(self):
return "-fPIC"
required_libs = ["libclang", "libflang"]
@classmethod
def fc_version(cls, fc):
return cls.default_version(fc)
@classmethod
def f77_version(cls, f77):
return cls.fc_version(f77)

View File

@@ -19,6 +19,18 @@ def __init__(self, *args, **kwargs):
if not self.is_clang_based:
self.version_argument = "-V"
# Subclasses use possible names of C compiler
cc_names = ["craycc"]
# Subclasses use possible names of C++ compiler
cxx_names = ["crayCC"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["crayftn"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["crayftn"]
# MacPorts builds gcc versions with prefixes and -mp-X.Y suffixes.
suffixes = [r"-mp-\d\.\d"]

View File

@@ -31,6 +31,18 @@
class Clang(Compiler):
# Subclasses use possible names of C compiler
cc_names = ["clang"]
# Subclasses use possible names of C++ compiler
cxx_names = ["clang++"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["flang-new", "flang"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["flang-new", "flang"]
version_argument = "--version"
@property

View File

@@ -9,6 +9,18 @@
class Fj(spack.compiler.Compiler):
# Subclasses use possible names of C compiler
cc_names = ["fcc"]
# Subclasses use possible names of C++ compiler
cxx_names = ["FCC"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["frt"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["frt"]
# Named wrapper links within build_env_path
link_paths = {
"cc": os.path.join("fj", "fcc"),

View File

@@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
from llnl.util.filesystem import ancestor
@@ -14,6 +15,18 @@
class Gcc(spack.compiler.Compiler):
# Subclasses use possible names of C compiler
cc_names = ["gcc"]
# Subclasses use possible names of C++ compiler
cxx_names = ["g++"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["gfortran"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["gfortran"]
# MacPorts builds gcc versions with prefixes and -mp-X or -mp-X.Y suffixes.
# Homebrew and Linuxbrew may build gcc with -X, -X.Y suffixes.
# Old compatibility versions may contain XY suffixes.
@@ -168,6 +181,40 @@ def default_version(cls, cc):
version = cls.extract_version_from_output(output)
return version
@classmethod
def fc_version(cls, fc):
"""Older versions of gfortran use the ``-dumpversion`` option.
Output looks like this::
GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
Copyright (C) 2010 Free Software Foundation, Inc.
or::
4.8.5
In GCC 7, this option was changed to only return the major
version of the compiler::
7
A new ``-dumpfullversion`` option was added that gives us
what we want::
7.2.0
"""
output = spack.compiler.get_compiler_version_output(fc, "-dumpversion")
match = re.search(r"(?:GNU Fortran \(GCC\) )?([\d.]+)", output)
version = match.group(match.lastindex) if match else "unknown"
if Version(version) >= Version("7"):
output = spack.compiler.get_compiler_version_output(fc, "-dumpfullversion")
version = cls.extract_version_from_output(output)
return version
@classmethod
def f77_version(cls, f77):
return cls.fc_version(f77)
@property
def stdcxx_libs(self):
return ("-lstdc++",)

View File

@@ -11,6 +11,18 @@
class Intel(Compiler):
# Subclasses use possible names of C compiler
cc_names = ["icc"]
# Subclasses use possible names of C++ compiler
cxx_names = ["icpc"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["ifort"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["ifort"]
# Named wrapper links within build_env_path
link_paths = {
"cc": os.path.join("intel", "icc"),

View File

@@ -8,7 +8,7 @@
import subprocess
import sys
import tempfile
from typing import Dict
from typing import Dict, List
import archspec.cpu
@@ -117,6 +117,18 @@ def get_valid_fortran_pth():
class Msvc(Compiler):
# Subclasses use possible names of C compiler
cc_names: List[str] = ["cl"]
# Subclasses use possible names of C++ compiler
cxx_names: List[str] = ["cl"]
# Subclasses use possible names of Fortran 77 compiler
f77_names: List[str] = ["ifx"]
# Subclasses use possible names of Fortran 90 compiler
fc_names: List[str] = ["ifx"]
# Named wrapper links within build_env_path
# Due to the challenges of supporting compiler wrappers
# in Windows, we leave these blank, and dynamically compute
@@ -381,3 +393,7 @@ def fc_version(cls, fc):
)
clp = spack.util.executable.which_string("cl", path=sps)
return cls.default_version(clp) if clp else fc_ver
@classmethod
def f77_version(cls, f77):
return cls.fc_version(f77)

View File

@@ -5,6 +5,7 @@
import os
import re
from typing import List
import llnl.util.lang
@@ -12,6 +13,18 @@
class Nag(spack.compiler.Compiler):
# Subclasses use possible names of C compiler
cc_names: List[str] = []
# Subclasses use possible names of C++ compiler
cxx_names: List[str] = []
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["nagfor"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["nagfor"]
# Named wrapper links within build_env_path
# Use default wrappers for C and C++, in case provided in compilers.yaml
link_paths = {

View File

@@ -9,6 +9,18 @@
class Nvhpc(Compiler):
# Subclasses use possible names of C compiler
cc_names = ["nvc"]
# Subclasses use possible names of C++ compiler
cxx_names = ["nvc++"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["nvfortran"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["nvfortran"]
# Named wrapper links within build_env_path
link_paths = {
"cc": os.path.join("nvhpc", "nvc"),

View File

@@ -13,6 +13,18 @@
class Oneapi(Compiler):
# Subclasses use possible names of C compiler
cc_names = ["icx"]
# Subclasses use possible names of C++ compiler
cxx_names = ["icpx"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["ifx"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["ifx"]
# Named wrapper links within build_env_path
link_paths = {
"cc": os.path.join("oneapi", "icx"),

View File

@@ -10,6 +10,18 @@
class Pgi(Compiler):
# Subclasses use possible names of C compiler
cc_names = ["pgcc"]
# Subclasses use possible names of C++ compiler
cxx_names = ["pgc++", "pgCC"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["pgfortran", "pgf77"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["pgfortran", "pgf95", "pgf90"]
# Named wrapper links within build_env_path
link_paths = {
"cc": os.path.join("pgi", "pgcc"),

View File

@@ -11,6 +11,18 @@
class Rocmcc(spack.compilers.clang.Clang):
# Subclasses use possible names of C compiler
cc_names = ["amdclang"]
# Subclasses use possible names of C++ compiler
cxx_names = ["amdclang++"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["amdflang"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["amdflang"]
@property
def link_paths(self):
link_paths = {
@@ -49,6 +61,14 @@ def extract_version_from_output(cls, output):
if match:
return ".".join(match.groups())
@classmethod
def fc_version(cls, fortran_compiler):
return cls.default_version(fortran_compiler)
@classmethod
def f77_version(cls, f77):
return cls.fc_version(f77)
@property
def stdcxx_libs(self):
return ("-lstdc++",)

View File

@@ -10,6 +10,18 @@
class Xl(Compiler):
# Subclasses use possible names of C compiler
cc_names = ["xlc"]
# Subclasses use possible names of C++ compiler
cxx_names = ["xlC", "xlc++"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["xlf"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["xlf90", "xlf95", "xlf2003", "xlf2008"]
# Named wrapper links within build_env_path
link_paths = {
"cc": os.path.join("xl", "xlc"),
@@ -91,3 +103,31 @@ def fflags(self):
# For Fortran 90 and beyond, it is set by default and has not impact.
# Its use has no negative side effects.
return "-qzerosize"
@classmethod
def fc_version(cls, fc):
# The fortran and C/C++ versions of the XL compiler are always
# two units apart. By this we mean that the fortran release that
# goes with XL C/C++ 11.1 is 13.1. Having such a difference in
# version number is confusing spack quite a lot. Most notably
# if you keep the versions as is the default xl compiler will
# only have fortran and no C/C++. So we associate the Fortran
# compiler with the version associated to the C/C++ compiler.
# One last stumble. Version numbers over 10 have at least a .1
# those under 10 a .0. There is no xlf 9.x or under currently
# available. BG/P and BG/L can such a compiler mix and possibly
# older version of AIX and linux on power.
fortran_version = cls.default_version(fc)
if fortran_version >= 16:
# Starting with version 16.1, the XL C and Fortran compilers
# have the same version. So no need to downgrade the Fortran
# compiler version to match that of the C compiler version.
return str(fortran_version)
c_version = float(fortran_version) - 2
if c_version < 10:
c_version = c_version - 0.1
return str(c_version)
@classmethod
def f77_version(cls, f77):
return cls.fc_version(f77)

View File

@@ -9,6 +9,18 @@
class XlR(spack.compilers.xl.Xl):
# Subclasses use possible names of C compiler
cc_names = ["xlc_r"]
# Subclasses use possible names of C++ compiler
cxx_names = ["xlC_r", "xlc++_r"]
# Subclasses use possible names of Fortran 77 compiler
f77_names = ["xlf_r"]
# Subclasses use possible names of Fortran 90 compiler
fc_names = ["xlf90_r", "xlf95_r", "xlf2003_r", "xlf2008_r"]
# Named wrapper links within build_env_path
link_paths = {
"cc": os.path.join("xl_r", "xlc_r"),

View File

@@ -8,8 +8,16 @@
from contextlib import contextmanager
from itertools import chain
import spack.compilers
import spack.config
import spack.environment
import spack.error
import spack.platforms
import spack.repo
import spack.spec
import spack.target
import spack.tengine
import spack.util.path
CHECK_COMPILER_EXISTENCE = True

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