Compare commits

...

12 Commits

Author SHA1 Message Date
Todd Gamblin
37bb0843fd clean up some comments
Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2025-05-20 09:25:20 -07:00
Todd Gamblin
07a8f6235b merge three branches into one 2025-05-20 01:02:49 -07:00
Todd Gamblin
485291ef20 Omit fake edge to root
This saves singificant time in comparison

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2025-05-19 15:59:03 -07:00
Todd Gamblin
8363fbf40f Spec: use short-circuiting, stable comparison
## Background

Spec comparison on develop used a somewhat questionable optimization to
get decent spec comparison performance -- instead of comparing entire spec
DAGs, it put a `hash()` call in `_cmp_iter()` and compared specs by their
runtime hashes. This gets us good performance abstract specs, which don't
have complex dependencies and for which hashing is cheap. But it makes
the order of specs unstable and hard to reproduce.

We really need to do a full, consistent traversal over specs to compare
and to get a stable ordering. Simply taking the hash out and yielding
dependencies recursively (i.e. yielding `dep.spec._cmp_iter()` instead
of a hash) goes exponential for concrete specs because it explores all
paths. Traversal tracks visited nodes, but it's expensive to set up
the data structures for that, and it can slow down comparison of simple
abstract specs. Abstract spec comparison performance is important for
concretization (specifically setup), so we don't want to do that.

## New comparison algorithm

We can have (mostly) the best of both worlds -- it's just a bit more
complicated.

This changes Spec comparison to do a proper, stable graph comparison:

1. Spec comparison will now short-circuit whenever possible for concrete
   specs, when DAG hashes are known to be equal or not equal. This means
   that concrete spec `==` and `!=` comparisons will no longer have
   to traverse the whole DAG.

2. Spec comparison now traverses the graph consistently, comparing nodes
   and edges in breadth-first order. This means Spec sort order is stable,
   and it won't vary arbitrarily from run to run.

3. Traversal can be expensive, so we avoid it for simple specs. Specifically,
   if a spec has no dependencies, or if its dependencies have no dependencies,
   we avoid calling `traverse_edges()` by doing some special casing.

The `_cmp_iter` method for `Spec` now iterates over the DAG and yields nodes
in BFS order. While it does that, it generates consistent ids for each node,
based on traversal order. It then outputs edges in terms of these ids, along with
their depflags and virtuals, so that all parts of the Spec DAG are included.
The resulting total ordering of specs keys on node attributes first, then
dependency nodes, then any edge differences between graphs.

Optimized cases skip the id generation and traversal, since we know the
order and therefore the ids in advance.

## Performance ramifications

### Abstract specs

This seems to add around 7-8% overhead to concretization setup time. It's
worth the cost, because this enables concretization caching (as input to
concretization was previously not stable) and setup will eventually be
parallelized, at which point it will no longer be a bottleneck for solving.
Together those two optimizations will cut well over 50% of the time (likely
closer to 90+%) off of most solves.

### Concrete specs

Comparison for concrete specs is faster than before, sometimes *way* faster
because comparison is now guaranteed to be linear time w.r.t. DAG size.
Times for comparing concrete Specs:

```python
def compare(json):
    a = spack.spec.Spec(json)
    b = spack.spec.Spec(json)
    print(a == b)
    print(timeit.timeit(lambda: a == b, number=1))

compare("./py-black.json")
compare("./hdf5.json")
```

* `develop` (uses our prior hash optimization):
  * `py-black`: 7.013e-05s
  * `py-hdf5`: 6.445e-05s

* `develop` with full traversal and no hash:
  * `py-black`: 3.955s
  * `py-hdf5`: 0.0122s

* This branch (full traversal, stable, short-circuiting, no hash)
  * `py-black`: 2.208e-06s
  * `py-hdf5`: 3.416e-06s

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2025-05-19 15:59:03 -07:00
Todd Gamblin
e4b898f7c3 lazy_lexicographic_ordering: Add short-circuiting with _cmp_fast_eq
Add a `_cmp_fast_eq` method to the `lazy_lexicographic_ordering` protocol
so that implementors can short-circuit full comparison if they know (e.g.
with a hash) that objects are equal (or not).

