summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Scogland <scogland1@llnl.gov>2022-02-16 13:23:12 -0800
committerGitHub <noreply@github.com>2022-02-16 21:23:12 +0000
commit8f5fcc6e95745dd18c978396d79f028d83a62a20 (patch)
tree3dd59318f810c70c7c9179fe41514c0050c75220 /lib
parente8c5f195a788ea0d7437272983d6c99e19d5b150 (diff)
downloadspack-8f5fcc6e95745dd18c978396d79f028d83a62a20.tar.gz
spack-8f5fcc6e95745dd18c978396d79f028d83a62a20.tar.bz2
spack-8f5fcc6e95745dd18c978396d79f028d83a62a20.tar.xz
spack-8f5fcc6e95745dd18c978396d79f028d83a62a20.zip
extensions: allow multiple "extends" directives (#28853)
* extensions: allow multiple "extends" directives This will allow multiple extends directives in a package as long as only one of them is selected as a dependency in the concrete spec. * document the option to have multiple extends
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/docs/packaging_guide.rst18
-rw-r--r--lib/spack/spack/package.py15
2 files changed, 28 insertions, 5 deletions
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst
index 293e83a118..bdf557a346 100644
--- a/lib/spack/docs/packaging_guide.rst
+++ b/lib/spack/docs/packaging_guide.rst
@@ -2470,6 +2470,24 @@ Now, the ``py-numpy`` package can be used as an argument to ``spack
activate``. When it is activated, all the files in its prefix will be
symbolically linked into the prefix of the python package.
+A package can only extend one other package at a time. To support packages
+that may extend one of a list of other packages, Spack supports multiple
+``extends`` directives as long as at most one of them is selected as
+a dependency during concretization. For example, a lua package could extend
+either lua or luajit, but not both:
+
+.. code-block:: python
+
+ class LuaLpeg(Package):
+ ...
+ variant('use_lua', default=True)
+ extends('lua', when='+use_lua')
+ extends('lua-luajit', when='~use_lua')
+ ...
+
+Now, a user can install, and activate, the ``lua-lpeg`` package for either
+lua or luajit.
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Adding additional constraints
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index d3e1bdc002..447e7a9d46 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -1186,22 +1186,27 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
if not self.extendees:
return None
- # TODO: allow more than one extendee.
- name = next(iter(self.extendees))
+ deps = []
# If the extendee is in the spec's deps already, return that.
for dep in self.spec.traverse(deptypes=('link', 'run')):
- if name == dep.name:
- return dep
+ if dep.name in self.extendees:
+ deps.append(dep)
+
+ # TODO: allow more than one active extendee.
+ if deps:
+ assert len(deps) == 1
+ return deps[0]
# if the spec is concrete already, then it extends something
# that is an *optional* dependency, and the dep isn't there.
if self.spec._concrete:
return None
else:
+ # TODO: do something sane here with more than one extendee
# If it's not concrete, then return the spec from the
# extends() directive since that is all we know so far.
- spec, kwargs = self.extendees[name]
+ spec, kwargs = next(iter(self.extendees.items()))
return spec
@property