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
This commit is contained in:
parent
e8c5f195a7
commit
8f5fcc6e95
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1186,22 +1186,27 @@ def extendee_spec(self):
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user