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
|
activate``. When it is activated, all the files in its prefix will be
|
||||||
symbolically linked into the prefix of the python package.
|
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
|
Adding additional constraints
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -1186,22 +1186,27 @@ def extendee_spec(self):
|
|||||||
if not self.extendees:
|
if not self.extendees:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# TODO: allow more than one extendee.
|
deps = []
|
||||||
name = next(iter(self.extendees))
|
|
||||||
|
|
||||||
# If the extendee is in the spec's deps already, return that.
|
# If the extendee is in the spec's deps already, return that.
|
||||||
for dep in self.spec.traverse(deptypes=('link', 'run')):
|
for dep in self.spec.traverse(deptypes=('link', 'run')):
|
||||||
if name == dep.name:
|
if dep.name in self.extendees:
|
||||||
return dep
|
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
|
# if the spec is concrete already, then it extends something
|
||||||
# that is an *optional* dependency, and the dep isn't there.
|
# that is an *optional* dependency, and the dep isn't there.
|
||||||
if self.spec._concrete:
|
if self.spec._concrete:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
# TODO: do something sane here with more than one extendee
|
||||||
# If it's not concrete, then return the spec from the
|
# If it's not concrete, then return the spec from the
|
||||||
# extends() directive since that is all we know so far.
|
# extends() directive since that is all we know so far.
|
||||||
spec, kwargs = self.extendees[name]
|
spec, kwargs = next(iter(self.extendees.items()))
|
||||||
return spec
|
return spec
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
Loading…
Reference in New Issue
Block a user