`_cmp_fast_eq` can return True (known true), False (known false), or
None (unknown -- do full comparison).

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2025-05-19 15:59:03 -07:00
Todd Gamblin
a5f1a4ea81 Spec: Remove unused methods on _EdgeMap
`_EdgeMap` implements `_cmp_iter` for `lazy_lexicographic_ordering` but it's never used
or tested. Remove it.

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2025-05-19 15:59:02 -07:00
Harmen Stoppels
2929ea02a1 Move builders into builtin repo (#50452)
Builders and package classes refer to packages from the builtin package
repo and are often modified together with packages. That means that
these classes should move into `spack_repo.builtin`.

* move `spack.build_systems` -> `spack_repo.builtin.build_systems`

* Remove the following re-exports from the `spack.package` module:
  - `AspellDictPackage`                 - `LuaPackage`
  - `AutotoolsPackage`                  - `MakefilePackage`
  - `BundlePackage`                     - `MavenPackage`
  - `CachedCMakePackage`                - `MesonPackage`
  - `cmake_cache_filepath`              - `MSBuildPackage`
  - `cmake_cache_option`                - `NMakePackage`
  - `cmake_cache_path`                  - `OctavePackage`
  - `cmake_cache_string`                - `PerlPackage`
  - `CargoPackage`                      - `PythonExtension`
  - `CMakePackage`                      - `PythonPackage`
  - `generator`                         - `QMakePackage`
  - `CompilerPackage`                   - `RacketPackage`
  - `CudaPackage`                       - `RPackage`
  - `Package`                           - `ROCmPackage`
  - `GNUMirrorPackage`                  - `RubyPackage`
  - `GoPackage`                         - `SConsPackage`
  - `IntelPackage`                      - `SIPPackage`
  - `IntelOneApiLibraryPackageWithSdk`  - `SourceforgePackage`
  - `IntelOneApiLibraryPackage`         - `SourcewarePackage`
  - `IntelOneApiStaticLibraryList`      - `WafPackage`
  - `IntelOneApiPackage`                - `XorgPackage`
  - `INTEL_MATH_LIBRARIES`

* update mock packages to repo v2.0 and add copies of packages/build
  systems they use from builtin

* add missing imports to build systems in `package.py` from builtin
  and test repos

* update various tests

This PR is breaking because of removal of various names from
 `spack.package`, but breakage should be minimal thanks to #50496, which
 ensures the above names are always imported in repo v1 packages.

Specifically this PR breaks imports like the following in `package.py` files:

```python
from spack.package import Package
```

but if your repo is v1.0 (see `spack repo list`) and has the following
much more common pattern:

```python
from spack.package import *
```

nothing should break.
2025-05-18 20:31:20 -07:00
downloadico
c99e654650 meme: add version 5.5.7 (#50517) 2025-05-18 18:45:10 -07:00
Chris White
8ba4b3c103 forward shared variant to parmetis/metis (#50461) 2025-05-17 08:13:11 -06:00
Afzal Patel
240e669793 ci: remove ck from ML ROCm stack (#50508) 2025-05-17 13:33:22 +02:00
Luc Berger
2bda9159d3 kokkos ecosystem: release 4.6.01 (#50271) 2025-05-16 20:47:54 -06:00
John W. Parent
b12a64d687 msmpi package: fix build (#50263)
Restores ability to build MSMPI from source.

* Modernizes the MSMPI package
* Strips out MSMPI build system that is long deprecated
* Adds patches to re-introduce missing functionality from said build system
* Adds builds + support for dependencies no longer fetched by build system
2025-05-16 22:03:33 +00:00
9092 changed files with 24959 additions and 1369 deletions

View File

@@ -66,7 +66,7 @@ on these ideas for each distinct build system that Spack supports:
build_systems/rocmpackage
build_systems/sourceforgepackage
For reference, the :py:mod:`Build System API docs <spack.build_systems>`
For reference, the :py:mod:`Build System API docs <spack_repo.builtin.build_systems>`
provide a list of build systems and methods/attributes that can be
overridden. If you are curious about the implementation of a particular
build system, you can view the source code by running:
@@ -90,7 +90,7 @@ packages. You can quickly find examples by running:
You can then view these packages with ``spack edit``.
This guide is intended to supplement the
:py:mod:`Build System API docs <spack.build_systems>` with examples of
:py:mod:`Build System API docs <spack_repo.builtin.build_systems>` with examples of
how to override commonly used methods. It also provides rules of thumb
and suggestions for package developers who are unfamiliar with a
particular build system.

View File

@@ -129,8 +129,8 @@ Adding flags to cmake
To add additional flags to the ``cmake`` call, simply override the
``cmake_args`` function. The following example defines values for the flags
``WHATEVER``, ``ENABLE_BROKEN_FEATURE``, ``DETECT_HDF5``, and ``THREADS`` with
and without the :meth:`~spack.build_systems.cmake.CMakeBuilder.define` and
:meth:`~spack.build_systems.cmake.CMakeBuilder.define_from_variant` helper functions:
and without the :meth:`~spack_repo.builtin.build_systems.cmake.CMakeBuilder.define` and
:meth:`~spack_repo.builtin.build_systems.cmake.CMakeBuilder.define_from_variant` helper functions:
.. code-block:: python

View File

@@ -36,6 +36,7 @@
os.symlink(os.path.abspath("../../.."), link_name, target_is_directory=True)
sys.path.insert(0, os.path.abspath("_spack_root/lib/spack/external"))
sys.path.append(os.path.abspath("_spack_root/lib/spack/"))
sys.path.append(os.path.abspath("_spack_root/var/spack/repos/"))
# Add the Spack bin directory to the path so that we can use its output in docs.
os.environ["SPACK_ROOT"] = os.path.abspath("_spack_root")
@@ -75,11 +76,20 @@
apidoc_args
+ [
"_spack_root/lib/spack/spack",
"_spack_root/lib/spack/spack/package.py", # sphinx struggles with os.chdir re-export.
"_spack_root/lib/spack/spack/test/*.py",
"_spack_root/lib/spack/spack/test/cmd/*.py",
]
)
sphinx_apidoc(apidoc_args + ["_spack_root/lib/spack/llnl"])
sphinx_apidoc(
apidoc_args
+ [
"--implicit-namespaces",
"_spack_root/var/spack/repos/spack_repo",
"_spack_root/var/spack/repos/spack_repo/builtin/packages",
]
)
# Enable todo items
todo_include_todos = True
@@ -208,7 +218,7 @@ def setup(sphinx):
# Spack classes that are private and we don't want to expose
("py:class", "spack.provider_index._IndexBase"),
("py:class", "spack.repo._PrependFileLoader"),
("py:class", "spack.build_systems._checks.BuilderWithDefaults"),
("py:class", "spack_repo.builtin.build_systems._checks.BuilderWithDefaults"),
# Spack classes that intersphinx is unable to resolve
("py:class", "spack.version.StandardVersion"),
("py:class", "spack.spec.DependencySpec"),

View File

@@ -103,6 +103,7 @@ or refer to the full manual below.
:caption: API Docs
Spack API Docs <spack>
Spack Builtin Repo <spack_repo>
LLNL API Docs <llnl>
==================

View File

@@ -69,7 +69,7 @@ An example for ``CMake`` is, for instance:
The predefined steps for each build system are called "phases".
In general, the name and order in which the phases will be executed can be
obtained by either reading the API docs at :py:mod:`~.spack.build_systems`, or
obtained by either reading the API docs at :py:mod:`~.spack_repo.builtin.build_systems`, or
using the ``spack info`` command:
.. code-block:: console
@@ -158,7 +158,7 @@ builder class explicitly. Using the same example as above, this reads:
url_fmt = "https://github.com/uclouvain/openjpeg/archive/version.{0}.tar.gz"
return url_fmt.format(version)
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
class CMakeBuilder(spack_repo.builtin.build_systems.cmake.CMakeBuilder):
def cmake_args(self):
args = [
self.define_from_variant("BUILD_CODEC", "codec"),
@@ -256,7 +256,7 @@ for details):
#
# See the Spack documentation for more information on packaging.
# ----------------------------------------------------------------------------
import spack.build_systems.autotools
import spack_repo.builtin.build_systems.autotools
from spack.package import *
@@ -3697,60 +3697,60 @@ the build system. The build systems currently supported by Spack are:
+----------------------------------------------------------+----------------------------------+
| **API docs** | **Description** |
+==========================================================+==================================+
| :class:`~spack.build_systems.generic` | Generic build system without any |
| :class:`~spack_repo.builtin.build_systems.generic` | Generic build system without any |
| | base implementation |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.makefile` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.makefile` | Specialized build system for |
| | software built invoking |
| | hand-written Makefiles |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.autotools` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.autotools` | Specialized build system for |
| | software built using |
| | GNU Autotools |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.cmake` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.cmake` | Specialized build system for |
| | software built using CMake |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.maven` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.maven` | Specialized build system for |
| | software built using Maven |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.meson` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.meson` | Specialized build system for |
| | software built using Meson |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.nmake` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.nmake` | Specialized build system for |
| | software built using NMake |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.qmake` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.qmake` | Specialized build system for |
| | software built using QMake |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.scons` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.scons` | Specialized build system for |
| | software built using SCons |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.waf` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.waf` | Specialized build system for |
| | software built using Waf |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.r` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.r` | Specialized build system for |
| | R extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.octave` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.octave` | Specialized build system for |
| | Octave packages |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.python` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.python` | Specialized build system for |
| | Python extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.perl` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.perl` | Specialized build system for |
| | Perl extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.ruby` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.ruby` | Specialized build system for |
| | Ruby extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.intel` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.intel` | Specialized build system for |
| | licensed Intel software |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.oneapi` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.oneapi` | Specialized build system for |
| | Intel oneAPI software |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.aspell_dict` | Specialized build system for |
| :class:`~spack_repo.builtin.build_systems.aspell_dict` | Specialized build system for |
| | Aspell dictionaries |
+----------------------------------------------------------+----------------------------------+
@@ -3762,7 +3762,7 @@ the build system. The build systems currently supported by Spack are:
rare cases where manual intervention is needed we need to stress that a
package base class depends on the *build system* being used, not the language of the package.
For example, a Python extension installed with CMake would ``extends("python")`` and
subclass from :class:`~spack.build_systems.cmake.CMakePackage`.
subclass from :class:`~spack_repo.builtin.build_systems.cmake.CMakePackage`.
^^^^^^^^^^^^^^^^^^^^^^^^^^
Overriding builder methods
@@ -3770,7 +3770,7 @@ Overriding builder methods
Build-system "phases" have default implementations that fit most of the common cases:
.. literalinclude:: _spack_root/lib/spack/spack/build_systems/autotools.py
.. literalinclude:: _spack_root/var/spack/repos/spack_repo/builtin/build_systems/autotools.py
:pyobject: AutotoolsBuilder.configure
:linenos:
@@ -3784,7 +3784,7 @@ configure arguments:
Each specific build system has a list of attributes and methods that can be overridden to
fine-tune the installation of a package without overriding an entire phase. To
have more information on them the place to go is the API docs of the :py:mod:`~.spack.build_systems`
have more information on them the place to go is the API docs of the :py:mod:`~.spack_repo.builtin.build_systems`
module.
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -3826,7 +3826,7 @@ If the ``package.py`` has build instructions in a separate
.. code-block:: python
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
class CMakeBuilder(spack_repo.builtin.build_systems.cmake.CMakeBuilder):
def install(self, pkg, spec, prefix):
...
@@ -3839,31 +3839,32 @@ Mixin base classes
Besides build systems, there are other cases where common metadata and behavior can be extracted
and reused by many packages. For instance, packages that depend on ``Cuda`` or ``Rocm``, share
common dependencies and constraints. To factor these attributes into a single place, Spack provides
a few mixin classes in the ``spack.build_systems`` module:
a few mixin classes in the ``spack_repo.builtin.build_systems`` module:
+---------------------------------------------------------------+----------------------------------+
| **API docs** | **Description** |
+===============================================================+==================================+
| :class:`~spack.build_systems.cuda.CudaPackage` | A helper class for packages that |
| | use CUDA |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.rocm.ROCmPackage` | A helper class for packages that |
| | use ROCm |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.gnu.GNUMirrorPackage` | A helper class for GNU packages |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.python.PythonExtension` | A helper class for Python |
| | extensions |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.sourceforge.SourceforgePackage` | A helper class for packages |
| | from sourceforge.org |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.sourceware.SourcewarePackage` | A helper class for packages |
| | from sourceware.org |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.xorg.XorgPackage` | A helper class for x.org |
| | packages |
+---------------------------------------------------------------+----------------------------------+
+----------------------------------------------------------------------------+----------------------------------+
| **API docs** | **Description** |
+============================================================================+==================================+
| :class:`~spack_repo.builtin.build_systems.cuda.CudaPackage` | A helper class for packages that |
| | use CUDA |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.rocm.ROCmPackage` | A helper class for packages that |
| | use ROCm |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.gnu.GNUMirrorPackage` | A helper class for GNU packages |
| | |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.python.PythonExtension` | A helper class for Python |
| | extensions |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.sourceforge.SourceforgePackage` | A helper class for packages |
| | from sourceforge.org |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.sourceware.SourcewarePackage` | A helper class for packages |
| | from sourceware.org |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.xorg.XorgPackage` | A helper class for x.org |
| | packages |
+----------------------------------------------------------------------------+----------------------------------+
These classes should be used by adding them to the inheritance tree of the package that needs them,
for instance:
@@ -3907,13 +3908,13 @@ Additional build instructions are split into separate builder classes:
.. code-block:: python
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
class CMakeBuilder(spack_repo.builtin.build_systems.cmake.CMakeBuilder):
def cmake_args(self):
return [
self.define_from_variant("MY_FEATURE", "my_feature")
]
class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder):
class AutotoolsBuilder(spack_repo.builtin.build_systems.autotools.AutotoolsBuilder):
def configure_args(self):
return self.with_or_without("my-feature", variant="my_feature")

View File

@@ -67,7 +67,7 @@ def index_by(objects, *funcs):
}
If any elements in funcs is a string, it is treated as the name
of an attribute, and acts like getattr(object, name). So
of an attribute, and acts like ``getattr(object, name)``. So
shorthand for the above two indexes would be::
index1 = index_by(list_of_specs, 'arch', 'compiler')
@@ -77,7 +77,8 @@ def index_by(objects, *funcs):
index1 = index_by(list_of_specs, ('target', 'compiler'))
Keys in the resulting dict will look like ('gcc', 'skylake').
Keys in the resulting dict will look like ``('gcc', 'skylake')``.
"""
if not funcs:
return objects
@@ -315,7 +316,9 @@ def lazy_lexicographic_ordering(cls, set_hash=True):
This is a lazy version of the tuple comparison used frequently to
implement comparison in Python. Given some objects with fields, you
might use tuple keys to implement comparison, e.g.::
might use tuple keys to implement comparison, e.g.:
.. code-block:: python
class Widget:
def _cmp_key(self):
@@ -343,7 +346,9 @@ def __lt__(self):
Lazy lexicographic comparison maps the tuple comparison shown above
to generator functions. Instead of comparing based on pre-constructed
tuple keys, users of this decorator can compare using elements from a
generator. So, you'd write::
generator. So, you'd write:
.. code-block:: python
@lazy_lexicographic_ordering
class Widget:
@@ -366,6 +371,38 @@ def cd_fun():
only has to worry about writing ``_cmp_iter``, and making sure the
elements in it are also comparable.
In some cases, you may have a fast way to determine whether two
objects are equal, e.g. the ``is`` function or an already-computed
cryptographic hash. For this, you can implement your own
``_cmp_fast_eq`` function:
.. code-block:: python
@lazy_lexicographic_ordering
class Widget:
def _cmp_iter(self):
yield a
yield b
def cd_fun():
yield c
yield d
yield cd_fun
yield e
def _cmp_fast_eq(self, other):
return self is other or None
``_cmp_fast_eq`` should return:
* ``True`` if ``self`` is equal to ``other``,
* ``False`` if ``self`` is not equal to ``other``, and
* ``None`` if it's not known whether they are equal, and the full
comparison should be done.
``lazy_lexicographic_ordering`` uses ``_cmp_fast_eq`` to short-circuit
the comparison if the answer can be determined quickly. If you do not
implement it, it defaults to ``self is other or None``.
Some things to note:
* If a class already has ``__eq__``, ``__ne__``, ``__lt__``,
@@ -386,34 +423,40 @@ def cd_fun():
if not hasattr(cls, "_cmp_iter"):
raise TypeError(f"'{cls.__name__}' doesn't define _cmp_iter().")
# get an equal operation that allows us to short-circuit comparison
# if it's not provided, default to `is`
_cmp_fast_eq = getattr(cls, "_cmp_fast_eq", lambda x, y: x is y or None)
# comparison operators are implemented in terms of lazy_eq and lazy_lt
def eq(self, other):
if self is other:
return True
fast_eq = _cmp_fast_eq(self, other)
if fast_eq is not None:
return fast_eq
return (other is not None) and lazy_eq(self._cmp_iter, other._cmp_iter)
def lt(self, other):
if self is other:
if _cmp_fast_eq(self, other) is True:
return False
return (other is not None) and lazy_lt(self._cmp_iter, other._cmp_iter)
def ne(self, other):
if self is other:
return False
fast_eq = _cmp_fast_eq(self, other)
if fast_eq is not None:
return not fast_eq
return (other is None) or not lazy_eq(self._cmp_iter, other._cmp_iter)
def gt(self, other):
if self is other:
if _cmp_fast_eq(self, other) is True:
return False
return (other is None) or lazy_lt(other._cmp_iter, self._cmp_iter)
def le(self, other):
if self is other:
if _cmp_fast_eq(self, other) is True:
return True
return (other is not None) and not lazy_lt(other._cmp_iter, self._cmp_iter)
def ge(self, other):
if self is other:
if _cmp_fast_eq(self, other) is True:
return True
return (other is None) or not lazy_lt(self._cmp_iter, other._cmp_iter)

View File

@@ -52,6 +52,7 @@
# See the Spack documentation for more information on packaging.
# ----------------------------------------------------------------------------
{package_class_import}
from spack.package import *
@@ -85,6 +86,7 @@ class BundlePackageTemplate:
"""
base_class_name = "BundlePackage"
package_class_import = "from spack_repo.builtin.build_systems.bundle import BundlePackage"
dependencies = """\
# FIXME: Add dependencies if required.
@@ -114,6 +116,7 @@ def write(self, pkg_path):
name=self.name,
class_name=self.class_name,
base_class_name=self.base_class_name,
package_class_import=self.package_class_import,
url_def=self.url_def,
versions=self.versions,
dependencies="\n".join(all_deps),
@@ -126,6 +129,7 @@ class PackageTemplate(BundlePackageTemplate):
"""Provides the default values to be used for the package file template"""
base_class_name = "Package"
package_class_import = "from spack_repo.builtin.build_systems.generic import Package"
body_def = """\
def install(self, spec, prefix):
@@ -146,6 +150,9 @@ class AutotoolsPackageTemplate(PackageTemplate):
that *do* come with a ``configure`` script"""
base_class_name = "AutotoolsPackage"
package_class_import = (
"from spack_repo.builtin.build_systems.autotools import AutotoolsPackage"
)
body_def = """\
def configure_args(self):
@@ -160,6 +167,9 @@ class AutoreconfPackageTemplate(PackageTemplate):
that *do not* come with a ``configure`` script"""
base_class_name = "AutotoolsPackage"
package_class_import = (
"from spack_repo.builtin.build_systems.autotools import AutotoolsPackage"
)
dependencies = """\
depends_on("autoconf", type="build")
@@ -186,6 +196,7 @@ class CargoPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for cargo-based packages"""
base_class_name = "CargoPackage"
package_class_import = "from spack_repo.builtin.build_systems.cargo import CargoPackage"
body_def = ""
@@ -194,6 +205,7 @@ class CMakePackageTemplate(PackageTemplate):
"""Provides appropriate overrides for CMake-based packages"""
base_class_name = "CMakePackage"
package_class_import = "from spack_repo.builtin.build_systems.cmake import CMakePackage"
body_def = """\
def cmake_args(self):
@@ -208,6 +220,7 @@ class GoPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for Go-module-based packages"""
base_class_name = "GoPackage"
package_class_import = "from spack_repo.builtin.build_systems.go import GoPackage"
body_def = ""
@@ -216,6 +229,7 @@ class LuaPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for LuaRocks-based packages"""
base_class_name = "LuaPackage"
package_class_import = "from spack_repo.builtin.build_systems.lua import LuaPackage"
body_def = """\
def luarocks_args(self):
@@ -237,6 +251,7 @@ class MesonPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for meson-based packages"""
base_class_name = "MesonPackage"
package_class_import = "from spack_repo.builtin.build_systems.meson import MesonPackage"
body_def = """\
def meson_args(self):
@@ -249,6 +264,7 @@ class QMakePackageTemplate(PackageTemplate):
"""Provides appropriate overrides for QMake-based packages"""
base_class_name = "QMakePackage"
package_class_import = "from spack_repo.builtin.build_systems.qmake import QMakePackage"
body_def = """\
def qmake_args(self):
@@ -261,6 +277,7 @@ class MavenPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for Maven-based packages"""
base_class_name = "MavenPackage"
package_class_import = "from spack_repo.builtin.build_systems.maven import MavenPackage"
body_def = """\
def build(self, spec, prefix):
@@ -272,6 +289,7 @@ class SconsPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for SCons-based packages"""
base_class_name = "SConsPackage"
package_class_import = "from spack_repo.builtin.build_systems.scons import SConsPackage"
body_def = """\
def build_args(self, spec, prefix):
@@ -285,6 +303,7 @@ class WafPackageTemplate(PackageTemplate):
"""Provides appropriate override for Waf-based packages"""
base_class_name = "WafPackage"
package_class_import = "from spack_repo.builtin.build_systems.waf import WafPackage"
body_def = """\
# FIXME: Override configure_args(), build_args(),
@@ -308,6 +327,7 @@ class RacketPackageTemplate(PackageTemplate):
"""Provides approriate overrides for Racket extensions"""
base_class_name = "RacketPackage"
package_class_import = "from spack_repo.builtin.build_systems.racket import RacketPackage"
url_line = """\
# FIXME: set the proper location from which to fetch your package
@@ -345,6 +365,7 @@ class PythonPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for python extensions"""
base_class_name = "PythonPackage"
package_class_import = "from spack_repo.builtin.build_systems.python import PythonPackage"
dependencies = """\
# FIXME: Only add the python/pip/wheel dependencies if you need specific versions
@@ -432,6 +453,7 @@ class RPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for R extensions"""
base_class_name = "RPackage"
package_class_import = "from spack_repo.builtin.build_systems.r import RPackage"
dependencies = """\
# FIXME: Add dependencies if required.
@@ -472,6 +494,7 @@ class PerlmakePackageTemplate(PackageTemplate):
that come with a Makefile.PL"""
base_class_name = "PerlPackage"
package_class_import = "from spack_repo.builtin.build_systems.perl import PerlPackage"
dependencies = """\
# FIXME: Add dependencies if required:
@@ -509,6 +532,7 @@ class OctavePackageTemplate(PackageTemplate):
"""Provides appropriate overrides for octave packages"""
base_class_name = "OctavePackage"
package_class_import = "from spack_repo.builtin.build_systems.octave import OctavePackage"
dependencies = """\
extends("octave")
@@ -531,6 +555,7 @@ class RubyPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for Ruby packages"""
base_class_name = "RubyPackage"
package_class_import = "from spack_repo.builtin.build_systems.ruby import RubyPackage"
dependencies = """\
# FIXME: Add dependencies if required. Only add the ruby dependency
@@ -559,6 +584,7 @@ class MakefilePackageTemplate(PackageTemplate):
"""Provides appropriate overrides for Makefile packages"""
base_class_name = "MakefilePackage"
package_class_import = "from spack_repo.builtin.build_systems.makefile import MakefilePackage"
body_def = """\
def edit(self, spec, prefix):
@@ -573,6 +599,7 @@ class IntelPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for licensed Intel software"""
base_class_name = "IntelOneApiPackage"
package_class_import = "from spack_repo.builtin.build_systems.oneapi import IntelOneApiPackage"
body_def = """\
# FIXME: Override `setup_environment` if necessary."""
@@ -582,6 +609,7 @@ class SIPPackageTemplate(PackageTemplate):
"""Provides appropriate overrides for SIP packages."""
base_class_name = "SIPPackage"
package_class_import = "from spack_repo.builtin.build_systems.sip import SIPPackage"
body_def = """\
def configure_args(self, spec, prefix):

View File

@@ -28,7 +28,7 @@ def setup_parser(subparser):
"--build-system",
dest="path",
action="store_const",
const=spack.paths.build_systems_path,
const=os.path.join(spack.repo.PATH.repos[0].root, "build_systems"),
help="edit the build system with the supplied name",
)
excl_args.add_argument(

View File

@@ -183,7 +183,7 @@ def pkg_grep(args, unknown_args):
grep.add_default_arg("--color=auto")
# determines number of files to grep at a time
grouper = lambda e: e[0] // 500
grouper = lambda e: e[0] // 100
# set up iterator and save the first group to ensure we don't end up with a group of size 1
groups = itertools.groupby(enumerate(spack.repo.PATH.all_package_paths()), grouper)

View File

@@ -332,18 +332,8 @@ def process_files(file_list, is_args):
rewrite_and_print_output(output, args, pat, replacement)
packages_isort_args = (
"--rm",
"spack.pkgkit",
"--rm",
"spack.package_defs",
"-a",
"from spack.package import *",
)
packages_isort_args = packages_isort_args + isort_args
# packages
process_files(filter(is_package, file_list), packages_isort_args)
process_files(filter(is_package, file_list), isort_args)
# non-packages
process_files(filter(lambda f: not is_package(f), file_list), isort_args)

View File

@@ -5,6 +5,7 @@
import collections.abc
import contextlib
import errno
import glob
import os
import pathlib
import re
@@ -2424,19 +2425,11 @@ def display_specs(specs):
def make_repo_path(root):
"""Make a RepoPath from the repo subdirectories in an environment."""
path = spack.repo.RepoPath(cache=spack.caches.MISC_CACHE)
if os.path.isdir(root):
for repo_root in os.listdir(root):
repo_root = os.path.join(root, repo_root)
if not os.path.isdir(repo_root):
continue
repo = spack.repo.from_path(repo_root)
path.put_last(repo)
return path
repos = [
spack.repo.from_path(os.path.dirname(p))
for p in glob.glob(os.path.join(root, "**", "repo.yaml"), recursive=True)
]
return spack.repo.RepoPath(*repos, cache=spack.caches.MISC_CACHE)
def manifest_file(env_name_or_dir):

View File

@@ -2,7 +2,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
# flake8: noqa: F401, E402
"""spack.package defines the public API for Spack packages, by re-exporting useful symbols from
other modules. Packages should import this module, instead of importing from spack.* directly
to ensure forward compatibility with future versions of Spack."""
@@ -13,17 +12,6 @@
# import most common types used in packages
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 (
FileFilter,
FileList,
@@ -61,51 +49,6 @@ class tty:
from llnl.util.symlink import symlink
from spack.build_environment import MakeExecutable
from spack.build_systems.aspell_dict import AspellDictPackage
from spack.build_systems.autotools import AutotoolsPackage
from spack.build_systems.bundle import BundlePackage
from spack.build_systems.cached_cmake import (
CachedCMakePackage,
cmake_cache_filepath,
cmake_cache_option,
cmake_cache_path,
cmake_cache_string,
)
from spack.build_systems.cargo import CargoPackage
from spack.build_systems.cmake import CMakePackage, generator
from spack.build_systems.compiler import CompilerPackage
from spack.build_systems.cuda import CudaPackage
from spack.build_systems.generic import Package
from spack.build_systems.gnu import GNUMirrorPackage
from spack.build_systems.go import GoPackage
from spack.build_systems.intel import IntelPackage
from spack.build_systems.lua import LuaPackage
from spack.build_systems.makefile import MakefilePackage
from spack.build_systems.maven import MavenPackage
from spack.build_systems.meson import MesonPackage
from spack.build_systems.msbuild import MSBuildPackage
from spack.build_systems.nmake import NMakePackage
from spack.build_systems.octave import OctavePackage
from spack.build_systems.oneapi import (
INTEL_MATH_LIBRARIES,
IntelOneApiLibraryPackage,
IntelOneApiLibraryPackageWithSdk,
IntelOneApiPackage,
IntelOneApiStaticLibraryList,
)
from spack.build_systems.perl import PerlPackage
from spack.build_systems.python import PythonExtension, PythonPackage
from spack.build_systems.qmake import QMakePackage
from spack.build_systems.r import RPackage
from spack.build_systems.racket import RacketPackage
from spack.build_systems.rocm import ROCmPackage
from spack.build_systems.ruby import RubyPackage
from spack.build_systems.scons import SConsPackage
from spack.build_systems.sip import SIPPackage
from spack.build_systems.sourceforge import SourceforgePackage
from spack.build_systems.sourceware import SourcewarePackage
from spack.build_systems.waf import WafPackage
from spack.build_systems.xorg import XorgPackage
from spack.builder import BaseBuilder
from spack.config import determine_number_of_jobs
from spack.deptypes import ALL_TYPES as all_deptypes
@@ -158,6 +101,123 @@ class tty:
cd = chdir
pwd = getcwd
class tty:
import llnl.util.tty as _tty
debug = _tty.debug
error = _tty.error
info = _tty.info
msg = _tty.msg
warn = _tty.warn
__all__ = [
"chdir",
"environ",
"getcwd",
"makedirs",
"mkdir",
"remove",
"removedirs",
"move",
"rmtree",
"Dict",
"List",
"Optional",
"FileFilter",
"FileList",
"HeaderList",
"LibraryList",
"ancestor",
"can_access",
"change_sed_delimiter",
"copy",
"copy_tree",
"filter_file",
"find",
"find_all_headers",
"find_first",
"find_headers",
"find_libraries",
"find_system_libraries",
"force_remove",
"force_symlink",
"install",
"install_tree",
"is_exe",
"join_path",
"keep_modification_time",
"library_extensions",
"mkdirp",
"remove_directory_contents",
"remove_linked_tree",
"rename",
"set_executable",
"set_install_permissions",
"touch",
"working_dir",
"symlink",
"MakeExecutable",
"BaseBuilder",
"determine_number_of_jobs",
"all_deptypes",
"build_system",
"can_splice",
"conditional",
"conflicts",
"depends_on",
"extends",
"license",
"maintainers",
"patch",
"provides",
"redistribute",
"requires",
"resource",
"variant",
"version",
"InstallError",
"NoHeadersError",
"NoLibrariesError",
"SkipTest",
"cache_extra_test_sources",
"check_outputs",
"find_required_file",
"get_escaped_text_output",
"install_test_root",
"test_part",
"filter_compiler_wrappers",
"default_args",
"when",
"build_system_flags",
"env_flags",
"inject_flags",
"on_package_attributes",
"bash_completion_path",
"fish_completion_path",
"zsh_completion_path",
"run_after",
"run_before",
"Spec",
"EnvironmentModifications",
"Executable",
"ProcessError",
"which",
"which_string",
"fix_darwin_install_name",
"Prefix",
"any_combination_of",
"auto_or_any_combination_of",
"disjoint_sets",
"Version",
"ver",
"env",
"cd",
"pwd",
"tty",
]
# These are just here for editor support; they may be set when the build env is set up.
configure: Executable
make_jobs: int

View File

@@ -583,7 +583,7 @@ class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta):
like ``homepage`` and, for a code-based package, ``url``, or functions
such as ``install()``.
There are many custom ``Package`` subclasses in the
``spack.build_systems`` package that make things even easier for
``spack_repo.builtin.build_systems`` package that make things even easier for
specific build systems.
"""

View File

@@ -58,7 +58,7 @@
repos_path = os.path.join(var_path, "repos")
test_repos_path = os.path.join(var_path, "test_repos")
packages_path = os.path.join(repos_path, "spack_repo", "builtin")
mock_packages_path = os.path.join(test_repos_path, "builtin.mock")
mock_packages_path = os.path.join(test_repos_path, "spack_repo", "builtin_mock")
#
# Writable things in $spack/var/spack

View File

@@ -85,7 +85,7 @@ def __init__(self, fullname: str, repo: "Repo", package_name: str) -> None:
self.package_name = package_name
path = repo.filename_for_package_name(package_name)
self.fullname = fullname
self.prepend = b"from spack.build_systems._package_api_v1 import *\n"
self.prepend = b"from spack_repo.builtin.build_systems._package_api_v1 import *\n"
super().__init__(self.fullname, path)
def path_stats(self, path):
@@ -173,7 +173,7 @@ def compute_loader(self, fullname: str):
def builtin_repo() -> "Repo":
"""Get the test repo if it is active, otherwise the builtin repo."""
try:
return PATH.get_repo("builtin.mock")
return PATH.get_repo("builtin_mock")
except UnknownNamespaceError:
return PATH.get_repo("builtin")

View File

@@ -100,7 +100,11 @@ def migrate_v1_to_v2(
ino_to_relpath[entry.inode()] = entry.path[prefix_len:]
if entry.is_symlink():
symlink_to_ino[rel_path] = entry.stat(follow_symlinks=True).st_ino
try:
symlink_to_ino[rel_path] = entry.stat(follow_symlinks=True).st_ino
except OSError:
symlink_to_ino[rel_path] = -1 # dangling or no access
continue
elif entry.is_dir(follow_symlinks=False):
@@ -143,9 +147,13 @@ def migrate_v1_to_v2(
os.makedirs(new_root, exist_ok=True)
def _relocate(rel_path: str) -> Tuple[str, str]:
return os.path.join(repo.root, rel_path), os.path.join(
new_root, rename_regex.sub(lambda m: rename[m.group(0)], rel_path)
)
old = os.path.join(repo.root, rel_path)
if rename:
new_rel = rename_regex.sub(lambda m: rename[m.group(0)], rel_path)
else:
new_rel = rel_path
new = os.path.join(new_root, new_rel)
return old, new
if not fix:
print("The following directories, files and symlinks will be created:\n", file=out)

View File

@@ -961,7 +961,6 @@ def _sort_by_dep_types(dspec: DependencySpec):
return dspec.depflag
@lang.lazy_lexicographic_ordering
class _EdgeMap(collections.abc.Mapping):
"""Represent a collection of edges (DependencySpec objects) in the DAG.
@@ -999,21 +998,6 @@ def add(self, edge: DependencySpec) -> None:
def __str__(self) -> str:
return f"{{deps: {', '.join(str(d) for d in sorted(self.values()))}}}"
def _cmp_iter(self):
for item in sorted(itertools.chain.from_iterable(self.edges.values())):
yield item
def copy(self):
"""Copies this object and returns a clone"""
clone = type(self)()
clone.store_by_child = self.store_by_child
# Copy everything from this dict into it.
for dspec in itertools.chain.from_iterable(self.values()):
clone.add(dspec.copy())
return clone
def select(
self,
*,
@@ -3785,26 +3769,152 @@ def eq_node(self, other):
"""Equality with another spec, not including dependencies."""
return (other is not None) and lang.lazy_eq(self._cmp_node, other._cmp_node)
def _cmp_iter(self):
"""Lazily yield components of self for comparison."""
for item in self._cmp_node():
yield item
def _cmp_fast_eq(self, other) -> Optional[bool]:
"""Short-circuit compare with other for equality, for lazy_lexicographic_ordering."""
# If there is ever a breaking change to hash computation, whether accidental or purposeful,
# two specs can be identical modulo DAG hash, depending on what time they were concretized
# From the perspective of many operation in Spack (database, build cache, etc) a different
# DAG hash means a different spec. Here we ensure that two otherwise identical specs, one
# serialized before the hash change and one after, are considered different.
yield self.dag_hash() if self.concrete else None
if self is other:
return True
def deps():
for dep in sorted(itertools.chain.from_iterable(self._dependencies.values())):
yield dep.spec.name
yield dep.depflag
yield hash(dep.spec)
if self.concrete and other and other.concrete:
return self.dag_hash() == other.dag_hash()
yield deps
return None
def _cmp_iter(self):
"""Lazily yield components of self for comparison."""
# Spec comparison in Spack needs to be fast, so there are several cases here for
# performance. The main places we care about this are:
#
# * Abstract specs: there are lots of abstract specs in package.py files,
# which are put into metadata dictionaries and sorted during concretization
# setup. We want comparing abstract specs to be fast.
#
# * Concrete specs: concrete specs are bigger and have lots of nodes and
# edges. Because of the graph complexity, we need a full, linear time
# traversal to compare them -- that's pretty much is unavoidable. But they
# also have precoputed cryptographic hashes (dag_hash()), which we can use
# to do fast equality comparison. See _cmp_fast_eq() above for the
# short-circuit logic for hashes.
#
# A full traversal involves constructing data structurs, visitor objects, etc.,
# and it can be expensive if we have to do it to compare a bunch of tiny
# abstract specs. Therefore, there are 3 cases below, which avoid calling
# `spack.traverse.traverse_edges()` unless necessary.
#
# WARNING: the cases below need to be consistent, so don't mess with this code
# unless you really know what you're doing. Be sure to keep all three consistent.
#
# All cases lazily yield:
#
# 1. A generator over nodes
# 2. A generator over canonical edges
#
# Canonical edges have consistent ids defined by breadth-first traversal order. That is,
# the root is always 0, dependencies of the root are 1, 2, 3, etc., and so on.
#
# The three cases are:
#
# 1. Spec has no dependencies
# * We can avoid any traversal logic and just yield this node's _cmp_node generator.
#
# 2. Spec has dependencies, but dependencies have no dependencies.
# * We need to sort edges, but we don't need to track visited nodes, which
# can save us the cost of setting up all the tracking data structures
# `spack.traverse` uses.
#
# 3. Spec has dependencies that have dependencies.
# * In this case, the spec is *probably* concrete. Equality comparisons
# will be short-circuited by dag_hash(), but other comparisons will need
# to lazily enumerate components of the spec. The traversal logic is
# unavoidable.
#
# TODO: consider reworking `spack.traverse` to construct fewer data structures
# and objects, as this would make all traversals faster and could eliminate the
# need for the complexity here. It was not clear at the time of writing that how
# much optimization was possible in `spack.traverse`.
sorted_l1_edges = None
edge_list = None
node_ids = None
def nodes():
nonlocal sorted_l1_edges
nonlocal edge_list
nonlocal node_ids
# Level 0: root node
yield self._cmp_node # always yield the root (this node)
if not self._dependencies: # done if there are no dependencies
return
# Level 1: direct dependencies
# we can yield these in sorted order without tracking visited nodes
deps_have_deps = False
sorted_l1_edges = self.edges_to_dependencies(depflag=dt.ALL)
if len(sorted_l1_edges) > 1:
sorted_l1_edges = spack.traverse.sort_edges(sorted_l1_edges)
for edge in sorted_l1_edges:
yield edge.spec._cmp_node
if edge.spec._dependencies:
deps_have_deps = True
if not deps_have_deps: # done if level 1 specs have no dependencies
return
# Level 2: dependencies of direct dependencies
# now it's general; we need full traverse() to track visited nodes
l1_specs = [edge.spec for edge in sorted_l1_edges]
# the node_ids dict generates consistent ids based on BFS traversal order
# these are used to identify edges later
node_ids = collections.defaultdict(lambda: len(node_ids))
node_ids[id(self)] # self is 0
for spec in l1_specs:
node_ids[id(spec)] # l1 starts at 1
edge_list = []
for edge in spack.traverse.traverse_edges(
l1_specs, order="breadth", cover="edges", root=False, visited=set([0])
):
# yield each node only once, and generate a consistent id for it the
# first time it's encountered.
if id(edge.spec) not in node_ids:
yield edge.spec._cmp_node
node_ids[id(edge.spec)]
if edge.parent is None: # skip fake edge to root
continue
edge_list.append(
(
node_ids[id(edge.parent)],
node_ids[id(edge.spec)],
edge.depflag,
edge.virtuals,
)
)
def edges():
# no edges in single-node graph
if not self._dependencies:
return
# level 1 edges all start with zero
for i, edge in enumerate(sorted_l1_edges, start=1):
yield (0, i, edge.depflag, edge.virtuals)
# yield remaining edges in the order they were encountered during traversal
if edge_list:
yield from edge_list
yield nodes
yield edges
@property
def namespace_if_anonymous(self):

View File

@@ -12,8 +12,7 @@
import llnl.util.filesystem as fs
import spack.build_systems.autotools
import spack.build_systems.cmake
import spack
import spack.builder
import spack.concretize
import spack.environment
@@ -28,6 +27,8 @@
DATA_PATH = os.path.join(spack.paths.test_path, "data")
pytestmark = pytest.mark.skip(reason="build_systems module is moved out of spack")
@pytest.fixture()
def concretize_and_setup(default_mock_concretization, monkeypatch):

View File

@@ -15,7 +15,7 @@
@pytest.fixture()
def builder_test_repository(config):
builder_test_path = os.path.join(spack.paths.test_repos_path, "builder.test")
builder_test_path = os.path.join(spack.paths.test_repos_path, "spack_repo", "builder_test")
with spack.repo.use_repositories(builder_test_path) as mock_repo:
yield mock_repo

View File

@@ -549,11 +549,10 @@ def test_url_buildcache_entry_v2_exists(
):
"""Test existence check for v2 buildcache entries"""
test_mirror_path = v2_buildcache_layout("unsigned")
mirror_url = f"file://{test_mirror_path}"
mirror_url = pathlib.Path(test_mirror_path).as_uri()
mirror("add", "v2mirror", mirror_url)
with capsys.disabled():
output = buildcache("list", "-a", "-l")
output = buildcache("list", "-a", "-l")
assert "Fetching an index from a v2 binary mirror layout" in output
assert "is deprecated" in output

View File

@@ -2,134 +2,39 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import pytest
import spack.cmd.diff
import spack.concretize
import spack.main
import spack.paths
import spack.repo
import spack.util.spack_json as sjson
from spack.test.conftest import create_test_repo
install_cmd = spack.main.SpackCommand("install")
diff_cmd = spack.main.SpackCommand("diff")
find_cmd = spack.main.SpackCommand("find")
_p1 = (
"p1",
"""\
from spack.package import *
class P1(Package):
version("1.0")
variant("p1var", default=True)
variant("usev1", default=True)
depends_on("p2")
depends_on("v1", when="+usev1")
""",
)
_p2 = (
"p2",
"""\
from spack.package import *
class P2(Package):
version("1.0")
variant("p2var", default=True)
depends_on("p3")
""",
)
_p3 = (
"p3",
"""\
from spack.package import *
class P3(Package):
version("1.0")
variant("p3var", default=True)
""",
)
_i1 = (
"i1",
"""\
from spack.package import *
class I1(Package):
version("1.0")
provides("v1")
variant("i1var", default=True)
depends_on("p3")
depends_on("p4")
""",
)
_i2 = (
"i2",
"""\
from spack.package import *
class I2(Package):
version("1.0")
provides("v1")
variant("i2var", default=True)
depends_on("p3")
depends_on("p4")
""",
)
_p4 = (
"p4",
"""\
from spack.package import *
class P4(Package):
version("1.0")
variant("p4var", default=True)
""",
)
# Note that the hash of p1 will differ depending on the variant chosen
# we probably always want to omit that from diffs
@pytest.fixture
def _create_test_repo(tmpdir, mutable_config):
"""
p1____
| \
p2 v1
| ____/ |
p3 p4
# p1____
# | \
# p2 v1
# | ____/ |
# p3 p4
i1 and i2 provide v1 (and both have the same dependencies)
# i1 and i2 provide v1 (and both have the same dependencies)
All packages have an associated variant
"""
yield create_test_repo(tmpdir, [_p1, _p2, _p3, _i1, _i2, _p4])
# All packages have an associated variant
@pytest.fixture
def test_repo(_create_test_repo, monkeypatch, mock_stage):
with spack.repo.use_repositories(_create_test_repo) as mock_repo_path:
yield mock_repo_path
def test_repo(config):
builder_test_path = os.path.join(spack.paths.test_repos_path, "spack_repo", "diff")
with spack.repo.use_repositories(builder_test_path) as mock_repo:
yield mock_repo
def test_diff_ignore(test_repo):

View File

@@ -6,7 +6,6 @@
import spack.repo
import spack.util.editor
from spack.build_systems import autotools, cmake
from spack.main import SpackCommand
edit = SpackCommand("edit")
@@ -29,13 +28,15 @@ def editor(*args: str, **kwargs):
assert called
def test_edit_files(monkeypatch):
def test_edit_files(monkeypatch, mock_packages):
"""Test spack edit --build-system autotools cmake"""
called = False
def editor(*args: str, **kwargs):
nonlocal called
called = True
from spack_repo.builtin_mock.build_systems import autotools, cmake # type: ignore
assert os.path.samefile(args[0], autotools.__file__)
assert os.path.samefile(args[1], cmake.__file__)

View File

@@ -886,12 +886,12 @@ def test_env_activate_broken_view(
with spack.repo.use_repositories(mock_custom_repository):
wrong_repo = env("activate", "--sh", "test")
assert "Warning: could not load runtime environment" in wrong_repo
assert "Unknown namespace: builtin.mock" in wrong_repo
assert "Unknown namespace: builtin_mock" in wrong_repo
# test replacing repo fixes it
normal_repo = env("activate", "--sh", "test")
assert "Warning: could not load runtime environment" not in normal_repo
assert "Unknown namespace: builtin.mock" not in normal_repo
assert "Unknown namespace: builtin_mock" not in normal_repo
def test_to_lockfile_dict():
@@ -916,7 +916,7 @@ def test_env_repo():
pkg_cls = e.repo.get_pkg_class("mpileaks")
assert pkg_cls.name == "mpileaks"
assert pkg_cls.namespace == "builtin.mock"
assert pkg_cls.namespace == "builtin_mock"
def test_user_removed_spec(environment_from_manifest):

View File

@@ -102,25 +102,25 @@ def _determine_version(cls, exe):
["detectable"],
[],
[
"builtin.mock.cmake",
"builtin.mock.find-externals1",
"builtin.mock.gcc",
"builtin.mock.intel-oneapi-compilers",
"builtin.mock.llvm",
"builtin.mock.mpich",
"builtin_mock.cmake",
"builtin_mock.find-externals1",
"builtin_mock.gcc",
"builtin_mock.intel-oneapi-compilers",
"builtin_mock.llvm",
"builtin_mock.mpich",
],
),
# find --all --exclude find-externals1
(
None,
["detectable"],
["builtin.mock.find-externals1"],
["builtin_mock.find-externals1"],
[
"builtin.mock.cmake",
"builtin.mock.gcc",
"builtin.mock.intel-oneapi-compilers",
"builtin.mock.llvm",
"builtin.mock.mpich",
"builtin_mock.cmake",
"builtin_mock.gcc",
"builtin_mock.intel-oneapi-compilers",
"builtin_mock.llvm",
"builtin_mock.mpich",
],
),
(
@@ -128,11 +128,11 @@ def _determine_version(cls, exe):
["detectable"],
["find-externals1"],
[
"builtin.mock.cmake",
"builtin.mock.gcc",
"builtin.mock.intel-oneapi-compilers",
"builtin.mock.llvm",
"builtin.mock.mpich",
"builtin_mock.cmake",
"builtin_mock.gcc",
"builtin_mock.intel-oneapi-compilers",
"builtin_mock.llvm",
"builtin_mock.mpich",
],
),
# find hwloc (and mock hwloc is not detectable)

View File

@@ -14,12 +14,12 @@
import spack.cmd.find
import spack.concretize
import spack.environment as ev
import spack.paths
import spack.repo
import spack.store
import spack.user_environment as uenv
from spack.enums import InstallRecordStatus
from spack.main import SpackCommand
from spack.test.conftest import create_test_repo
from spack.test.utilities import SpackCommandArgs
from spack.util.pattern import Bunch
@@ -129,7 +129,7 @@ def test_tag2_tag3(parser, specs):
@pytest.mark.db
def test_namespaces_shown_correctly(args, with_namespace, database):
"""Test that --namespace(s) works. Old syntax is --namespace"""
assert ("builtin.mock.zmpi" in find(*args)) == with_namespace
assert ("builtin_mock.zmpi" in find(*args)) == with_namespace
@pytest.mark.db
@@ -462,89 +462,16 @@ def test_environment_with_version_range_in_compiler_doesnt_fail(tmp_path, mock_p
assert "zlib" in output
_pkga = (
"a0",
"""\
from spack.package import *
class A0(Package):
version("1.2")
version("1.1")
depends_on("b0")
depends_on("c0")
""",
)
_pkgb = (
"b0",
"""\
from spack.package import *
class B0(Package):
version("1.2")
version("1.1")
""",
)
_pkgc = (
"c0",
"""\
from spack.package import *
class C0(Package):
version("1.2")
version("1.1")
tags = ["tag0", "tag1"]
""",
)
_pkgd = (
"d0",
"""\
from spack.package import *
class D0(Package):
version("1.2")
version("1.1")
depends_on("c0")
depends_on("e0")
""",
)
_pkge = (
"e0",
"""\
from spack.package import *
class E0(Package):
tags = ["tag1", "tag2"]
version("1.2")
version("1.1")
""",
)
# a0 d0
# / \ / \
# b0 c0 e0
@pytest.fixture
def _create_test_repo(tmpdir, mutable_config):
r"""
a0 d0
/ \ / \
b0 c0 e0
"""
yield create_test_repo(tmpdir, [_pkga, _pkgb, _pkgc, _pkgd, _pkge])
@pytest.fixture
def test_repo(_create_test_repo, monkeypatch, mock_stage):
with spack.repo.use_repositories(_create_test_repo) as mock_repo_path:
def test_repo(mock_stage):
with spack.repo.use_repositories(
os.path.join(spack.paths.test_repos_path, "spack_repo", "find")
) as mock_repo_path:
yield mock_repo_path

View File

@@ -143,13 +143,13 @@ def test_list_count():
def test_list_repos():
with spack.repo.use_repositories(
os.path.join(spack.paths.test_repos_path, "builtin.mock"),
os.path.join(spack.paths.test_repos_path, "builder.test"),
os.path.join(spack.paths.test_repos_path, "spack_repo", "builtin_mock"),
os.path.join(spack.paths.test_repos_path, "spack_repo", "builder_test"),
):
total_pkgs = len(list().strip().split())
mock_pkgs = len(list("-r", "builtin.mock").strip().split())
builder_pkgs = len(list("-r", "builder.test").strip().split())
both_repos = len(list("-r", "builtin.mock", "-r", "builder.test").strip().split())
mock_pkgs = len(list("-r", "builtin_mock").strip().split())
builder_pkgs = len(list("-r", "builder_test").strip().split())
both_repos = len(list("-r", "builtin_mock", "-r", "builder_test").strip().split())
assert total_pkgs > mock_pkgs > builder_pkgs
assert both_repos == total_pkgs

View File

@@ -39,7 +39,9 @@ def install(self, spec, prefix):
def mock_pkg_git_repo(git, tmp_path_factory):
"""Copy the builtin.mock repo and make a mutable git repo inside it."""
root_dir = tmp_path_factory.mktemp("mock_pkg_git_repo")
repo_dir = root_dir / "builtin.mock"
# create spack_repo subdir
(root_dir / "spack_repo").mkdir()
repo_dir = root_dir / "spack_repo" / "builtin_mock"
shutil.copytree(spack.paths.mock_packages_path, str(repo_dir))
repo_cache = spack.util.file_cache.FileCache(root_dir / "cache")
@@ -57,25 +59,25 @@ def mock_pkg_git_repo(git, tmp_path_factory):
git("-c", "commit.gpgsign=false", "commit", "-m", "initial mock repo commit")
# add commit with mockpkg-a, mockpkg-b, mockpkg-c packages
mkdirp("mockpkg-a", "mockpkg-b", "mockpkg-c")
with open("mockpkg-a/package.py", "w", encoding="utf-8") as f:
mkdirp("mockpkg_a", "mockpkg_b", "mockpkg_c")
with open("mockpkg_a/package.py", "w", encoding="utf-8") as f:
f.write(pkg_template.format(name="PkgA"))
with open("mockpkg-b/package.py", "w", encoding="utf-8") as f:
with open("mockpkg_b/package.py", "w", encoding="utf-8") as f:
f.write(pkg_template.format(name="PkgB"))
with open("mockpkg-c/package.py", "w", encoding="utf-8") as f:
with open("mockpkg_c/package.py", "w", encoding="utf-8") as f:
f.write(pkg_template.format(name="PkgC"))
git("add", "mockpkg-a", "mockpkg-b", "mockpkg-c")
git("add", "mockpkg_a", "mockpkg_b", "mockpkg_c")
git("-c", "commit.gpgsign=false", "commit", "-m", "add mockpkg-a, mockpkg-b, mockpkg-c")
# remove mockpkg-c, add mockpkg-d
with open("mockpkg-b/package.py", "a", encoding="utf-8") as f:
with open("mockpkg_b/package.py", "a", encoding="utf-8") as f:
f.write("\n# change mockpkg-b")
git("add", "mockpkg-b")
mkdirp("mockpkg-d")
with open("mockpkg-d/package.py", "w", encoding="utf-8") as f:
git("add", "mockpkg_b")
mkdirp("mockpkg_d")
with open("mockpkg_d/package.py", "w", encoding="utf-8") as f:
f.write(pkg_template.format(name="PkgD"))
git("add", "mockpkg-d")
git("rm", "-rf", "mockpkg-c")
git("add", "mockpkg_d")
git("rm", "-rf", "mockpkg_c")
git(
"-c",
"commit.gpgsign=false",
@@ -90,7 +92,7 @@ def mock_pkg_git_repo(git, tmp_path_factory):
@pytest.fixture(scope="module")
def mock_pkg_names():
repo = spack.repo.PATH.get_repo("builtin.mock")
repo = spack.repo.PATH.get_repo("builtin_mock")
# Be sure to include virtual packages since packages with stand-alone
# tests may inherit additional tests from the virtuals they provide,
@@ -117,22 +119,22 @@ def test_builtin_repo():
def test_mock_builtin_repo(mock_packages):
assert spack.repo.builtin_repo() is spack.repo.PATH.get_repo("builtin.mock")
assert spack.repo.builtin_repo() is spack.repo.PATH.get_repo("builtin_mock")
def test_pkg_add(git, mock_pkg_git_repo):
with working_dir(mock_pkg_git_repo):
mkdirp("mockpkg-e")
with open("mockpkg-e/package.py", "w", encoding="utf-8") as f:
mkdirp("mockpkg_e")
with open("mockpkg_e/package.py", "w", encoding="utf-8") as f:
f.write(pkg_template.format(name="PkgE"))
pkg("add", "mockpkg-e")
with working_dir(mock_pkg_git_repo):
try:
assert "A mockpkg-e/package.py" in git("status", "--short", output=str)
assert "A mockpkg_e/package.py" in git("status", "--short", output=str)
finally:
shutil.rmtree("mockpkg-e")
shutil.rmtree("mockpkg_e")
# Removing a package mid-run disrupts Spack's caching
if spack.repo.PATH.repos[0]._fast_package_checker:
spack.repo.PATH.repos[0]._fast_package_checker.invalidate()

View File

@@ -48,11 +48,13 @@ def test_resource_list(mock_packages, capfd):
assert "path:" in out
assert (
os.path.join("repos", "builtin.mock", "packages", "patch-a-dependency", "libelf.patch")
os.path.join(
"spack_repo", "builtin_mock", "packages", "patch_a_dependency", "libelf.patch"
)
in out
)
assert "applies to: builtin.mock.libelf" in out
assert "patched by: builtin.mock.patch-a-dependency" in out
assert "applies to: builtin_mock.libelf" in out
assert "patched by: builtin_mock.patch-a-dependency" in out
def test_resource_list_only_hashes(mock_packages, capfd):
@@ -74,10 +76,12 @@ def test_resource_show(mock_packages, capfd):
assert out.startswith(test_hash)
assert (
os.path.join("repos", "builtin.mock", "packages", "patch-a-dependency", "libelf.patch")
os.path.join(
"spack_repo", "builtin_mock", "packages", "patch_a_dependency", "libelf.patch"
)
in out
)
assert "applies to: builtin.mock.libelf" in out
assert "patched by: builtin.mock.patch-a-dependency" in out
assert "applies to: builtin_mock.libelf" in out
assert "patched by: builtin_mock.patch-a-dependency" in out
assert len(out.strip().split("\n")) == 4

View File

@@ -241,14 +241,14 @@ def test_external_root(external_style_root, capfd):
assert "%s Imports are incorrectly sorted" % str(py_file) in output
# mypy error
assert 'lib/spack/spack/dummy.py:9: error: Name "Package" is not defined' in output
assert 'lib/spack/spack/dummy.py:47: error: Name "version" is not defined' in output
# black error
assert "--- lib/spack/spack/dummy.py" in output
assert "+++ lib/spack/spack/dummy.py" in output
# flake8 error
assert "lib/spack/spack/dummy.py:6: [F401] 'os' imported but unused" in output
assert "lib/spack/spack/dummy.py:8: [F401] 'os' imported but unused" in output
@pytest.mark.skipif(not FLAKE8, reason="flake8 is not installed.")
@@ -311,8 +311,10 @@ def test_run_import_check(tmp_path: pathlib.Path):
import spack.repo
import spack.repo_utils
from spack_repo.builtin_mock.build_systems import autotools
# this comment about spack.error should not be removed
class Example(spack.build_systems.autotools.AutotoolsPackage):
class Example(autotools.AutotoolsPackage):
"""this is a docstring referencing unused spack.error.SpackError, which is fine"""
pass
@@ -339,7 +341,6 @@ def foo(config: "spack.error.SpackError"):
assert "issues.py: redundant import: spack.repo" in output
assert "issues.py: redundant import: spack.config" not in output # comment prevents removal
assert "issues.py: missing import: spack" in output # used by spack.__version__
assert "issues.py: missing import: spack.build_systems.autotools" in output
assert "issues.py: missing import: spack.util.executable" in output
assert "issues.py: missing import: spack.error" not in output # not directly used
assert exit_code == 1
@@ -359,7 +360,6 @@ def foo(config: "spack.error.SpackError"):
assert exit_code == 1
assert "issues.py: redundant import: spack.cmd" in output
assert "issues.py: missing import: spack" in output
assert "issues.py: missing import: spack.build_systems.autotools" in output
assert "issues.py: missing import: spack.util.executable" in output
# after fix a second fix is idempotent
@@ -380,7 +380,6 @@ def foo(config: "spack.error.SpackError"):
new_contents = file.read_text()
assert "import spack.cmd" not in new_contents
assert "import spack\n" in new_contents
assert "import spack.build_systems.autotools\n" in new_contents
assert "import spack.util.executable\n" in new_contents

View File

@@ -36,7 +36,7 @@ def test_remote_versions_only():
@pytest.mark.usefixtures("mock_packages")
def test_new_versions_only(monkeypatch):
"""Test a package for which new versions should be available."""
from spack.pkg.builtin.mock.brillig import Brillig # type: ignore[import]
from spack_repo.builtin_mock.packages.brillig.package import Brillig # type: ignore[import]
def mock_fetch_remote_versions(*args, **kwargs):
mock_remote_versions = {

View File

@@ -29,7 +29,7 @@ def _concretize_with_reuse(*, root_str, reused_str):
@pytest.fixture
def runtime_repo(mutable_config):
repo = os.path.join(spack.paths.test_repos_path, "compiler_runtime.test")
repo = os.path.join(spack.paths.test_repos_path, "spack_repo", "compiler_runtime_test")
with spack.repo.use_repositories(repo) as mock_repo:
yield mock_repo

View File

@@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import pathlib
import platform
import sys
@@ -79,7 +80,7 @@ def binary_compatibility(monkeypatch, request):
return
if "mock_packages" not in request.fixturenames:
# Only builtin.mock has a mock glibc package
# Only builtin_mock has a mock glibc package
return
if "database" in request.fixturenames or "mutable_database" in request.fixturenames:
@@ -170,18 +171,12 @@ def reverser(pkg_name):
@pytest.fixture()
def repo_with_changing_recipe(tmp_path_factory, mutable_mock_repo):
repo_namespace = "changing"
repo_dir = tmp_path_factory.mktemp(repo_namespace)
repos_dir: pathlib.Path = tmp_path_factory.mktemp("repos_dir")
root, _ = spack.repo.create_repo(str(repos_dir), "changing")
packages_dir = pathlib.Path(root, "packages")
(repo_dir / "repo.yaml").write_text(
"""
repo:
namespace: changing
"""
)
packages_dir = repo_dir / "packages"
root_pkg_str = """
from spack_repo.builtin_mock.build_systems.generic import Package
from spack.package import *
class Root(Package):
@@ -199,6 +194,7 @@ class Root(Package):
package_py.write_text(root_pkg_str)
middle_pkg_str = """
from spack_repo.builtin_mock.build_systems.generic import Package
from spack.package import *
class Middle(Package):
@@ -213,6 +209,7 @@ class Middle(Package):
package_py.write_text(middle_pkg_str)
changing_template = """
from spack_repo.builtin_mock.build_systems.generic import Package
from spack.package import *
class Changing(Package):
@@ -235,7 +232,7 @@ class Changing(Package):
{% endif %}
"""
with spack.repo.use_repositories(str(repo_dir), override=False) as repository:
with spack.repo.use_repositories(root, override=False) as repos:
class _ChangingPackage:
default_context = [
@@ -244,27 +241,22 @@ class _ChangingPackage:
("add_variant", False),
]
def __init__(self, repo_directory):
self.repo_dir = repo_directory
def __init__(self):
cache_dir = tmp_path_factory.mktemp("cache")
self.repo_cache = spack.util.file_cache.FileCache(str(cache_dir))
self.repo = spack.repo.Repo(str(repo_directory), cache=self.repo_cache)
self.repo = spack.repo.Repo(root, cache=self.repo_cache)
def change(self, changes=None):
changes = changes or {}
context = dict(self.default_context)
context.update(changes)
# Remove the repo object and delete Python modules
repository.remove(self.repo)
repos.remove(self.repo)
# TODO: this mocks a change in the recipe that should happen in a
# TODO: different process space. Leaving this comment as a hint
# TODO: in case tests using this fixture start failing.
if sys.modules.get("spack.pkg.changing.changing"):
del sys.modules["spack.pkg.changing.changing"]
if sys.modules.get("spack.pkg.changing.root"):
del sys.modules["spack.pkg.changing.root"]
if sys.modules.get("spack.pkg.changing"):
del sys.modules["spack.pkg.changing"]
for module in [x for x in sys.modules if x.startswith("spack_repo.changing")]:
del sys.modules[module]
# Change the recipe
t = _vendoring.jinja2.Template(changing_template)
@@ -274,10 +266,10 @@ def change(self, changes=None):
package_py.write_text(changing_pkg_str)
# Re-add the repository
self.repo = spack.repo.Repo(str(self.repo_dir), cache=self.repo_cache)
repository.put_first(self.repo)
self.repo = spack.repo.Repo(root, cache=self.repo_cache)
repos.put_first(self.repo)
_changing_pkg = _ChangingPackage(repo_dir)
_changing_pkg = _ChangingPackage()
_changing_pkg.change(
{"delete_version": False, "delete_variant": False, "add_variant": False}
)
@@ -374,11 +366,11 @@ def test_provides_handles_multiple_providers_of_same_version(self):
# Note that providers are repo-specific, so we don't misinterpret
# providers, but vdeps are not namespace-specific, so we can
# associate vdeps across repos.
assert Spec("builtin.mock.multi-provider-mpi@1.10.3") in providers
assert Spec("builtin.mock.multi-provider-mpi@1.10.2") in providers
assert Spec("builtin.mock.multi-provider-mpi@1.10.1") in providers
assert Spec("builtin.mock.multi-provider-mpi@1.10.0") in providers
assert Spec("builtin.mock.multi-provider-mpi@1.8.8") in providers
assert Spec("builtin_mock.multi-provider-mpi@1.10.3") in providers
assert Spec("builtin_mock.multi-provider-mpi@1.10.2") in providers
assert Spec("builtin_mock.multi-provider-mpi@1.10.1") in providers
assert Spec("builtin_mock.multi-provider-mpi@1.10.0") in providers
assert Spec("builtin_mock.multi-provider-mpi@1.8.8") in providers
def test_different_compilers_get_different_flags(
self, mutable_config, clang12_with_flags, gcc11_with_flags
@@ -1716,12 +1708,12 @@ def test_reuse_with_unknown_namespace_dont_raise(
):
with spack.repo.use_repositories(mock_custom_repository, override=False):
s = spack.concretize.concretize_one("pkg-c")
assert s.namespace != "builtin.mock"
assert s.namespace != "builtin_mock"
PackageInstaller([s.package], fake=True, explicit=True).install()
with spack.config.override("concretizer:reuse", True):
s = spack.concretize.concretize_one("pkg-c")
assert s.namespace == "builtin.mock"
assert s.namespace == "builtin_mock"
@pytest.mark.regression("45538")
def test_reuse_from_other_namespace_no_raise(self, tmpdir, temporary_store, monkeypatch):
@@ -1752,7 +1744,7 @@ def test_reuse_with_unknown_package_dont_raise(self, tmpdir, temporary_store, mo
repos.repos[0]._pkg_checker.invalidate()
with spack.config.override("concretizer:reuse", True):
s = spack.concretize.concretize_one("pkg-c")
assert s.namespace == "builtin.mock"
assert s.namespace == "builtin_mock"
@pytest.mark.parametrize(
"specs,checks",
@@ -2329,10 +2321,10 @@ def test_reuse_python_from_cli_and_extension_from_db(self, mutable_database):
"spec_str,expected_namespaces",
[
# Single node with fully qualified namespace
("builtin.mock.gmake", {"gmake": "builtin.mock"}),
("builtin_mock.gmake", {"gmake": "builtin_mock"}),
# Dependency with fully qualified namespace
("hdf5 ^builtin.mock.gmake", {"gmake": "builtin.mock", "hdf5": "duplicates.test"}),
("hdf5 ^gmake", {"gmake": "duplicates.test", "hdf5": "duplicates.test"}),
("hdf5 ^builtin_mock.gmake", {"gmake": "builtin_mock", "hdf5": "duplicates_test"}),
("hdf5 ^gmake", {"gmake": "duplicates_test", "hdf5": "duplicates_test"}),
],
)
def test_select_lower_priority_package_from_repository_stack(
@@ -2341,8 +2333,10 @@ def test_select_lower_priority_package_from_repository_stack(
"""Tests that a user can explicitly select a lower priority, fully qualified dependency
from cli.
"""
# 'builtin.mock" and "duplicates.test" share a 'gmake' package
additional_repo = os.path.join(spack.paths.test_repos_path, "duplicates.test")
# 'builtin_mock" and "duplicates_test" share a 'gmake' package
additional_repo = os.path.join(
spack.paths.test_repos_path, "spack_repo", "duplicates_test"
)
with spack.repo.use_repositories(additional_repo, override=False):
s = spack.concretize.concretize_one(spec_str)
@@ -2586,7 +2580,7 @@ def test_correct_external_is_selected_from_packages_yaml(self, mutable_config):
@pytest.fixture()
def duplicates_test_repository():
repository_path = os.path.join(spack.paths.test_repos_path, "duplicates.test")
repository_path = os.path.join(spack.paths.test_repos_path, "spack_repo", "duplicates_test")
with spack.repo.use_repositories(repository_path) as mock_repo:
yield mock_repo
@@ -2821,7 +2815,7 @@ def test_adding_specs(self, input_specs, default_mock_concretization):
@pytest.fixture()
def edges_test_repository():
repository_path = os.path.join(spack.paths.test_repos_path, "edges.test")
repository_path = os.path.join(spack.paths.test_repos_path, "spack_repo", "edges_test")
with spack.repo.use_repositories(repository_path) as mock_repo:
yield mock_repo

View File

@@ -46,7 +46,7 @@
@pytest.fixture
def test_repo(mutable_config, monkeypatch, mock_stage):
repo_dir = pathlib.Path(spack.paths.test_repos_path) / "flags.test"
repo_dir = pathlib.Path(spack.paths.test_repos_path) / "spack_repo" / "flags_test"
with spack.repo.use_repositories(str(repo_dir)) as mock_repo_path:
yield mock_repo_path

View File

@@ -28,7 +28,7 @@ def update_packages_config(conf_str):
@pytest.fixture
def test_repo(mutable_config, monkeypatch, mock_stage):
repo_dir = pathlib.Path(spack.paths.test_repos_path) / "requirements.test"
repo_dir = pathlib.Path(spack.paths.test_repos_path) / "spack_repo" / "requirements_test"
with spack.repo.use_repositories(str(repo_dir)) as mock_repo_path:
yield mock_repo_path
@@ -766,21 +766,21 @@ def test_skip_requirement_when_default_requirement_condition_cannot_be_met(
def test_requires_directive(mock_packages, config):
# This package requires either clang or gcc
s = spack.concretize.concretize_one("requires_clang_or_gcc")
s = spack.concretize.concretize_one("requires-clang-or-gcc")
assert s.satisfies("%gcc")
s = spack.concretize.concretize_one("requires_clang_or_gcc %gcc")
s = spack.concretize.concretize_one("requires-clang-or-gcc %gcc")
assert s.satisfies("%gcc")
s = spack.concretize.concretize_one("requires_clang_or_gcc %clang")
s = spack.concretize.concretize_one("requires-clang-or-gcc %clang")
# Test both the real package (llvm) and its alias (clang)
assert s.satisfies("%llvm") and s.satisfies("%clang")
# This package can only be compiled with clang
s = spack.concretize.concretize_one("requires_clang")
s = spack.concretize.concretize_one("requires-clang")
assert s.satisfies("%llvm")
s = spack.concretize.concretize_one("requires_clang %clang")
s = spack.concretize.concretize_one("requires-clang %clang")
assert s.satisfies("%llvm")
with pytest.raises(spack.error.SpackError, match="can only be compiled with Clang"):
spack.concretize.concretize_one("requires_clang %gcc")
spack.concretize.concretize_one("requires-clang %gcc")
@pytest.mark.parametrize(

View File

@@ -654,7 +654,7 @@ def mock_pkg_install(monkeypatch):
@pytest.fixture(scope="function")
def mock_packages(mock_repo_path, mock_pkg_install, request):
"""Use the 'builtin.mock' repository instead of 'builtin'"""
"""Use the 'builtin_mock' repository instead of 'builtin'"""
ensure_configuration_fixture_run_before(request)
with spack.repo.use_repositories(mock_repo_path) as mock_repo:
yield mock_repo
@@ -1434,7 +1434,7 @@ def mock_git_repository(git, tmpdir_factory):
of these refers to a repository with a single commit.
c0, c1, and c2 include information to define explicit versions in the
associated builtin.mock package 'git-test'. c3 is a commit in the
associated builtin_mock package 'git-test'. c3 is a commit in the
repository but does not have an associated explicit package version.
"""
suburls = []
@@ -2100,35 +2100,6 @@ def mock_modules_root(tmp_path, monkeypatch):
monkeypatch.setattr(spack.modules.common, "root_path", fn)
_repo_name_id = 0
def create_test_repo(tmpdir, pkg_name_content_tuples):
global _repo_name_id
repo_path = str(tmpdir)
repo_yaml = tmpdir.join("repo.yaml")
with open(str(repo_yaml), "w", encoding="utf-8") as f:
f.write(
f"""\
repo:
namespace: testrepo{str(_repo_name_id)}
"""
)
_repo_name_id += 1
packages_dir = tmpdir.join("packages")
for pkg_name, pkg_str in pkg_name_content_tuples:
pkg_dir = packages_dir.ensure(pkg_name, dir=True)
pkg_file = pkg_dir.join("package.py")
with open(str(pkg_file), "w", encoding="utf-8") as f:
f.write(pkg_str)
repo_cache = spack.util.file_cache.FileCache(str(tmpdir.join("cache")))
return spack.repo.Repo(repo_path, cache=repo_cache)
@pytest.fixture()
def compiler_factory():
"""Factory for a compiler dict, taking a spec and an OS as arguments."""

View File

@@ -2,10 +2,11 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.package_base import PackageBase
from spack.package import *
class DiffTest(AutotoolsPackage):
class DiffTest(PackageBase):
"""zlib replacement with optimizations for next generation systems."""
homepage = "https://github.com/zlib-ng/zlib-ng"

View File

@@ -2,10 +2,11 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.package_base import PackageBase
from spack.package import *
class DiffTest(AutotoolsPackage):
class DiffTest(PackageBase):
"""zlib replacement with optimizations for next generation systems."""
homepage = "https://github.com/zlib-ng/zlib-ng"

View File

@@ -2,10 +2,11 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.package_base import PackageBase
from spack.package import *
class DiffTest(AutotoolsPackage):
class DiffTest(PackageBase):
"""zlib replacement with optimizations for next generation systems."""
homepage = "https://github.com/zlib-ng/zlib-ng"

View File

@@ -26,7 +26,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -70,7 +70,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -114,7 +114,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -137,7 +137,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -160,7 +160,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -183,7 +183,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -215,7 +215,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -253,7 +253,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -276,7 +276,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -314,7 +314,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -337,7 +337,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -368,7 +368,7 @@
"name": "clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],

View File

@@ -57,7 +57,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -133,7 +133,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -209,7 +209,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -264,7 +264,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -319,7 +319,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -374,7 +374,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -438,7 +438,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -508,7 +508,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -563,7 +563,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -633,7 +633,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -688,7 +688,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -751,7 +751,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -806,7 +806,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -882,7 +882,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],

View File

@@ -58,7 +58,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -136,7 +136,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -214,7 +214,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -268,7 +268,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -322,7 +322,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -376,7 +376,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -440,7 +440,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -511,7 +511,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -565,7 +565,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -636,7 +636,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -690,7 +690,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -753,7 +753,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -807,7 +807,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],
@@ -885,7 +885,7 @@
"name": "apple-clang",
"version": "13.0.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],

View File

@@ -18,7 +18,7 @@ spec:
compiler:
name: gcc
version: 4.5.0
namespace: builtin.mock
namespace: builtin_mock
parameters:
optimize: true
pic: true

View File

@@ -1,29 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGf23+EBEAC6UqaiE43cF9jFuVjA8xJ5j31BMhufpnk0cwoE5Iks/GgR/Hki
LMYbzy36V7TZGObel+5DtFKipX+WCwWj2XsjbeqHeuCkxZhzHFwfi1UJl9FO2T28
iNn6OsBiGeU6ULNmehSia2hx0uhj1re/FUwJExOAvuYv8nc7M+nozqi7Pp/WjP8v
UTiqP2onzZJbidlSBvmZ2nheWk7G78e617gcV/ye+UyXZvciiF2UQBg9YV6D8JuD
YhBbNAVOzJOiyOdTBmZmOkmYsGx58sEbFVqGeOMB0xoxZrqKjMm9NhvjqjJF/sWs
hN/PD5ylW1UR05/fGxlG2GLKKfBInbdqnC101OFWXP5HenYHmKaBJoCKCAUfsoJ0
r/t/GVh3z3w/99p0TRDONnTecKm5S9z3/5QjjE5RsWcd4ll7mRikUiVpe1WhKRwT
4T76pQLq3XwNJqiOmuMQuSHoBE9OMufvRFiTYC0QHyLoCV2H5PCWtS2xSsIDN4PB
0RNd0hnHKanVV7d2TkIrGOagoAo0wXqyW/Op6KUG1NdaFYYziDFEHeZxfGoPKytO
iS5PEwZG2FqambAZhJU5OXwzgnCRIoE5DCZad4YS6U5YD/2zg+RrQ/5GUxl5Cc+W
Zwesn9FV5jywx/oFePYbTSNQVPQ6jbUDvhmHvZ8c/OfGOVXQr0VpvfIwdwARAQAB
tD1UZXN0IFNpZ25pbmcgS2V5IChHUEcgY3JlYXRlZCBmb3IgU3BhY2spIDxub2Jv
ZHlAbm93aGVyZS5jb20+iQJRBBMBCAA7FiEEqYoEuILhnYX9Nu4GlWXYCwVckv8F
Amf23+ECGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQlWXYCwVckv9i
pg//eGjBR9ph9hUYRsekzKWM1xB5zFOFfNoqlpCut/W7LAfy0XXkFy/y6EvPdcgn
lLWRWPsOFfsKGwZd7LgSovhEMQ2MRsAUUB/KNZx7s6vO/P773PmJspF3odQ/lcrM
1fum2lShChWqimdBdNLrXxG+8duO9uWaMBIp28diBCyB25M/MqpHtKYu00FB/QJ6
ZwQH4OsgXVQHRjyrtIGx/2FQoWt0ah3eJMJCEw46GgkgiojtoTfXQQc4fIJP324b
O1sxz5lx3xVBG/EZYzyV3xnSoG9aZNJ1cJq8EKO7ZoNKc/8jwkVu5gewGaXYI0LK
/WkOeiXcSHPMSdu7TpnitvLYFCjc9YAEKQnjooXdt7+BElwC3+5hZJNXEnoGPMzn
3UL60sQE/ViCsGcW+l9rtzXPNTmLMjEg4rGRqOhX+UmwyhvGD2QYbZtXlayu5xn+
5m/PfmdqgL1xsdvNsLo/BOo+6kizMdBk48Xfp0YM8AC4BzUEENypGzC4T0WYF0k1
Jfc6/eSwiytIcIkJ42GlaVfEFE8UxfYc1/2zqTBN9EdzWJqy0Bh+mVOgOaeb0Dzi
xWpUpChi1fBB3PXWJ5iAS/w0HSVn4G5/JAIEFAs7r6ju2YtKBfuk+u/K5Q28mo7W
6LrZQywN44nBMTvSQUhhXpSNYG+juyotXJUJ3F2u9Cf/jVU=
=TkbL
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -0,0 +1,29 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGgnhhYBEAC5LOSkJlxL4rRDBLDatswpzAw7NQnONW37hwOauEf6rlw/wk6J
2D1l/jjmGwyo1iHOEu1/26fMuXMmG0vAxOQJFrkoKAgxDUD9nL0GqTJyg0+yTCN6
xsWsrIZi+8oNDXYzLiejICZorc+ri11kcZdA+WE2hWPRStmJH75afpSd7XfNijqb
MPfDZBcr+pLeARSH11BTfb8Dtm9qN//+X+pNIUqeHL9hLu/W9hb3GCfXqnsCQJA1
WMFTrbCcPYm0R7EevMnscFvS8xbhocBPDwZ12f4W5CugrL29X4Vx9SaUlIyy/+SC
2Gwi8Yq78Y4dTN7N5aA8L169/uqy4Tx7/966wMkUYXk7UxmH9E0ol5EZYnY9SCj6
xLtMNKA+NLwESj0azaWEzxfztyNdTYfG8Eaa/QGFs1YVGhYdmcEp8KDbQg5FBeCA
I6MUcH0XWOTJaZI/oEtukMYHzBt9jyyq6Gp45TiQvOou0wE+w/zJcd9Td23R81KW
GfMh5r80NET/bx88vee4NNHkWCphhqs53rIrhWV3y3WKaWp7DfP3WMiTBJ+Yc+PI
0vMIHKYNy+OqwTjmwgKdN1w1xZhLG7hx0sAdcZGP7q0A6381HtucgS/fucDogMnW
H3anE8UGx4HBRjyXsuOaOAgNw2K4IwancUSf67WSzji3AiP46sUun5ERNQARAQAB
tBlTcGFjayA8c3BhY2tAc3BhY2suc3BhY2s+iQJXBBMBCgBBFiEEy6ssEDLG/1B4
BJ7A+mHVDBLK034FAmgnhhYCGwMFCQWjmoAFCwkIBwICIgIGFQoJCAsCBBYCAwEC
HgcCF4AACgkQ+mHVDBLK034zWhAAtjm802qaTSCvB9WvY1RM65/B1GUK3ZEv3fw/
Dvt3xd3mh+rzWBTJ8t7+/cPaOq7qOGnfUateHgou+0T6lgCLkrwr4lFa6yZSUATb
xcnopcA0Dal218UcIRb20PjPtoKu3Tt9JFceXJGCTYoGz5HbkOemwkR8B+4qMRPW
sn1IhV32eig2HUzrUXVOv6WomMtk2qUpND0WnTlZo3EoInJeTzdlXkOR3lRLADM9
yPM6Rp8AV/ykM9DztL4SinzyZjqEM7o1H7EFITZSlkjcBPvqDlvowZGN8TVbG9TQ
8Nfz8BYF3SVaPduwXwhbE9D8jqtNt652IZ1+1KbMii1l4deu0UYx8BSfJjNANTTU
jFDiyNaGnn5OsZXNllsyAHWky6ApyBD9qFxxNr0kiWbVrrN6s2u4ghm5Hgtdx40v
hA9+kvB2mtV/HklUkwDTJ6Ytgp5veh8GKvBD9eAWIitl6w153Rba5LkZbk2ijK6k
oyN9Ge/YloSMwXpIEnE7/SRE1o5vye294BZjyqnr+U+wzbEYbC7eXJ0peDCbpbZc
0kxMDDbrhmHeEaHeWF30hm6WBaUT4SUcPj5BiV3mt3BhtRgAwA3SvuSenk2yRzR8
tBES4b/RBmOczfs4w4m5rAmfVNkNwykry4M2jPCJhVA2qG8q1gLxf+AvaPcAvQ8D
kmDeNLI=
=CYuA
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -1,29 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGfHlp4BEAC5wkZSHqF9z6GcymuHpk1m9aNXCJdt4ZWvE8ck8GcuVu1nbzlZ
h959jqtwk7nFMki5YaNMz6jcQf0eeS75viL4CoPAqFiVyhyCCh5am75h9F7vTBq6
190017lhu9IgkAkiklnjfDbyXH+BwqJ78nXp6e6R4ShFMHNGGvYLem1wmPKzqPlZ
zN0yjc0+d5pw4hu+IEFrM63yqGp2BVX1X132IKUEcROCQt1QOma5oORhYEtSCieX
PuhuHJOA7q6nJuFccPCs5OcDS4IbQgGAbWL4L1+LAGVLVGpK4IVtqEZ831Srclh8
0ruyFFeV/hqOONThwwile0Jwh5Jz/2sYxT5c+nlumXWK+CXTm4OCfGt1UuGy6c6u
Rz84PHfanbKnATp6RUjz4DMREkmA6qBnUFqGLLGaBKBsm42b7kbo7m5aeItuOwLE
U7AcnBEqqHLfI7O1zrHKjQCxhEWP/iok0kgEdiJ4tlPhfDjQRG6thlmZnVdt/08V
+bvVkbYZyWPzjbG3QHyFew1+uzPHb2UopgpByVKYEWhCgNfcFtE56lEI9c40Ba5o
LaZl0VlgfSLP4c+LoFB6gZp1gcVQuPo1JKd1v5WP60f1iHhazL5LEeMYcW6kvujK
58Q683gSH5DsVAnxaj1uU4nvtKDh8IF1CNKKXk8RVsltdpv9bGhV8b4qVQARAQAB
tD1UZXN0IFNpZ25pbmcgS2V5IChHUEcgY3JlYXRlZCBmb3IgU3BhY2spIDxub2Jv
ZHlAbm93aGVyZS5jb20+iQJOBBMBCgA4FiEE6J1JcfAJex56PrVzcbSEgC54180F
AmfHlp4CGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQcbSEgC54180aDg//
f7GqIW5LzYqIqkey+IjdkSSfeD47tlWc2ukKYStHu0gTlHhrUp4rHNJ/s8XQ1o6o
jwzWfNMYh68wt9sjuM2BEkkh3RUFEjVqqW+k562gS5ibfKTDtJb2Yj0n/CQKWvoi
vUUzO88xW0AnZFieP+vD5iI5Zw4H2dY8cH4X1XlWAJufFdH4WBaZjujNwNOcCsnd
w2nE050wKTR2wroWq0HKn1Ni3QNtKWPpLoHGAlhW6ACLa+EFqxHU6D3KhW6IV4Jc
sdt36nHNiRiy6nT99asqtN6Z0Yw+EnQSuIDosIbmSgZoieINh0gU6AKwgydxLUxL
Cu1w2fZHGuFR/ym0c/tTpM893DxHMc/EZ/SpU8fXkC9lYnQO3or/Y0mLHd0kSEv7
XoonvcOu1tOQzmvrvUQUtTn4+6OKpGViyZG5C8Lbk8/yKWFv5b+Gpss/EiGTHSsk
bPTHf5jMsWElv0GgFq2TpybtIcY52yJoZ1fBMEA9Nk76Y/MNFlN0d7HyS6tWGr6E
8FWJB7RYG5XHMEDIKSheq+Q5cORwz92JPFI+sovZukp+20G7f7/gwos441KamJPc
y1+M4uO21aKX2fA07bcgFtm25gNLoHyvjQLcmyDis6xogvciCV3iQ/mtunewgYp/
lUX1dv0R5o8TteaAIkbJicbdLtur/iuAWN404E/QShc=
=8P00
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -1 +1 @@
{"keys":{"A98A04B882E19D85FD36EE069565D80B055C92FF":{},"E89D4971F0097B1E7A3EB57371B484802E78D7CD":{}}}
{"keys":{"CBAB2C1032C6FF5078049EC0FA61D50C12CAD37E":{}}}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
7f94d6038bb4e5e7fff817151da5b22d7dd6d1e2d9ad51bd55504676786c17bd
81a5add9d75b27fc4d16a4f72685b54903973366531b98c65e8cf5376758a817

View File

@@ -33,7 +33,7 @@ Hash: SHA512
"name":"gcc",
"version":"10.2.1"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -85,7 +85,7 @@ Hash: SHA512
"name":"gcc",
"version":"10.2.1"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -108,17 +108,17 @@ Hash: SHA512
}
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEE6J1JcfAJex56PrVzcbSEgC54180FAmfHlp8ACgkQcbSEgC54
180hlxAAisLofFhr/PQvLcQ79T3t3V0tqGgz9x6QnPKfbPCgvb66tTNlny+ML0fY
y1H9xXQO53QOxfN9cdXcf2EVbRQ2eT6ltmwekI3ZZuCaTguflNu/i11UV6UnDy3x
dXOYQhky5QjtPbhJ0NxG5XDKoRFoUPR/rgXsiNG5O0sk3M5H9ldpsj8af5W/6LCL
gCTNM8fF0TVbd4MF9TiIECFBng2CrxhHwpl2gPHHxab1zxLRCF6t1lZvL6To0hmC
e/Tqre+42PhRSCtXuwhK22r0rvreVUaiglYn8udjOJHwNVKdzLnTZ1OBAFeIq00U
9uuroyaF841pq9+8PitwUORurv0lsnHUbfbi/+ou0HzMiaXzz+MPdOXt8nUuyScs
oKOi8ExvpWJ7vn6klkvQtMK/Gakzd4YOxO/nk9K8BJgVN3qrODwHYSORk8RrdITS
tkjiEJiIoklddiwCf3NUzlxiIYWbiqKqNbY+Pxh4B+OpVDnvRmpkJHgoSuVoCS8b
coaOTIgqDpnIClHIj7ogxO+ureRjIIkGNNh6wVhlHDlgm1GzxNUOklMrzDkYMD01
eTYxrbicw7ZVwqhFtR8olODKT9QAqXUJOkGHS9IA6FJctatkUkIOG1DSI52AZV1r
PYzgdKtTxS60EkN8Igl6VMTkaC05anLygCTyOvGaV7sqVKmzHY8=
=8OR5
iQIzBAEBCgAdFiEEy6ssEDLG/1B4BJ7A+mHVDBLK034FAmgnhqIACgkQ+mHVDBLK
0373kg/+Iy7pfWoAa465XtWUyf87KcjmJ1hE4OmfMc9sA7kdKNYPfmttxfp8jCU5
gRc8RnQ5K+h4GWGl9nd6bFOT3oZSBH9WnH33gcnStHubwvHzhY05ZmlKjXKKTJmG
rcQ8+vVv/e8KfMatydPuXQmAzbJ0pr2bGnicT8fs/W35hgcyygDZvDqJo3m+q4H7
uu4C3LnaixAf7kCZefdxReYvFBNz9Qovws3+LqVFPxWgqo4zYt1PcI24UhCpL2YJ
6XJySW7e0rR64bwCZR/owy504aUC64wr8kM19MMJAoB0R4zciJ0YyY8xLfRMI3Tr
JTPetuTN7ncKJ2kZJ5L+KbeYnr4+CA5ZYmjyAM5NSJ3fTXuEu477H+1XovcJtP1s
IZS10UWX452QEBXE5nWAludmiw4BenyR2Lccg2QfER8jbiZf3U3do43aGoI5U8rg
qf1kQ/dMcIX6oSrbxMKymdsuf6e8UCSys3KNwb44UdSBiihgYFtiMfGtQ6Ixsvky
TB+EwweUY6LtBuep1fh+M1tHgo9qCxUH79duor0JRDgQ/VLeO6e1RCptc7EHnQZQ
mZK7YjVtHYWzyOZ4KsWuLYBSAMvKDhrTxI8cxp816NNGUfj1jmBQR/5vn6d7nMwX
PmWrQV9O2e899Mv30VVR9XDf6tJoT+BPvS4Kc5hw/LxjaBbAxXo=
=Zprh
-----END PGP SIGNATURE-----

View File

@@ -33,7 +33,7 @@ Hash: SHA512
"name":"gcc",
"version":"10.2.1"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -56,17 +56,17 @@ Hash: SHA512
}
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEE6J1JcfAJex56PrVzcbSEgC54180FAmfHlp8ACgkQcbSEgC54
182ezg/7Bkil1mY6d4recJMkFhpBzzDs8aMD+WQOBPoy/bWHIGsPb1DyOOW7lTLa
QC9jh9Rq02oMeX0LWvNg7k6iMTayWcrPzJwk1rgh3pg/ySgCTZ576/aP/UOZwA8h
HT/3RzsDFlq7Wkh4yYaDgSEDVc5PgUevb1p2f126Z9HMFjG8siEWmuZQOcy4I9JG
osQFtwWTLmx96sBMzweZTu2i3iGTPNz4Ae1hu+v5clmSFg43eW7EWChEVoob+3hb
hLRxajZEPsIho4yR5yynoxduXeXrLLP7GH6XGnYt7Z2GJR0UamIrPfxYuWBK76V1
03Ie2rRXwOKfsjDWw9Z8ziTVu25G0aZ274DX6eQyaWKfvzz69cBXO0fgw1lU8B9S
K0j9k/xtnDCrIkPSh4QGQpFRlbzxkj20E+EnwgDCGIlK1rBzo2V5na4YNj+SbC91
0BmWrj6dRkQZUMJHeb95kBMfFpKG5B6u7HQxZtIwHFAfF0nypbiB7xmdy/gAmUao
ej3Cu34DvWtLVeSh7lRimeEc44WyBDk2YSPqYleAwYMZBn4WSozUS/KVLU2T/AhZ
VlLaEBaFrVngmsw5PCdck0XRSNSAN9HUgPItpOzYig20NeT1/69wIlUZVNpLEYGT
yvZsmqHFnkunAs6av3XmGl0i8rSA6DujunpNXML6hUciFEK5wg4=
=Aq8h
iQIzBAEBCgAdFiEEy6ssEDLG/1B4BJ7A+mHVDBLK034FAmgnhqIACgkQ+mHVDBLK
036q+Q//XkOoRoZ5g3uyQTXTV3w6YCUezkvGv+WRV4oZfj0CElKf4KoW5bhdtWEM
EBRC4UuFturk7m1KrgztKsEFq7vx0TxvbWjj5R64swrwczKkD7i5xjMhWZn0nrpk
kzeKJw8zCr+o+qAHUoqTZAAf1GaMOwCKN8rZ5zrulbkrugPY783UKJtfyJc8+BPT
dixOerTC5cvzFNHENIKXMTh7Pbww2jdnFCn2eGA1kmyJGkRFhKKQ9kerlUcfOdQB
w51jMfgZRoG/hvSnrlrYHJQx1hpUiBV5eyEcLHnlbiJj7cNTvqcrt2nHpy/1Co1H
5uiQou5I8ETTvTQrtWNgCtUBg1ZqaKZw8tanSY4cHXoeP5s4uQl1yTEGCEDDFB9y
E/yO9xTfak3Avv1h6FZ2Lw+ipVLnlurtpo/jGmr4UgoKV4MZ1hFSseIEWQVyXJ+4
kP2gZ/LZF84eYqRKANYGWbKp/fKJQgnn/nhKgySfx4dKHJFRpVNgiGzNYyYwOtOC
BWrLIqgvETl+MZZPMPwt8T7ZCYIR5fzQ1itGM3ffmsh9DIvRyu32DRWBcqgiDE7o
866L+C6Kk2RyCS8dB3Ep4LW7kO42k0Rq6cvkO8wV+CjbTF/i8OQEclDMxr+ruoN0
IKEp2thRZA39iDHGAIPyCsryrZhpEJ+uOfMykWKc0j957CpXLck=
=Qmpp
-----END PGP SIGNATURE-----

View File

@@ -1,5 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hash: SHA512
{
"spec":{
@@ -57,7 +57,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -169,7 +169,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -193,7 +193,7 @@ Hash: SHA256
"platform_os":"debian6",
"target":"aarch64"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"languages":[
@@ -275,7 +275,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -353,7 +353,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -413,17 +413,17 @@ Hash: SHA256
}
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEqYoEuILhnYX9Nu4GlWXYCwVckv8FAmf23+QACgkQlWXYCwVc
kv9Xlg//d7uWhVbHjujSXRpoN3hzH5sUvvTSZ9xzvXGAXCoAu2oEGg4hxZPIFQJ3
pZzKysZMfeFg+UKwDzex5TlKZ3JtKgCTKYl64zZfUl2EQgo/d/Fjz5mSFHW/6sa1
1uTe3+sVt+HlijN72t2412Qbp+/uGvU+KBvXPA7kgkp88Kd/PL9xe3jlT9ytH5Nw
3LIghe++JiepjFAKXTfIA04EjLb8c50AAxsK5Xx37HOOVHHQ8L9anFnOVYM+DxAz
gn4dBYUQ9Uu5k5uEu5CwtxsED2/Yar7YWIepEnyp6z4zQVbwjO4/w0vZ3wSJ9c4P
UhZs8V2akuqIWyzlQuBOjywnEQc/nw9v0py+Dr/Qr3U4XWh/LARWABMxa4IqXMOK
aVmd6weVjV4U929gaOT/FCtZPfaFNRbk97YP8yAxuLhSdiGS0Mp16Ygz21fVWB7C
UjkGGsKK1cdiJQ0m1CffmydU/nbDjSuw4WZIoIgDzvN7SFm7YBtE+xY+RUPsHU22
QMAXojF5abwn48HJeP47MYdfR7+nUJq6XJiJ7/80a7Ciy8SAVxinQWqvigf/hmTf
kAiQaqOVSlRBJ2yry5fYBKHSIRvghCqS4t4es8o13R7n2wz68VqKu0JkNlT3Ijjc
QjJYtI+844PCDNetPVV8iNWF6upnTJnPHcFmKAEO1663hOc3Dh8=
=3fA5
iQIzBAEBCgAdFiEEy6ssEDLG/1B4BJ7A+mHVDBLK034FAmgnhqIACgkQ+mHVDBLK
035oXBAAj12qztxIYhTbNRq0jpk7/ZfCLRDz/XyqzKx2JbS+p3DfZruVZV/OMZ9I
Hlj9GYxQEwLGVsEMXoZDWtUytcte3m6sCG6H8fZGKw6IWQ6eiDR5i7TJWSuPvWGU
NMH57kvSJlICLP9x6NWjQeyLAI4I3kASk+Ei/WHAGqIiP9CR1O5IXheMusPDAEjd
2IR7khPvJTwpD6rzMHPou9BWk0Jqefb9qHhaJnc0Ga1D5HCS2VdGltViQ0XCX7/7
nkWV9ad9NOvbO9oQYIW1jRY8D9Iw9vp2d77Dv5eUzI8or5c5x0VFAHpQL0FUxIR9
LpHWUohDiAp3M4kmZqLBPl1Qf2jAXFXiSmcrLhKD5eWhdiwn3Bkhs2JiSiJpHt6K
Sa970evIFcGw6sUBGznsuFxmXFfp84LYvzIVjacuzkm9WDvbEE/5pa2b5Pxr7BmH
d2xDmAYmZVOso6INf3ZEXOyMBPWyGyq9Hy/8Nyg/+7w2d4ICEG/z/N13VsTqRoXc
rb8I0xDE9iCXCelQJYlJcJ2UMZk9E76zd3Bd2WcgCTrrnHsg0fBjmNeyPJcBN8hA
am5Lq/Cxqm2Jo2qnjoVmCt8/TBkvT2w8PTpR5uTEbLDl2ghyzxyBkX7a8ldKx55f
aL8/OxN+u0pyISTDs5AoZ1YbhgDMiBiZV8ZDIB8PzU8pE78De3Q=
=YbRr
-----END PGP SIGNATURE-----

View File

@@ -1,5 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hash: SHA512
{
"spec":{
@@ -57,7 +57,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -157,7 +157,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -181,7 +181,7 @@ Hash: SHA256
"platform_os":"debian6",
"target":"aarch64"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"languages":[
@@ -263,7 +263,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -301,17 +301,17 @@ Hash: SHA256
}
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEqYoEuILhnYX9Nu4GlWXYCwVckv8FAmf23+QACgkQlWXYCwVc
kv/zSg/+NrS4JjT9TFSFR/q2vaN9aL7fSTunxp+M8eAzTmg0sgHc/D6ov2PMpUF7
1E2mnZ2gL5a5dHtsSCf30ILFzQoD+m+I9yOwcJopcbEjr8pcnXBFe6TT8lkxlXtI
EHNsYGMUHFbFvc+hFdWatQJicdDaIbdyEMGAC7Kobs/4KpdBF5VWV+sIrzD5+XzO
ACiKRjBmcaJpa950nuEaFzBITgq1aDtZ0EEZdXYvjRnzj9Bm6gbqmWzlllW1wf4r
5hSMTpAsRED4TxL433nuf0nKIvTD5Mywzs88kiLCtEABfDy1qccyBAnjyNypFF6B
fPqSDnr33s+JQ35t7RcHKfrgowk69UablE25YOUrQP6LtH4QzLBLj4/Z0zuz33hO
v+YYe51DgixsMQ2WCKWEO6sNcrcrLBJMFVwUP2FyTTdW3jCYRlFiTYLSfoDhTRJ/
4o7f2eEp3sVoOe12jKI6dw/P+c70dl8K4+1ICcnZkwsb0pd0vt2z4J2kPs2+1/0g
vpywJO1HL5Zy7/ZRlmeeSMHYEDX2eKhm7QRFbxw1IEbg3stQCA7a425JWztyJ05K
sfhFQgPt7F/xanJVFYk/hdza+3+5pFr1K/ARcLFBdLBKGxAXTMMR+NkMp3J5NiOo
SMZJ3jG6xA2ntvSkyx/GFawD0FpnlgEByU3E+R/WiQA4VojLpvo=
=kfWI
iQIzBAEBCgAdFiEEy6ssEDLG/1B4BJ7A+mHVDBLK034FAmgnhqIACgkQ+mHVDBLK
0356nQ//aVMUZU8Ly8/b1H4nvKM8Vyd275aFK64rvO89mERDNiYIOKk1pmYSMldU
+ltx2iIfVTUCEWYYJb/4UXWmw6SLAXIZ5mtrkALDAeDSih4wqIdevM3yii7pn8Oh
/OEyDX8N5k05pnxFLYqR/2gA6vvdxHFd9/h4/zy2Z5w6m1hXb5jtS2ECyYN72nYN
8QnnkXWZYturOhb4GawWY1l/rHIBqAseCQXSGR6UyrHTEGLUgT0+VQZwgxLNM4uG
xj4xCDTgKiOesa5+3WE8Ug2wDIm48Prvg4qFmNrofguRNiIsNrl5k7wRiJWdfkjc
gzs9URYddoCTRR2wpN0CaAQ268UlwZUCjPSrxgCNeqRi4Ob9Q4n37TKXNcVw46Ud
MXRezAf+wyPGkq4vudh7cu11mHUcTeev82GM5bYQa6dSna3WvPpie/rx0TZYRkKE
hesDW/41ZtFDANfXa7r011ngS5zZwak3zUaoqOdLNhN/xL4TFsZ19uSUdSZHAgSk
9Sr3xodwV2D5H6gDuOtAo1vRod1Fx+yoi3BubX0sI5QuFgvtJrHVZmVj2bnGMBKI
gR17q1ZHOmp3yPhVE9ZsiLKn9r3yIsfVhoTB6mXOnvq2q1fBxyrEpIGzIUmWfuTm
vLn4nXt7PD78msiG/GZt6fShYBAwVfuvG+M1AQrsyGGoW2Bty7M=
=hLvB
-----END PGP SIGNATURE-----

View File

@@ -1,5 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hash: SHA512
{
"spec":{
@@ -57,7 +57,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -83,17 +83,17 @@ Hash: SHA256
}
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEqYoEuILhnYX9Nu4GlWXYCwVckv8FAmf23+QACgkQlWXYCwVc
kv/T8BAAhK/v7CP6lMIKILj35nEi+Gftjs7B7f6qvb4QNtqcGHum6z9t3JxkOOrd
+q+Wd329kLYAFs/y9eaGe5X7wY1U7/f863i3XrxHbtmrnMci61D8qMjA1xnBGC+5
yd746aVeV/VRbJxTeB9kGcKPMcIQYcearlDMgj5fKfpCKM8a+VyJfw7qHNUyrTnu
d6LSGsEey6tGkJecgnJZTNSwryO3BZbg/4EviivMXm38AKGZrSib06qjkoHrPRvB
8ftGSGlK4YmFs5/YjKFL7QzuNJeqPNJt4mD64tsk21urOfbQJe5AmdMLPGY0PbW/
w++06c8lsd/6FmzUwlnTBUa39lKJjhkhoK7KFGVqZROcXZfhwAyqPZt7ReA5FDMV
l5X7sytjQuSFaQPGi5g1xXQGEI394T2I55p5T5/RuQ2PXcFxxSOmIcEcD8o6Z7+x
XWLq44KUWQyQP/StjaVhIz9YPogeBBJllA9hN+GzVrr2i+Esu1QO5uDgVuJP7pTA
9wwCLV/t0hf2TZcpU2fwEu+DMniaHm6haVwqiu6QGkbkMBx49zkV9b5i9L441GoC
Q86R2Gs9O0+QzHuN6egbQ0xKm/lfU8dmJSzV0snXawAeQ/vgCpdinx40EMc7Nz03
rgZ3j88c/ADvCb1DVKmu1Phf6U7WqG6/AvB9tYl4Zl30VX7ETaw=
=ifvQ
iQIzBAEBCgAdFiEEy6ssEDLG/1B4BJ7A+mHVDBLK034FAmgnhqIACgkQ+mHVDBLK
037BIQ//U30gx1qTt5cQs+I6fwqQSase8DT7Hi8VdYxMuBTVbEpnPScNpcH03ITC
KWVbXvEAPBdoWEfAHpuOJr2pm013dYXaWp1k0G6pLSvnR17LEDTJs0ixAurH4vDr
4VXPerPR57sMi0WYomi1+dJhvA3S85+m6KBPLhXgi9Y28leDrFpjBwxVoIN7yUP2
tenMI9jAoGh/hts1pIPbALmKbeGUKC2MPu9MF0CtkbbE1VOkeJ6jkZLGki7AAYZ0
TSWAeWDk6EG90TZ6ls2anUPI1mNc7JdPqq8L0+jWAwLJi3i/JiDAGUM99hpu9cCF
NvZn+eQFOKrE0WG1KsF4vQilOAuE3P+QLomcfZdf2UNi73XPWIF5j46r50oPmXZE
+mVUyw7CUbHMZlXvWml0pdugEER1Kyc2nLZdLZYAT92AsPbAcDBQKsm1xf66lOB+
FPPLc97oybcFFldrjmUJAASJBeAihZG1aDm6dYBxtynMzzRGdq2+R1chHMOQ5Wej
8ZvyRv+TOPUTtRkAxrUpq6wA+BUoq+OBDltOs9mXUIcV3rpOq5nTjKZ5FLMtGaDw
No0E5gwceDDLeshT9nAHaqcmSY1LK+/5+aDxOFRm4yRTI+GLJzg8FZCJbJRLstrD
Ts4zKdcb0kukKdE9raqWw7xuhbjz2ORiEicZzckzvB1Lx38bG2s=
=T5l5
-----END PGP SIGNATURE-----

View File

@@ -1,5 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hash: SHA512
{
"spec":{
@@ -57,7 +57,7 @@ Hash: SHA256
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -93,7 +93,7 @@ Hash: SHA256
"platform_os":"debian6",
"target":"aarch64"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"languages":[
@@ -135,17 +135,17 @@ Hash: SHA256
}
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEqYoEuILhnYX9Nu4GlWXYCwVckv8FAmf23+QACgkQlWXYCwVc
kv+MsRAAsaQjZbB9iW/Lq9b87H/E5Zmv6RrClvpjSnwvhLR4nhPL3p0G70k6tI/b
NEdXctDyvBOJOEoLaEBrCODl/3GjV8B9Gj7OhT/BIKQjlOfJqVdwIrnHgav5ri+Q
UUXLtejhJiUNoxeILI/xZx2CoKT9q/3EpQ5ysqdybJmYJCf/hv+lXEhnwUIv8vV/
xdRYY//rfeMowCNIZtFPjSejMywXJfFKjl7h5dN5kwM63D6z/sh4zW7tqHq4kk+A
2m0WcorVg93wAm+YoJaQJVx8bYeMGfV/TjmY/cSouCt8PM4Vi93vwieZCkzEpXbM
BkVN4X3PTMZSOf0WTkEbnQD5v090/DoQPZyBrcDoJ/HmWDiz5Is2wUI0mLVkbg2L
+rKNC3ZajJhsWElMGNNtZRLmGeTIe8hT+LNAejo221vrOJbnUmpIjKxVjStDbXmW
nulgyEPSTfsJaXgbXmeJ8LOk0tWpBAGC16VzgXrPxoGD2XKxoiPCGLNrF/l1wyl+
n+nw3TchNFrofpPrqJzT/vS71B6KDb0PVSTQZfM9+FahrQ+YbsIkzDAuxVZb5t3q
HUME95RgoIBbccUGxAPwkaNme2OLaLzsJZ/Xhl5I8T1fraLYapsKNjQ5+CSKO8+t
MlJYgSHuazWSetRbZ2H7g7QJWqeHUAWi9i1szpNDYxTFSs8wgDY=
=edPy
iQIzBAEBCgAdFiEEy6ssEDLG/1B4BJ7A+mHVDBLK034FAmgnhqIACgkQ+mHVDBLK
037zHBAAsqy4wItctMqauuna+JjxT1HM7YJElXzqjOWmxyuAzUzjXlhR2DBd/2TI
ZEN2q3Z3XY9sCjhZ/4c9wDfMNYLUBLMHuenyV3fOqsfIVL8NprrkGc5mOiJ8HbRk
u00qXWogsYSEmbGrlfDKf4HmZtgPNs82+Li1MD5udDUzyApuVbObJumSRh6/1QHm
BcQZgMlSCd8xsTxJudXKAnfpemqE41LF0znuU0x5Hj/hU1A3CELynQrLEYnJpzpR
ja2l341cBQKNy86kX1/eHQtBJverjFoD3Nx4per8/qUc+xTH0ejMuseyd9P3RLnd
WShY8Uk72f1OLGzq5RvayP1M/dBWedajKz5gYOD19pCuFEdQm1LkZhxRWJ35PYMV
CqzY/uJgs33zyYkNJKO8CKG5j7Y8zOuZ3YFN8DKmoWa+lC4gFIsXm42BttqiQ5+x
Q65YkX/DdPYO6dcUety1j3NuNr70W6PsLyqKBny1WOzKCx25nmzftS0OA76F6UZA
hDneqltGrYEQTowU5I7V14f3SMeO8xje3BcqhOAn956/JJObd5VbwqcHwcslwEJA
tL3361qbpkc7xURnhciV1eL3RYR9Q4xDnvI1i/k8J8E8W373TviK3r2MG/oKZ6N9
n+ehBZhSIT+QUgqylATekoMQfohNVbDQEsQhj96Ky1CC2Iqo1/c=
=UIyv
-----END PGP SIGNATURE-----

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
57cad2589fae55cda3c35cadf4286d2e7702f90a708da80d70a76213fc45a688
fc129b8fab649ab4c5623c874c73bd998a76fd30d2218b9d99340d045c1ec759

View File

@@ -30,7 +30,7 @@
"name":"gcc",
"version":"10.2.1"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -82,7 +82,7 @@
"name":"gcc",
"version":"10.2.1"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],

View File

@@ -30,7 +30,7 @@
"name":"gcc",
"version":"10.2.1"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],

View File

@@ -54,7 +54,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -166,7 +166,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -190,7 +190,7 @@
"platform_os":"debian6",
"target":"aarch64"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"languages":[
@@ -272,7 +272,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -350,7 +350,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],

View File

@@ -54,7 +54,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -154,7 +154,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -178,7 +178,7 @@
"platform_os":"debian6",
"target":"aarch64"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"languages":[
@@ -260,7 +260,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],

View File

@@ -54,7 +54,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],

View File

@@ -54,7 +54,7 @@
"cpupart":"0x022"
}
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"cflags":[],
@@ -90,7 +90,7 @@
"platform_os":"debian6",
"target":"aarch64"
},
"namespace":"builtin.mock",
"namespace":"builtin_mock",
"parameters":{
"build_system":"generic",
"languages":[

View File

@@ -31,7 +31,7 @@
"name": "gcc",
"version": "4.5.0"
},
"namespace": "builtin.mock",
"namespace": "builtin_mock",
"parameters": {
"cflags": [],
"cppflags": [],

View File

@@ -10,7 +10,6 @@
import spack.repo
import spack.spec
import spack.version
from spack.test.conftest import create_test_repo
def test_false_directives_do_not_exist(mock_packages):
@@ -159,66 +158,19 @@ def test_version_type_validation():
spack.directives._execute_version(package(name="python"), {})
_pkgx = (
"x",
"""\
from spack.package import *
class X(Package):
version("1.3")
version("1.2")
version("1.1")
version("1.0")
variant("foo", default=False)
redistribute(binary=False, when="@1.1")
redistribute(binary=False, when="@1.0:1.2+foo")
redistribute(source=False, when="@1.0:1.2")
""",
)
_pkgy = (
"y",
"""\
from spack.package import *
class Y(Package):
version("2.1")
version("2.0")
variant("bar", default=False)
redistribute(binary=False, source=False)
""",
)
@pytest.fixture
def _create_test_repo(tmpdir, mutable_config):
yield create_test_repo(tmpdir, [_pkgx, _pkgy])
@pytest.fixture
def test_repo(_create_test_repo, monkeypatch, mock_stage):
with spack.repo.use_repositories(_create_test_repo) as mock_repo_path:
yield mock_repo_path
@pytest.mark.parametrize(
"spec_str,distribute_src,distribute_bin",
[
("x@1.1~foo", False, False),
("x@1.2+foo", False, False),
("x@1.2~foo", False, True),
("x@1.0~foo", False, True),
("x@1.3+foo", True, True),
("y@2.0", False, False),
("y@2.1+bar", False, False),
("redistribute-x@1.1~foo", False, False),
("redistribute-x@1.2+foo", False, False),
("redistribute-x@1.2~foo", False, True),
("redistribute-x@1.0~foo", False, True),
("redistribute-x@1.3+foo", True, True),
("redistribute-y@2.0", False, False),
("redistribute-y@2.1+bar", False, False),
],
)
def test_redistribute_directive(test_repo, spec_str, distribute_src, distribute_bin):
def test_redistribute_directive(mock_packages, spec_str, distribute_src, distribute_bin):
spec = spack.spec.Spec(spec_str)
assert spack.repo.PATH.get_pkg_class(spec.fullname).redistribute_source(spec) == distribute_src
concretized_spec = spack.concretize.concretize_one(spec)

View File

@@ -1,7 +1,7 @@
# Copyright Spack Project Developers. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Test class methods on Package objects.
"""Test class methods on PackageBase objects.
This doesn't include methods on package *instances* (like do_patch(),
etc.). Only methods like ``possible_dependencies()`` that deal with the
@@ -20,13 +20,12 @@
import spack.deptypes as dt
import spack.error
import spack.install_test
import spack.package
import spack.package_base
import spack.spec
import spack.store
import spack.subprocess_context
from spack.build_systems.generic import Package
from spack.error import InstallError
from spack.package_base import PackageBase
from spack.solver.input_analysis import NoStaticAnalysis, StaticAnalysis
@@ -241,7 +240,7 @@ def test_cache_extra_sources_fails(install_mockery):
def test_package_exes_and_libs():
with pytest.raises(spack.error.SpackError, match="defines both"):
class BadDetectablePackage(spack.package.Package):
class BadDetectablePackage(PackageBase):
executables = ["findme"]
libraries = ["libFindMe.a"]
@@ -249,7 +248,7 @@ class BadDetectablePackage(spack.package.Package):
def test_package_url_and_urls():
UrlsPackage = type(
"URLsPackage",
(spack.package.Package,),
(PackageBase,),
{
"__module__": "spack.pkg.builtin.urls_package",
"url": "https://www.example.com/url-package-1.0.tgz",
@@ -264,9 +263,7 @@ def test_package_url_and_urls():
def test_package_license():
LicensedPackage = type(
"LicensedPackage",
(spack.package.Package,),
{"__module__": "spack.pkg.builtin.licensed_package"},
"LicensedPackage", (PackageBase,), {"__module__": "spack.pkg.builtin.licensed_package"}
)
pkg = LicensedPackage(spack.spec.Spec("licensed-package"))
@@ -276,7 +273,7 @@ def test_package_license():
assert os.path.basename(pkg.global_license_file) == pkg.license_files[0]
class BaseTestPackage(Package):
class BaseTestPackage(PackageBase):
extendees = None # currently a required attribute for is_extension()

View File

@@ -2,11 +2,13 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import importlib
import os
import pathlib
import sys
import pytest
import spack.build_systems.cmake as cmake
import spack.concretize
import spack.directives
import spack.error
@@ -43,7 +45,7 @@ def test_nonexisting_package_filename(self):
repo = spack.repo.from_path(mock_packages_path)
filename = repo.filename_for_package_name("some-nonexisting-package")
assert filename == os.path.join(
mock_packages_path, "packages", "some-nonexisting-package", "package.py"
mock_packages_path, "packages", "some_nonexisting_package", "package.py"
)
def test_package_class_names(self):
@@ -57,16 +59,19 @@ def test_package_class_names(self):
assert "_None" == pkg_name_to_class_name("none") # reserved keyword
assert "Finally" == pkg_name_to_class_name("finally") # `Finally` is not reserved
# Below tests target direct imports of spack packages from the
# spack.pkg namespace
def test_import_package(self):
import spack.pkg.builtin.mock.mpich # type: ignore[import] # noqa: F401
# Below tests target direct imports of spack packages from the spack.pkg namespace
def test_import_package(self, tmp_path: pathlib.Path):
root, _ = spack.repo.create_repo(str(tmp_path), "testing_repo", package_api=(1, 0))
pkg_path = pathlib.Path(root) / "packages" / "mpich" / "package.py"
pkg_path.parent.mkdir(parents=True)
pkg_path.write_text("foo = 1")
def test_import_package_as(self):
import spack.pkg.builtin.mock # noqa: F401
import spack.pkg.builtin.mock as m # noqa: F401
import spack.pkg.builtin.mock.mpich as mp # noqa: F401
from spack.pkg.builtin import mock # noqa: F401
with spack.repo.use_repositories(root):
importlib.import_module("spack.pkg.testing_repo")
assert importlib.import_module("spack.pkg.testing_repo.mpich").foo == 1
del sys.modules["spack.pkg.testing_repo"]
del sys.modules["spack.pkg.testing_repo.mpich"]
def test_inheritance_of_directives(self):
pkg_cls = spack.repo.PATH.get_pkg_class("simple-inheritance")
@@ -97,28 +102,11 @@ def test_inheritance_of_patches(self):
# Will error if inheritor package cannot find inherited patch files
_ = spack.concretize.concretize_one("patch-inheritance")
def test_import_class_from_package(self):
from spack.pkg.builtin.mock.mpich import Mpich # noqa: F401
def test_import_module_from_package(self):
from spack.pkg.builtin.mock import mpich # noqa: F401
def test_import_namespace_container_modules(self):
import spack.pkg # noqa: F401
import spack.pkg as p # noqa: F401
import spack.pkg.builtin # noqa: F401
import spack.pkg.builtin as b # noqa: F401
import spack.pkg.builtin.mock # noqa: F401
import spack.pkg.builtin.mock as m # noqa: F401
from spack import pkg # noqa: F401
from spack.pkg import builtin # noqa: F401
from spack.pkg.builtin import mock # noqa: F401
@pytest.mark.regression("2737")
def test_urls_for_versions(mock_packages, config):
"""Version directive without a 'url' argument should use default url."""
for spec_str in ("url_override@0.9.0", "url_override@1.0.0"):
for spec_str in ("url-override@0.9.0", "url-override@1.0.0"):
s = spack.concretize.concretize_one(spec_str)
url = s.package.url_for_version("0.9.0")
assert url == "http://www.anothersite.org/uo-0.9.0.tgz"
@@ -140,12 +128,13 @@ def test_url_for_version_with_no_urls(mock_packages, config):
pkg_cls(spec).url_for_version("1.1")
@pytest.mark.skip(reason="spack.build_systems moved out of spack/spack")
def test_custom_cmake_prefix_path(mock_packages, config):
spec = spack.concretize.concretize_one("depends-on-define-cmake-prefix-paths")
assert cmake.get_cmake_prefix_path(spec.package) == [
spec["define-cmake-prefix-paths"].prefix.test
]
pass
# spec = spack.concretize.concretize_one("depends-on-define-cmake-prefix-paths")
# assert spack.build_systems.cmake.get_cmake_prefix_path(spec.package) == [
# spec["define-cmake-prefix-paths"].prefix.test
# ]
def test_url_for_version_with_only_overrides(mock_packages, config):

View File

@@ -360,11 +360,11 @@ def get_patch(spec, ending):
assert foo_patch.path == os.path.join(package_dir, "foo.patch")
assert foo_patch.sha256 == foo_sha256
assert bar_patch.owner == "builtin.mock.patch-several-dependencies"
assert bar_patch.owner == "builtin_mock.patch-several-dependencies"
assert bar_patch.path == os.path.join(package_dir, "bar.patch")
assert bar_patch.sha256 == bar_sha256
assert baz_patch.owner == "builtin.mock.patch-several-dependencies"
assert baz_patch.owner == "builtin_mock.patch-several-dependencies"
assert baz_patch.path == os.path.join(package_dir, "baz.patch")
assert baz_patch.sha256 == baz_sha256
@@ -376,11 +376,11 @@ def get_patch(spec, ending):
url1_patch = get_patch(fake, "urlpatch.patch")
url2_patch = get_patch(fake, "urlpatch2.patch.gz")
assert url1_patch.owner == "builtin.mock.patch-several-dependencies"
assert url1_patch.owner == "builtin_mock.patch-several-dependencies"
assert url1_patch.url == "http://example.com/urlpatch.patch"
assert url1_patch.sha256 == url1_sha256
assert url2_patch.owner == "builtin.mock.patch-several-dependencies"
assert url2_patch.owner == "builtin_mock.patch-several-dependencies"
assert url2_patch.url == "http://example.com/urlpatch2.patch.gz"
assert url2_patch.sha256 == url2_sha256
assert url2_patch.archive_sha256 == url2_archive_sha256
@@ -397,7 +397,7 @@ def test_conditional_patched_deps_with_conditions(mock_packages, config):
fake = spec["fake"]
check_multi_dependency_patch_specs(
libelf, libdwarf, fake, "builtin.mock.patch-several-dependencies", spec.package.package_dir
libelf, libdwarf, fake, "builtin_mock.patch-several-dependencies", spec.package.package_dir
)
@@ -417,7 +417,7 @@ def test_write_and_read_sub_dags_with_patched_deps(mock_packages, config):
# make sure we can still read patches correctly for these specs
check_multi_dependency_patch_specs(
libelf, libdwarf, fake, "builtin.mock.patch-several-dependencies", spec.package.package_dir
libelf, libdwarf, fake, "builtin_mock.patch-several-dependencies", spec.package.package_dir
)

View File

@@ -43,19 +43,19 @@ def extra_repo(tmp_path_factory, request):
def test_repo_getpkg(mutable_mock_repo):
mutable_mock_repo.get_pkg_class("pkg-a")
mutable_mock_repo.get_pkg_class("builtin.mock.pkg-a")
mutable_mock_repo.get_pkg_class("builtin_mock.pkg-a")
def test_repo_multi_getpkg(mutable_mock_repo, extra_repo):
mutable_mock_repo.put_first(extra_repo[0])
mutable_mock_repo.get_pkg_class("pkg-a")
mutable_mock_repo.get_pkg_class("builtin.mock.pkg-a")
mutable_mock_repo.get_pkg_class("builtin_mock.pkg-a")
def test_repo_multi_getpkgclass(mutable_mock_repo, extra_repo):
mutable_mock_repo.put_first(extra_repo[0])
mutable_mock_repo.get_pkg_class("pkg-a")
mutable_mock_repo.get_pkg_class("builtin.mock.pkg-a")
mutable_mock_repo.get_pkg_class("builtin_mock.pkg-a")
def test_repo_pkg_with_unknown_namespace(mutable_mock_repo):
@@ -65,7 +65,7 @@ def test_repo_pkg_with_unknown_namespace(mutable_mock_repo):
def test_repo_unknown_pkg(mutable_mock_repo):
with pytest.raises(spack.repo.UnknownPackageError):
mutable_mock_repo.get_pkg_class("builtin.mock.nonexistentpackage")
mutable_mock_repo.get_pkg_class("builtin_mock.nonexistentpackage")
def test_repo_last_mtime(mock_packages):
@@ -93,15 +93,6 @@ def test_repo_invisibles(mutable_mock_repo, extra_repo):
extra_repo[0].all_package_names()
@pytest.mark.parametrize("attr_name,exists", [("cmake", True), ("__sphinx_mock__", False)])
@pytest.mark.regression("20661")
def test_namespace_hasattr(attr_name, exists, mutable_mock_repo):
# Check that we don't fail on 'hasattr' checks because
# of a custom __getattr__ implementation
nms = spack.repo.SpackNamespace("spack.pkg.builtin.mock")
assert hasattr(nms, attr_name) == exists
@pytest.mark.regression("24552")
def test_all_package_names_is_cached_correctly(mock_packages):
assert "mpi" in spack.repo.all_package_names(include_virtuals=True)
@@ -120,25 +111,20 @@ def test_use_repositories_doesnt_change_class(mock_packages):
assert id(zlib_cls_inner) == id(zlib_cls_outer)
def test_import_repo_prefixes_as_python_modules(mock_packages):
import spack.pkg.builtin.mock
assert isinstance(spack.pkg, spack.repo.SpackNamespace)
assert isinstance(spack.pkg.builtin, spack.repo.SpackNamespace)
assert isinstance(spack.pkg.builtin.mock, spack.repo.SpackNamespace)
def test_absolute_import_spack_packages_as_python_modules(mock_packages):
import spack.pkg.builtin.mock.mpileaks
import spack_repo.builtin_mock.packages.mpileaks.package # type: ignore[import]
assert hasattr(spack.pkg.builtin.mock, "mpileaks")
assert hasattr(spack.pkg.builtin.mock.mpileaks, "Mpileaks")
assert isinstance(spack.pkg.builtin.mock.mpileaks.Mpileaks, spack.package_base.PackageMeta)
assert issubclass(spack.pkg.builtin.mock.mpileaks.Mpileaks, spack.package_base.PackageBase)
assert hasattr(spack_repo.builtin_mock.packages.mpileaks.package, "Mpileaks")
assert isinstance(
spack_repo.builtin_mock.packages.mpileaks.package.Mpileaks, spack.package_base.PackageMeta
)
assert issubclass(
spack_repo.builtin_mock.packages.mpileaks.package.Mpileaks, spack.package_base.PackageBase
)
def test_relative_import_spack_packages_as_python_modules(mock_packages):
from spack.pkg.builtin.mock.mpileaks import Mpileaks
from spack_repo.builtin_mock.packages.mpileaks.package import Mpileaks
assert isinstance(Mpileaks, spack.package_base.PackageMeta)
assert issubclass(Mpileaks, spack.package_base.PackageBase)
@@ -160,7 +146,7 @@ def test_repo_path_handles_package_removal(tmpdir, mock_packages):
builder.remove("pkg-c")
with spack.repo.use_repositories(builder.root, override=False) as repos:
r = repos.repo_for_pkg("pkg-c")
assert r.namespace == "builtin.mock"
assert r.namespace == "builtin_mock"
def test_repo_dump_virtuals(tmpdir, mutable_mock_repo, mock_packages, ensure_debug, capsys):
@@ -185,7 +171,7 @@ def _repo_paths(repos):
for entry in repos:
if entry == "mock":
repo_paths.append(spack.paths.mock_packages_path)
namespaces.append("builtin.mock")
namespaces.append("builtin_mock")
if entry == "extra":
name = "extra_mock"
repo_dir = tmp_path / name
@@ -211,7 +197,7 @@ def test_path_computation_with_names(method_name, mock_repo_path):
repo_path = spack.repo.RepoPath(mock_repo_path, cache=None)
method = getattr(repo_path, method_name)
unqualified = method("mpileaks")
qualified = method("builtin.mock.mpileaks")
qualified = method("builtin_mock.mpileaks")
assert qualified == unqualified
@@ -220,11 +206,11 @@ def test_use_repositories_and_import():
import spack.paths
repo_dir = pathlib.Path(spack.paths.test_repos_path)
with spack.repo.use_repositories(str(repo_dir / "compiler_runtime.test")):
import spack.pkg.compiler_runtime.test.gcc_runtime
with spack.repo.use_repositories(str(repo_dir / "spack_repo" / "compiler_runtime_test")):
import spack_repo.compiler_runtime_test.packages.gcc_runtime.package # type: ignore[import] # noqa: E501
with spack.repo.use_repositories(str(repo_dir / "builtin.mock")):
import spack.pkg.builtin.mock.cmake
with spack.repo.use_repositories(str(repo_dir / "spack_repo" / "builtin_mock")):
import spack_repo.builtin_mock.packages.cmake.package # type: ignore[import] # noqa: F401
@pytest.mark.usefixtures("nullify_globals")
@@ -236,7 +222,7 @@ class TestRepo:
def test_creation(self, mock_test_cache):
repo = spack.repo.Repo(spack.paths.mock_packages_path, cache=mock_test_cache)
assert repo.config_file.endswith("repo.yaml")
assert repo.namespace == "builtin.mock"
assert repo.namespace == "builtin_mock"
@pytest.mark.parametrize(
"name,expected", [("mpi", True), ("mpich", False), ("mpileaks", False)]
@@ -248,7 +234,7 @@ def test_is_virtual(self, repo_cls, name, expected, mock_test_cache):
assert repo.is_virtual_safe(name) is expected
@pytest.mark.parametrize(
"module_name,expected",
"module_name,pkg_name",
[
("dla_future", "dla-future"),
("num7zip", "7zip"),
@@ -256,12 +242,19 @@ def test_is_virtual(self, repo_cls, name, expected, mock_test_cache):
("unknown", None),
],
)
def test_real_name(self, module_name, expected, mock_test_cache):
def test_real_name(self, module_name, pkg_name, mock_test_cache, tmp_path):
"""Test that we can correctly compute the 'real' name of a package, from the one
used to import the Python module.
"""
repo = spack.repo.Repo(spack.paths.mock_packages_path, cache=mock_test_cache)
assert repo.real_name(module_name) == expected
path, _ = spack.repo.create_repo(str(tmp_path), package_api=(1, 0))
if pkg_name is not None:
pkg_path = pathlib.Path(path) / "packages" / pkg_name / "package.py"
pkg_path.parent.mkdir(parents=True)
pkg_path.write_text("")
repo = spack.repo.Repo(
path, cache=spack.util.file_cache.FileCache(str(tmp_path / "cache"))
)
assert repo.real_name(module_name) == pkg_name
@pytest.mark.parametrize("name", ["mpileaks", "7zip", "dla-future"])
def test_get(self, name, mock_test_cache):
@@ -312,12 +305,12 @@ class TestRepoPath:
def test_creation_from_string(self, mock_test_cache):
repo = spack.repo.RepoPath(spack.paths.mock_packages_path, cache=mock_test_cache)
assert len(repo.repos) == 1
assert repo.by_namespace["builtin.mock"] is repo.repos[0]
assert repo.by_namespace["builtin_mock"] is repo.repos[0]
def test_get_repo(self, mock_test_cache):
repo = spack.repo.RepoPath(spack.paths.mock_packages_path, cache=mock_test_cache)
# builtin.mock is there
assert repo.get_repo("builtin.mock") is repo.repos[0]
# builtin_mock is there
assert repo.get_repo("builtin_mock") is repo.repos[0]
# foo is not there, raise
with pytest.raises(spack.repo.UnknownNamespaceError):
repo.get_repo("foo")
@@ -407,7 +400,7 @@ def test_repo_v2_invalid_module_name(tmp_path: pathlib.Path, capsys):
(repo_dir / "packages" / "zlib-ng").mkdir()
(repo_dir / "packages" / "zlib-ng" / "package.py").write_text(
"""
from spack.package import Package
from spack_repo.builtin_mock.build_systems.generic import Package
class ZlibNg(Package):
pass
@@ -416,7 +409,7 @@ class ZlibNg(Package):
(repo_dir / "packages" / "UPPERCASE").mkdir()
(repo_dir / "packages" / "UPPERCASE" / "package.py").write_text(
"""
from spack.package import Package
from spack_repo.builtin_mock.build_systems.generic import Package
class Uppercase(Package):
pass
@@ -440,7 +433,7 @@ def test_repo_v2_module_and_class_to_package_name(tmp_path: pathlib.Path, capsys
(repo_dir / "packages" / "_1example_2_test").mkdir()
(repo_dir / "packages" / "_1example_2_test" / "package.py").write_text(
"""
from spack.package import Package
from spack_repo.builtin_mock.build_systems.generic import Package
class _1example2Test(Package):
pass

View File

@@ -6,6 +6,8 @@
import pytest
import llnl.util.lang
import spack.concretize
import spack.deptypes as dt
import spack.directives
@@ -609,7 +611,7 @@ def test_indirect_unsatisfied_single_valued_variant(self):
def test_satisfied_namespace(self):
spec = spack.concretize.concretize_one("zlib")
assert spec.satisfies("namespace=builtin.mock")
assert spec.satisfies("namespace=builtin_mock")
assert not spec.satisfies("namespace=builtin")
@pytest.mark.parametrize(
@@ -2013,6 +2015,137 @@ def test_comparison_multivalued_variants():
assert Spec("x=a") < Spec("x=a,b") < Spec("x==a,b") < Spec("x==a,b,c")
@pytest.mark.parametrize(
"specs_in_expected_order",
[
("a", "b", "c", "d", "e"),
("a@1.0", "a@2.0", "b", "c@3.0", "c@4.0"),
("a^d", "b^c", "c^b", "d^a"),
("e^a", "e^b", "e^c", "e^d"),
("e^a@1.0", "e^a@2.0", "e^a@3.0", "e^a@4.0"),
("e^a@1.0 +a", "e^a@1.0 +b", "e^a@1.0 +c", "e^a@1.0 +c"),
("a^b%c", "a^b%d", "a^b%e", "a^b%f"),
("a^b%c@1.0", "a^b%c@2.0", "a^b%c@3.0", "a^b%c@4.0"),
("a^b%c@1.0 +a", "a^b%c@1.0 +b", "a^b%c@1.0 +c", "a^b%c@1.0 +d"),
("a cflags=-O1", "a cflags=-O2", "a cflags=-O3"),
("a %cmake@1.0 ^b %cmake@2.0", "a %cmake@2.0 ^b %cmake@1.0"),
("a^b^c^d", "a^b^c^e", "a^b^c^f"),
("a^b^c^d", "a^b^c^e", "a^b^c^e", "a^b^c^f"),
("a%b%c%d", "a%b%c%e", "a%b%c%e", "a%b%c%f"),
("d.a", "c.b", "b.c", "a.d"), # names before namespaces
],
)
def test_spec_ordering(specs_in_expected_order):
specs_in_expected_order = [Spec(s) for s in specs_in_expected_order]
assert sorted(specs_in_expected_order) == specs_in_expected_order
assert sorted(reversed(specs_in_expected_order)) == specs_in_expected_order
for i in range(len(specs_in_expected_order) - 1):
lhs, rhs = specs_in_expected_order[i : i + 2]
assert lhs <= rhs
assert (lhs < rhs and lhs != rhs) or lhs == rhs
assert rhs >= lhs
assert (rhs > lhs and rhs != lhs) or rhs == lhs
EMPTY_VER = vn.VersionList(":")
EMPTY_VAR = Spec().variants
EMPTY_FLG = Spec().compiler_flags
@pytest.mark.parametrize(
"spec,expected_tuplified",
[
# simple, no dependencies
[("a"), ((("a", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),), ())],
# with some node attributes
[
("a@1.0 +foo cflags='-O3 -g'"),
(
(
(
"a",
None,
vn.VersionList(["1.0"]),
Spec("+foo").variants,
Spec("cflags='-O3 -g'").compiler_flags,
None,
None,
None,
),
),
(),
),
],
# single edge case
[
("a^b"),
(
(
("a", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("b", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
),
((0, 1, 0, ()),),
),
],
# root with multiple deps
[
("a^b^c^d"),
(
(
("a", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("b", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("c", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("d", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
),
((0, 1, 0, ()), (0, 2, 0, ()), (0, 3, 0, ())),
),
],
# root with multiple build deps
[
("a%b%c%d"),
(
(
("a", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("b", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("c", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("d", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
),
((0, 1, dt.BUILD, ()), (0, 2, dt.BUILD, ()), (0, 3, dt.BUILD, ())),
),
],
# dependencies with dependencies
[
("a ^b %c %d ^e %f %g"),
(
(
("a", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("b", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("e", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("c", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("d", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("f", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
("g", None, EMPTY_VER, EMPTY_VAR, EMPTY_FLG, None, None, None),
),
(
(0, 1, 0, ()),
(0, 2, 0, ()),
(1, 3, dt.BUILD, ()),
(1, 4, dt.BUILD, ()),
(2, 5, dt.BUILD, ()),
(2, 6, dt.BUILD, ()),
),
),
],
],
)
def test_spec_canonical_comparison_form(spec, expected_tuplified):
print()
print()
print()
assert llnl.util.lang.tuplify(Spec(spec)._cmp_iter) == expected_tuplified
def test_comparison_after_breaking_hash_change():
# We simulate a breaking change in DAG hash computation in Spack. We have two specs that are
# entirely equal modulo DAG hash. When deserializing these specs, we don't want them to compare

View File

@@ -1290,7 +1290,7 @@ def test_parse_filename_missing_slash_as_spec(specfile_for, tmpdir, filename):
# make sure that only happens when the spec ends in yaml
with pytest.raises(spack.solver.asp.UnsatisfiableSpecError) as exc_info:
spack.concretize.concretize_one(SpecParser("builtin.mock.doesnotexist").next_spec())
spack.concretize.concretize_one(SpecParser("builtin_mock.doesnotexist").next_spec())
assert not exc_info.value.long_message or (
"Did you mean to specify a filename with" not in exc_info.value.long_message
)

View File

@@ -19,6 +19,8 @@ spack:
- +rocm
- amdgpu_target=gfx90a
- ~flash_attention
miopen-hip:
require: ~ck
specs:
# Horovod

View File

@@ -1,3 +1,4 @@
from spack_repo.builtin_mock.build_systems.generic import Package
from spack.package import *
class {{ cls_name }}(Package):

View File

@@ -0,0 +1,889 @@
# Copyright Spack Project Developers. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import stat
import subprocess
from typing import Callable, List, Optional, Set, Tuple, Union
import llnl.util.filesystem as fs
import llnl.util.tty as tty
import spack.build_environment
import spack.builder
import spack.compilers.libraries
import spack.error
import spack.package_base
import spack.phase_callbacks
import spack.spec
import spack.util.environment
import spack.util.prefix
from spack.directives import build_system, conflicts, depends_on
from spack.multimethod import when
from spack.operating_systems.mac_os import macos_version
from spack.util.executable import Executable
from spack.version import Version
from ._checks import (
BuilderWithDefaults,
apply_macos_rpath_fixups,
ensure_build_dependencies_or_raise,
execute_build_time_tests,
execute_install_time_tests,
)
class AutotoolsPackage(spack.package_base.PackageBase):
"""Specialized class for packages built using GNU Autotools."""
#: This attribute is used in UI queries that need to know the build
#: system base class
build_system_class = "AutotoolsPackage"
#: Legacy buildsystem attribute used to deserialize and install old specs
legacy_buildsystem = "autotools"
build_system("autotools")
with when("build_system=autotools"):
depends_on("gnuconfig", type="build", when="target=ppc64le:")
depends_on("gnuconfig", type="build", when="target=aarch64:")
depends_on("gnuconfig", type="build", when="target=riscv64:")
depends_on("gmake", type="build")
conflicts("platform=windows")
def flags_to_build_system_args(self, flags):
"""Produces a list of all command line arguments to pass specified
compiler flags to configure."""
# Has to be dynamic attribute due to caching.
setattr(self, "configure_flag_args", [])
for flag, values in flags.items():
if values:
var_name = "LIBS" if flag == "ldlibs" else flag.upper()
values_str = "{0}={1}".format(var_name, " ".join(values))
self.configure_flag_args.append(values_str)
# Spack's fflags are meant for both F77 and FC, therefore we
# additionaly set FCFLAGS if required.
values = flags.get("fflags", None)
if values:
values_str = "FCFLAGS={0}".format(" ".join(values))
self.configure_flag_args.append(values_str)
# Legacy methods (used by too many packages to change them,
# need to forward to the builder)
def enable_or_disable(self, *args, **kwargs):
return spack.builder.create(self).enable_or_disable(*args, **kwargs)
def with_or_without(self, *args, **kwargs):
return spack.builder.create(self).with_or_without(*args, **kwargs)
@spack.builder.builder("autotools")
class AutotoolsBuilder(BuilderWithDefaults):
"""The autotools builder encodes the default way of installing software built
with autotools. It has four phases that can be overridden, if need be:
1. :py:meth:`~.AutotoolsBuilder.autoreconf`
2. :py:meth:`~.AutotoolsBuilder.configure`
3. :py:meth:`~.AutotoolsBuilder.build`
4. :py:meth:`~.AutotoolsBuilder.install`
They all have sensible defaults and for many packages the only thing necessary
is to override the helper method
:meth:`~spack_repo.builtin.build_systems.autotools.AutotoolsBuilder.configure_args`.
For a finer tuning you may also override:
+-----------------------------------------------+--------------------+
| **Method** | **Purpose** |
+===============================================+====================+
| :py:attr:`~.AutotoolsBuilder.build_targets` | Specify ``make`` |
| | targets for the |
| | build phase |
+-----------------------------------------------+--------------------+
| :py:attr:`~.AutotoolsBuilder.install_targets` | Specify ``make`` |
| | targets for the |
| | install phase |
+-----------------------------------------------+--------------------+
| :py:meth:`~.AutotoolsBuilder.check` | Run build time |
| | tests if required |
+-----------------------------------------------+--------------------+
"""
#: Phases of a GNU Autotools package
phases = ("autoreconf", "configure", "build", "install")
#: Names associated with package methods in the old build-system format
legacy_methods = ("configure_args", "check", "installcheck")
#: Names associated with package attributes in the old build-system format
legacy_attributes = (
"archive_files",
"patch_libtool",
"build_targets",
"install_targets",
"build_time_test_callbacks",
"install_time_test_callbacks",
"force_autoreconf",
"autoreconf_extra_args",
"install_libtool_archives",
"patch_config_files",
"configure_directory",
"configure_abs_path",
"build_directory",
"autoreconf_search_path_args",
)
#: Whether to update ``libtool`` (e.g. for Arm/Clang/Fujitsu/NVHPC compilers)
patch_libtool = True
#: Targets for ``make`` during the :py:meth:`~.AutotoolsBuilder.build` phase
build_targets: List[str] = []
#: Targets for ``make`` during the :py:meth:`~.AutotoolsBuilder.install` phase
install_targets = ["install"]
#: Callback names for build-time test
build_time_test_callbacks = ["check"]
#: Callback names for install-time test
install_time_test_callbacks = ["installcheck"]
#: Set to true to force the autoreconf step even if configure is present
force_autoreconf = False
#: Options to be passed to autoreconf when using the default implementation
autoreconf_extra_args: List[str] = []
#: If False deletes all the .la files in the prefix folder after the installation.
#: If True instead it installs them.
install_libtool_archives = False
@property
def patch_config_files(self) -> bool:
"""Whether to update old ``config.guess`` and ``config.sub`` files
distributed with the tarball.
This currently only applies to ``ppc64le:``, ``aarch64:``, and
``riscv64`` target architectures.
The substitutes are taken from the ``gnuconfig`` package, which is
automatically added as a build dependency for these architectures. In case
system versions of these config files are required, the ``gnuconfig`` package
can be marked external, with a prefix pointing to the directory containing the
system ``config.guess`` and ``config.sub`` files.
"""
return (
self.pkg.spec.satisfies("target=ppc64le:")
or self.pkg.spec.satisfies("target=aarch64:")
or self.pkg.spec.satisfies("target=riscv64:")
)
@property
def _removed_la_files_log(self) -> str:
"""File containing the list of removed libtool archives"""
return os.path.join(self.build_directory, "removed_la_files.txt")
@property
def archive_files(self) -> List[str]:
"""Files to archive for packages based on autotools"""
files = [os.path.join(self.build_directory, "config.log")]
if not self.install_libtool_archives:
files.append(self._removed_la_files_log)
return files
@spack.phase_callbacks.run_after("autoreconf")
def _do_patch_config_files(self) -> None:
"""Some packages ship with older config.guess/config.sub files and need to
have these updated when installed on a newer architecture.
In particular, config.guess fails for PPC64LE for version prior to a
2013-06-10 build date (automake 1.13.4) and for AArch64 and RISC-V.
"""
if not self.patch_config_files:
return
# TODO: Expand this to select the 'config.sub'-compatible architecture
# for each platform (e.g. 'config.sub' doesn't accept 'power9le', but
# does accept 'ppc64le').
if self.pkg.spec.satisfies("target=ppc64le:"):
config_arch = "ppc64le"
elif self.pkg.spec.satisfies("target=aarch64:"):
config_arch = "aarch64"
elif self.pkg.spec.satisfies("target=riscv64:"):
config_arch = "riscv64"
else:
config_arch = "local"
def runs_ok(script_abs_path):
# Construct the list of arguments for the call
additional_args = {"config.sub": [config_arch]}
script_name = os.path.basename(script_abs_path)
args = [script_abs_path] + additional_args.get(script_name, [])
try:
subprocess.check_call(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except Exception as e:
tty.debug(e)
return False
return True
# Get the list of files that needs to be patched
to_be_patched = fs.find(self.pkg.stage.path, files=["config.sub", "config.guess"])
to_be_patched = [f for f in to_be_patched if not runs_ok(f)]
# If there are no files to be patched, return early
if not to_be_patched:
return
# Otherwise, require `gnuconfig` to be a build dependency
ensure_build_dependencies_or_raise(
spec=self.pkg.spec, dependencies=["gnuconfig"], error_msg="Cannot patch config files"
)
# Get the config files we need to patch (config.sub / config.guess).
to_be_found = list(set(os.path.basename(f) for f in to_be_patched))
gnuconfig = self.pkg.spec["gnuconfig"]
gnuconfig_dir = gnuconfig.prefix
# An external gnuconfig may not not have a prefix.
if gnuconfig_dir is None:
raise spack.error.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`."
)
candidates = fs.find(gnuconfig_dir, files=to_be_found, recursive=False)
# For external packages the user may have specified an incorrect prefix.
# otherwise the installation is just corrupt.
if not candidates:
msg = (
"Spack could not find `config.guess` and `config.sub` "
"files in the `gnuconfig` prefix `{0}`. This means the "
"`gnuconfig` package is broken"
).format(gnuconfig_dir)
if gnuconfig.external:
msg += (
" or the `gnuconfig` package prefix is misconfigured as" " an external package"
)
raise spack.error.InstallError(msg)
# Filter working substitutes
candidates = [f for f in candidates if runs_ok(f)]
substitutes = {}
for candidate in candidates:
config_file = os.path.basename(candidate)
substitutes[config_file] = candidate
to_be_found.remove(config_file)
# Check that we found everything we needed
if to_be_found:
msg = """\
Spack could not find working replacements for the following autotools config
files: {0}.
To resolve this problem, please try the following:
1. Try to rebuild with `patch_config_files = False` in the package `{1}`, to
rule out that Spack tries to replace config files not used by the build.
2. Verify that the `gnuconfig` package is up-to-date.
3. On some systems you need to use system-provided `config.guess` and `config.sub`
files. In this case, mark `gnuconfig` as an non-buildable external package,
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.pkg.name))
# Copy the good files over the bad ones
for abs_path in to_be_patched:
name = os.path.basename(abs_path)
mode = os.stat(abs_path).st_mode
os.chmod(abs_path, stat.S_IWUSR)
fs.copy(substitutes[name], abs_path)
os.chmod(abs_path, mode)
@spack.phase_callbacks.run_before("configure")
def _patch_usr_bin_file(self) -> None:
"""On NixOS file is not available in /usr/bin/file. Patch configure
scripts to use file from path."""
if self.spec.os.startswith("nixos"):
x = fs.FileFilter(
*filter(fs.is_exe, fs.find(self.build_directory, "configure", recursive=True))
)
with fs.keep_modification_time(*x.filenames):
x.filter(regex="/usr/bin/file", repl="file", string=True)
@spack.phase_callbacks.run_before("configure")
def _set_autotools_environment_variables(self) -> None:
"""Many autotools builds use a version of mknod.m4 that fails when
running as root unless FORCE_UNSAFE_CONFIGURE is set to 1.
We set this to 1 and expect the user to take responsibility if
they are running as root. They have to anyway, as this variable
doesn't actually prevent configure from doing bad things as root.
Without it, configure just fails halfway through, but it can
still run things *before* this check. Forcing this just removes a
nuisance -- this is not circumventing any real protection.
"""
os.environ["FORCE_UNSAFE_CONFIGURE"] = "1"
@spack.phase_callbacks.run_before("configure")
def _do_patch_libtool_configure(self) -> None:
"""Patch bugs that propagate from libtool macros into "configure" and
further into "libtool". Note that patches that can be fixed by patching
"libtool" directly should be implemented in the _do_patch_libtool method
below."""
# Exit early if we are required not to patch libtool-related problems:
if not self.patch_libtool:
return
x = fs.FileFilter(
*filter(fs.is_exe, fs.find(self.build_directory, "configure", recursive=True))
)
# There are distributed automatically generated files that depend on the configure script
# and require additional tools for rebuilding.
# See https://github.com/spack/spack/pull/30768#issuecomment-1219329860
with fs.keep_modification_time(*x.filenames):
# Fix parsing of compiler output when collecting predeps and postdeps
# https://lists.gnu.org/archive/html/bug-libtool/2016-03/msg00003.html
x.filter(regex=r'^(\s*if test x-L = )("\$p" \|\|\s*)$', repl=r"\1x\2")
x.filter(
regex=r'^(\s*test x-R = )("\$p")(; then\s*)$', repl=r'\1x\2 || test x-l = x"$p"\3'
)
# Support Libtool 2.4.2 and older:
x.filter(regex=r'^(\s*test \$p = "-R")(; then\s*)$', repl=r'\1 || test x-l = x"$p"\2')
# Configure scripts generated with libtool < 2.5.4 have a faulty test for the
# -single_module linker flag. A deprecation warning makes it think the default is
# -multi_module, triggering it to use problematic linker flags (such as ld -r). The
# linker default is `-single_module` from (ancient) macOS 10.4, so override by setting
# `lt_cv_apple_cc_single_mod=yes`. See the fix in libtool commit
# 82f7f52123e4e7e50721049f7fa6f9b870e09c9d.
x.filter("lt_cv_apple_cc_single_mod=no", "lt_cv_apple_cc_single_mod=yes", string=True)
@spack.phase_callbacks.run_after("configure")
def _do_patch_libtool(self) -> None:
"""If configure generates a "libtool" script that does not correctly
detect the compiler (and patch_libtool is set), patch in the correct
values for libtool variables.
The generated libtool script supports mixed compilers through tags:
``libtool --tag=CC/CXX/FC/...```. For each tag there is a block with variables,
which defines what flags to pass to the compiler. The default variables (which
are used by the default tag CC) are set in a block enclosed by
``# ### {BEGIN,END} LIBTOOL CONFIG``. For non-default tags, there are
corresponding blocks ``# ### {BEGIN,END} LIBTOOL TAG CONFIG: {CXX,FC,F77}`` at
the end of the file (after the exit command). libtool evals these blocks.
Whenever we need to update variables that the configure script got wrong
(for example cause it did not recognize the compiler), we should properly scope
those changes to these tags/blocks so they only apply to the compiler we care
about. Below, ``start_at`` and ``stop_at`` are used for that."""
# Exit early if we are required not to patch libtool:
if not self.patch_libtool:
return
x = fs.FileFilter(
*filter(fs.is_exe, fs.find(self.build_directory, "libtool", recursive=True))
)
# Exit early if there is nothing to patch:
if not x.filenames:
return
markers = {"cc": "LIBTOOL CONFIG"}
for tag in ["cxx", "fc", "f77"]:
markers[tag] = "LIBTOOL TAG CONFIG: {0}".format(tag.upper())
# Replace empty linker flag prefixes:
if self.spec.satisfies("%nag"):
# Nag is mixed with gcc and g++, which are recognized correctly.
# Therefore, we change only Fortran values:
nag_pkg = self.spec["fortran"].package
for tag in ["fc", "f77"]:
marker = markers[tag]
x.filter(
regex='^wl=""$',
repl=f'wl="{nag_pkg.linker_arg}"',
start_at=f"# ### BEGIN {marker}",
stop_at=f"# ### END {marker}",
)
else:
compiler_spec = spack.compilers.libraries.compiler_spec(self.spec)
if compiler_spec:
x.filter(regex='^wl=""$', repl='wl="{0}"'.format(compiler_spec.package.linker_arg))
# Replace empty PIC flag values:
for compiler, marker in markers.items():
if compiler == "cc":
language = "c"
elif compiler == "cxx":
language = "cxx"
else:
language = "fortran"
if language not in self.spec:
continue
x.filter(
regex='^pic_flag=""$',
repl=f'pic_flag="{self.spec[language].package.pic_flag}"',
start_at=f"# ### BEGIN {marker}",
stop_at=f"# ### END {marker}",
)
# Other compiler-specific patches:
if self.spec.satisfies("%fj"):
x.filter(regex="-nostdlib", repl="", string=True)
rehead = r"/\S*/"
for o in [
r"fjhpctag\.o",
r"fjcrt0\.o",
r"fjlang08\.o",
r"fjomp\.o",
r"crti\.o",
r"crtbeginS\.o",
r"crtendS\.o",
]:
x.filter(regex=(rehead + o), repl="")
elif self.spec.satisfies("%nag"):
for tag in ["fc", "f77"]:
marker = markers[tag]
start_at = "# ### BEGIN {0}".format(marker)
stop_at = "# ### END {0}".format(marker)
# Libtool 2.4.2 does not know the shared flag:
x.filter(
regex=r"\$CC -shared",
repl=r"\$CC -Wl,-shared",
string=True,
start_at=start_at,
stop_at=stop_at,
)
# Libtool does not know how to inject whole archives
# (e.g. https://github.com/pmodels/mpich/issues/4358):
x.filter(
regex=r'^whole_archive_flag_spec="\\\$({?wl}?)--whole-archive'
r'\\\$convenience \\\$\1--no-whole-archive"$',
repl=r'whole_archive_flag_spec="\$\1--whole-archive'
r"\`for conv in \$convenience\\\\\"\\\\\"; do test -n \\\\\"\$conv\\\\\" && "
r"new_convenience=\\\\\"\$new_convenience,\$conv\\\\\"; done; "
r'func_echo_all \\\\\"\$new_convenience\\\\\"\` \$\1--no-whole-archive"',
start_at=start_at,
stop_at=stop_at,
)
# The compiler requires special treatment in certain cases:
x.filter(
regex=r"^(with_gcc=.*)$",
repl="\\1\n\n# Is the compiler the NAG compiler?\nwith_nag=yes",
start_at=start_at,
stop_at=stop_at,
)
# Disable the special treatment for gcc and g++:
for tag in ["cc", "cxx"]:
marker = markers[tag]
x.filter(
regex=r"^(with_gcc=.*)$",
repl="\\1\n\n# Is the compiler the NAG compiler?\nwith_nag=no",
start_at="# ### BEGIN {0}".format(marker),
stop_at="# ### END {0}".format(marker),
)
# The compiler does not support -pthread flag, which might come
# from the inherited linker flags. We prepend the flag with -Wl,
# before using it:
x.filter(
regex=r"^(\s*)(for tmp_inherited_linker_flag in \$tmp_inherited_linker_flags; "
r"do\s*)$",
repl='\\1if test "x$with_nag" = xyes; then\n'
"\\1 revert_nag_pthread=$tmp_inherited_linker_flags\n"
"\\1 tmp_inherited_linker_flags="
"`$ECHO \"$tmp_inherited_linker_flags\" | $SED 's% -pthread% -Wl,-pthread%g'`\n"
'\\1 test x"$revert_nag_pthread" = x"$tmp_inherited_linker_flags" && '
"revert_nag_pthread=no || revert_nag_pthread=yes\n"
"\\1fi\n\\1\\2",
start_at='if test -n "$inherited_linker_flags"; then',
stop_at='case " $new_inherited_linker_flags " in',
)
# And revert the modification to produce '*.la' files that can be
# used with gcc (normally, we do not install the files but they can
# still be used during the building):
start_at = '# Time to change all our "foo.ltframework" stuff back to "-framework foo"'
stop_at = "# installed libraries to the beginning of the library search list"
x.filter(
regex=r"(\s*)(# move library search paths that coincide with paths to not "
r"yet\s*)$",
repl='\\1test x"$with_nag$revert_nag_pthread" = xyesyes &&\n'
'\\1 new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | '
"$SED 's% -Wl,-pthread% -pthread%g'`\n\\1\\2",
start_at=start_at,
stop_at=stop_at,
)
@property
def configure_directory(self) -> str:
"""Return the directory where 'configure' resides."""
return self.pkg.stage.source_path
@property
def configure_abs_path(self) -> str:
# Absolute path to configure
configure_abs_path = os.path.join(os.path.abspath(self.configure_directory), "configure")
return configure_abs_path
@property
def build_directory(self) -> str:
"""Override to provide another place to build the package"""
# Handle the case where the configure directory is set to a non-absolute path
# Non-absolute paths are always relative to the staging source path
build_dir = self.configure_directory
if not os.path.isabs(build_dir):
build_dir = os.path.join(self.pkg.stage.source_path, build_dir)
return build_dir
@spack.phase_callbacks.run_before("autoreconf")
def _delete_configure_to_force_update(self) -> None:
if self.force_autoreconf:
fs.force_remove(self.configure_abs_path)
@property
def autoreconf_search_path_args(self) -> List[str]:
"""Search path includes for autoreconf. Add an -I flag for all `aclocal` dirs
of build deps, skips the default path of automake, move external include
flags to the back, since they might pull in unrelated m4 files shadowing
spack dependencies."""
return _autoreconf_search_path_args(self.spec)
@spack.phase_callbacks.run_after("autoreconf")
def _set_configure_or_die(self) -> None:
"""Ensure the presence of a "configure" script, or raise. If the "configure"
is found, a module level attribute is set.
Raises:
RuntimeError: if the "configure" script is not found
"""
# Check if the "configure" script is there. If not raise a RuntimeError.
if not os.path.exists(self.configure_abs_path):
msg = "configure script not found in {0}"
raise RuntimeError(msg.format(self.configure_directory))
# Monkey-patch the configure script in the corresponding module
globals_for_pkg = spack.build_environment.ModuleChangePropagator(self.pkg)
globals_for_pkg.configure = Executable(self.configure_abs_path)
globals_for_pkg.propagate_changes_to_mro()
def configure_args(self) -> List[str]:
"""Return the list of all the arguments that must be passed to configure,
except ``--prefix`` which will be pre-pended to the list.
"""
return []
def autoreconf(
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Not needed usually, configure should be already there"""
# If configure exists nothing needs to be done
if os.path.exists(self.configure_abs_path):
return
# Else try to regenerate it, which requires a few build dependencies
ensure_build_dependencies_or_raise(
spec=spec,
dependencies=["autoconf", "automake", "libtool"],
error_msg="Cannot generate configure",
)
tty.msg("Configure script not found: trying to generate it")
tty.warn("*********************************************************")
tty.warn("* If the default procedure fails, consider implementing *")
tty.warn("* a custom AUTORECONF phase in the package *")
tty.warn("*********************************************************")
with fs.working_dir(self.configure_directory):
# This line is what is needed most of the time
# --install, --verbose, --force
autoreconf_args = ["-ivf"]
autoreconf_args += self.autoreconf_search_path_args
autoreconf_args += self.autoreconf_extra_args
self.pkg.module.autoreconf(*autoreconf_args)
def configure(
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "configure", with the arguments specified by the builder and an
appropriately set prefix.
"""
options = getattr(self.pkg, "configure_flag_args", [])
options += ["--prefix={0}".format(prefix)]
options += self.configure_args()
with fs.working_dir(self.build_directory, create=True):
pkg.module.configure(*options)
def build(
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "make" on the build targets specified by the builder."""
# See https://autotools.io/automake/silent.html
params = ["V=1"]
params += self.build_targets
with fs.working_dir(self.build_directory):
pkg.module.make(*params)
def install(
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "make" on the install targets specified by the builder."""
with fs.working_dir(self.build_directory):
pkg.module.make(*self.install_targets)
spack.phase_callbacks.run_after("build")(execute_build_time_tests)
def check(self) -> None:
"""Run "make" on the ``test`` and ``check`` targets, if found."""
with fs.working_dir(self.build_directory):
self.pkg._if_make_target_execute("test")
self.pkg._if_make_target_execute("check")
def _activate_or_not(
self,
name: str,
activation_word: str,
deactivation_word: str,
activation_value: Optional[Union[Callable, str]] = None,
variant=None,
) -> List[str]:
"""This function contain the current implementation details of
:meth:`~spack_repo.builtin.build_systems.autotools.AutotoolsBuilder.with_or_without` and
:meth:`~spack_repo.builtin.build_systems.autotools.AutotoolsBuilder.enable_or_disable`.
Args:
name: name of the option that is being activated or not
activation_word: the default activation word ('with' in the case of
``with_or_without``)
deactivation_word: the default deactivation word ('without' in the case of
``with_or_without``)
activation_value: callable that accepts a single value. This value is either one of the
allowed values for a multi-valued variant or the name of a bool-valued variant.
Returns the parameter to be used when the value is activated.
The special value "prefix" can also be assigned and will return
``spec[name].prefix`` as activation parameter.
variant: name of the variant that is being processed (if different from option name)
Examples:
Given a package with:
.. code-block:: python
variant("foo", values=("x", "y"), description=")
variant("bar", default=True, description=")
variant("ba_z", default=True, description=")
calling this function like:
.. code-block:: python
_activate_or_not(
"foo", "with", "without", activation_value="prefix"
)
_activate_or_not("bar", "with", "without")
_activate_or_not("ba-z", "with", "without", variant="ba_z")
will generate the following configuration options:
.. code-block:: console
--with-x=<prefix-to-x> --without-y --with-bar --with-ba-z
for ``<spec-name> foo=x +bar``
Note: returns an empty list when the variant is conditional and its condition
is not met.
Returns:
list: list of strings that corresponds to the activation/deactivation
of the variant that has been processed
Raises:
KeyError: if name is not among known variants
"""
spec: spack.spec.Spec = self.pkg.spec
args: List[str] = []
if activation_value == "prefix":
activation_value = lambda x: spec[x].prefix
variant = variant or name
# Defensively look that the name passed as argument is among variants
if not self.pkg.has_variant(variant):
msg = '"{0}" is not a variant of "{1}"'
raise KeyError(msg.format(variant, self.pkg.name))
if variant not in spec.variants:
return []
# 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)): # type: ignore
# 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)]
else:
# "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 = [(v, f"{variant}={v}" in spec) for v in feature_values] # type: ignore
# For each allowed value in the list of values
for option_value, activated in options:
# Search for an override in the package for this value
override_name = f"{activation_word}_or_{deactivation_word}_{option_value}"
line_generator = getattr(self, override_name, None) or getattr(
self.pkg, override_name, None
)
# If not available use a sensible default
if line_generator is None:
def _default_generator(is_activated):
if is_activated:
line = f"--{activation_word}-{option_value}"
if activation_value is not None and activation_value(
option_value
): # NOQA=ignore=E501
line = f"{line}={activation_value(option_value)}"
return line
return f"--{deactivation_word}-{option_value}"
line_generator = _default_generator
args.append(line_generator(activated))
return args
def with_or_without(
self,
name: str,
activation_value: Optional[Union[Callable, str]] = None,
variant: Optional[str] = None,
) -> List[str]:
"""Inspects a variant and returns the arguments that activate
or deactivate the selected feature(s) for the configure options.
This function works on all type of variants. For bool-valued variants
it will return by default ``--with-{name}`` or ``--without-{name}``.
For other kinds of variants it will cycle over the allowed values and
return either ``--with-{value}`` or ``--without-{value}``.
If activation_value is given, then for each possible value of the
variant, the option ``--with-{value}=activation_value(value)`` or
``--without-{value}`` will be added depending on whether or not
``variant=value`` is in the spec.
Args:
name: name of a valid multi-valued variant
activation_value: callable that accepts a single value and returns the parameter to be
used leading to an entry of the type ``--with-{name}={parameter}``.
The special value "prefix" can also be assigned and will return
``spec[name].prefix`` as activation parameter.
Returns:
list of arguments to configure
"""
return self._activate_or_not(name, "with", "without", activation_value, variant)
def enable_or_disable(
self,
name: str,
activation_value: Optional[Union[Callable, str]] = None,
variant: Optional[str] = None,
) -> List[str]:
"""Same as
:meth:`~spack_repo.builtin.build_systems.autotools.AutotoolsBuilder.with_or_without`
but substitute ``with`` with ``enable`` and ``without`` with ``disable``.
Args:
name: name of a valid multi-valued variant
activation_value: if present accepts a single value and returns the parameter to be
used leading to an entry of the type ``--enable-{name}={parameter}``
The special value "prefix" can also be assigned and will return
``spec[name].prefix`` as activation parameter.
Returns:
list of arguments to configure
"""
return self._activate_or_not(name, "enable", "disable", activation_value, variant)
spack.phase_callbacks.run_after("install")(execute_install_time_tests)
def installcheck(self) -> None:
"""Run "make" on the ``installcheck`` target, if found."""
with fs.working_dir(self.build_directory):
self.pkg._if_make_target_execute("installcheck")
@spack.phase_callbacks.run_after("install")
def _remove_libtool_archives(self) -> None:
"""Remove all .la files in prefix sub-folders if the package sets
``install_libtool_archives`` to be False.
"""
# If .la files are to be installed there's nothing to do
if self.install_libtool_archives:
return
# Remove the files and create a log of what was removed
libtool_files = fs.find(str(self.pkg.prefix), "*.la", recursive=True)
with fs.safe_remove(*libtool_files):
fs.mkdirp(os.path.dirname(self._removed_la_files_log))
with open(self._removed_la_files_log, mode="w", encoding="utf-8") as f:
f.write("\n".join(libtool_files))
def setup_build_environment(
self, env: spack.util.environment.EnvironmentModifications
) -> None:
if self.spec.platform == "darwin" and macos_version() >= Version("11"):
# Many configure files rely on matching '10.*' for macOS version
# detection and fail to add flags if it shows as version 11.
env.set("MACOSX_DEPLOYMENT_TARGET", "10.16")
# On macOS, force rpaths for shared library IDs and remove duplicate rpaths
spack.phase_callbacks.run_after("install", when="platform=darwin")(apply_macos_rpath_fixups)
def _autoreconf_search_path_args(spec: spack.spec.Spec) -> List[str]:
dirs_seen: Set[Tuple[int, int]] = set()
flags_spack: List[str] = []
flags_external: List[str] = []
# We don't want to add an include flag for automake's default search path.
for automake in spec.dependencies(name="automake", deptype="build"):
try:
s = os.stat(automake.prefix.share.aclocal)
if stat.S_ISDIR(s.st_mode):
dirs_seen.add((s.st_ino, s.st_dev))
except OSError:
pass
for dep in spec.dependencies(deptype="build"):
path = dep.prefix.share.aclocal
# Skip non-existing aclocal paths
try:
s = os.stat(path)
except OSError:
continue
# Skip things seen before, as well as non-dirs.
if (s.st_ino, s.st_dev) in dirs_seen or not stat.S_ISDIR(s.st_mode):
continue
dirs_seen.add((s.st_ino, s.st_dev))
flags = flags_external if dep.external else flags_spack
flags.extend(["-I", path])
return flags_spack + flags_external

View File

@@ -24,6 +24,10 @@ class MSBuildPackage(spack.package_base.PackageBase):
build_system("msbuild")
conflicts("platform=linux", when="build_system=msbuild")
conflicts("platform=darwin", when="build_system=msbuild")
conflicts("platform=freebsd", when="build_system=msbuild")
def define(self, msbuild_arg, value):
return define(msbuild_arg, value)
@spack.builder.builder("msbuild")
@@ -87,7 +91,7 @@ def define_targets(self, *targets):
return "/target:" + ";".join(targets) if targets else ""
def define(self, msbuild_arg, value):
return "/p:{}={}".format(msbuild_arg, value)
return define(msbuild_arg, value)
def msbuild_args(self):
"""Define build arguments to MSbuild. This is an empty list by default.
@@ -121,3 +125,7 @@ def install(
pkg.module.msbuild(
*self.msbuild_install_args(), self.define_targets(*self.install_targets)
)
def define(msbuild_arg, value):
return "/p:{}={}".format(msbuild_arg, value)

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