[!19] Introduce variant dependency
Merge branch 'feature/variant-dependencies' into 'master' ref:spack/dune-spack\> The previous approach had the big downside of bypassing the specified variants through the specified dependencies of variants. E.g. dune+pdelab~functions would silently ignore the ~functions aspect, because +pdelab enforces the installation of dune-functions. This introduces even more subtle bugs as more Dune modules are added to the package as any Dune-module-dependent logic in the package needs to be duplicated for each Dune module that depends on the module that originally introduced that logic (yuck!). There is no direct mechanism in Spack to specify such dependencies in a way that enforces the correct variants on dependent modules. I have now added conflicts between variants that reflect the Dune module dependencies. In that case dune+pdelab~functions would throw an error. This comes at the cost that a command such as spack install dune+pdelab is not possible anymore. Instead the user needs to specify the dependent modules as well: spack install dune+pdelab+functions+typetree Note that in order to remove some burden from users, I removed the variants for the core modules - they are always installed. See merge request [spack/dune-spack!19] [spack/dune-spack!19]: gitlab.dune-project.org/spack/dune-spack/merge_requests/19
This commit is contained in:
commit
ce341af06e
|
@ -41,6 +41,58 @@ class Dune(CMakePackage):
|
|||
("master" , "master"),
|
||||
]
|
||||
|
||||
# This defines the mapping of the variant names for Dune modules and the
|
||||
# resource names that we assign later on.
|
||||
dune_variants_to_resources = {
|
||||
'alugrid' : 'dune-alugrid',
|
||||
'codegen' : 'dune-codegen',
|
||||
'fem' : 'dune-fem',
|
||||
'foamgrid' : 'dune-foamgrid',
|
||||
'functions': 'dune-functions',
|
||||
'gridglue' : 'dune-grid-glue',
|
||||
'multidomaingrid' : 'dune-multidomaingrid',
|
||||
'pdelab' : 'dune-pdelab',
|
||||
'polygongrid' : 'dune-polygongrid',
|
||||
'spgrid' : 'dune-spgrid',
|
||||
'testtools' : 'dune-testtools',
|
||||
'typetree' : 'dune-typetree',
|
||||
'uggrid' : 'dune-uggrid',
|
||||
}
|
||||
|
||||
# Define the inverse mapping
|
||||
dune_resources_to_variants = {v: k for k, v in dune_variants_to_resources.items()}
|
||||
|
||||
# Dependencies between modules - not necessarily the full set
|
||||
# as the closure of module dependencies is built later on.
|
||||
# dune-common does not need to be named.
|
||||
module_dependencies = {
|
||||
'dune-alugrid': ['dune-grid'],
|
||||
'dune-codegen': ['dune-pdelab', 'dune-testtools', 'dune-alugrid'],
|
||||
'dune-fem': ['dune-grid'],
|
||||
'dune-fempy': ['dune-fem'],
|
||||
'dune-foamgrid': ['dune-grid'],
|
||||
'dune-functions': ["dune-grid", "dune-typetree", "dune-localfunctions", "dune-istl"],
|
||||
'dune-grid': ['dune-geometry'],
|
||||
'dune-grid-glue': ['dune-grid'],
|
||||
'dune-localfunctions': ['dune-geometry'],
|
||||
'dune-multidomaingrid': ['dune-grid', 'dune-typetree'],
|
||||
'dune-pdelab': ['dune-istl', 'dune-functions'],
|
||||
'dune-polygongrid': ['dune-grid'],
|
||||
}
|
||||
|
||||
# Build the closure of above module dependency list
|
||||
for module in module_dependencies:
|
||||
closure = set(module_dependencies[module])
|
||||
old_closure = set()
|
||||
while (len(closure) > len(old_closure)):
|
||||
old_closure = closure.copy()
|
||||
|
||||
for res in old_closure:
|
||||
for mod in module_dependencies.get(res, []):
|
||||
closure.add(mod)
|
||||
|
||||
module_dependencies[module] = list(closure)
|
||||
|
||||
# Variants for the general build process
|
||||
variant('shared', default=True, description='Enables the build of shared libraries.')
|
||||
|
||||
|
@ -68,25 +120,16 @@ class Dune(CMakePackage):
|
|||
# Some variants that were here that are on my todo list
|
||||
# variant('jupyter', default=False, description='Build with Jupyter support')
|
||||
|
||||
# Define one variant for each Dune module that we have. Only core modules
|
||||
# are activated by default.
|
||||
variant('alugrid', default=False, description='Build with dune-alugrid module')
|
||||
variant('codegen', default=False, description='Build with dune-codegen module')
|
||||
variant('fem', default=False, description='Build with dune-fem(py) module')
|
||||
variant('foamgrid', default=False, description='Build with dune-foamgrid module')
|
||||
variant('functions', default=False, description='Build with dune-functions module')
|
||||
variant('geometry', default=True, description='Build with dune-geometry module')
|
||||
variant('grid', default=True, description='Build with dune-grid module')
|
||||
variant('gridglue', default=False, description='Build with dune-grid-glue module')
|
||||
variant('istl', default=True, description='Build with dune-istl module')
|
||||
variant('localfunctions', default=True, description='Build with dune-localfunctions module')
|
||||
variant('multidomaingrid', default=False, description='Build with dune-multidomaingrid module')
|
||||
variant('pdelab', default=False, description='Build with dune-pdelab module')
|
||||
variant('polygongrid', default=False, description='Build with dune-polygongrid module')
|
||||
variant('spgrid', default=False, description='Build with dune-spgrid module')
|
||||
variant('testtools', default=False, description='Build with dune-testtools module')
|
||||
variant('typetree', default=False, description='Build with dune-typetree module')
|
||||
variant('uggrid', default=False, description='Build with dune-uggrid module')
|
||||
# Define one variant for each non-core Dune module that we have.
|
||||
for var, res in dune_variants_to_resources.items():
|
||||
variant(var, default=False, description='Build with the %s module' % res)
|
||||
|
||||
# Define conflicts between Dune module variants. These conflicts are of the following type:
|
||||
# conflicts('dune~functions', when='+pdelab') -> dune-pdelab cannot be built without dune-functions
|
||||
for var, res in dune_variants_to_resources.items():
|
||||
for dep in module_dependencies.get(res, []):
|
||||
if dep in dune_resources_to_variants:
|
||||
conflicts('dune~%s' % dune_resources_to_variants[dep], when='+%s' % var)
|
||||
|
||||
# Iterate over all available Dune versions and define resources for all Dune modules
|
||||
# If a Dune module behaves differently for different versions (e.g. dune-python got
|
||||
|
@ -98,28 +141,28 @@ class Dune(CMakePackage):
|
|||
name='dune-geometry',
|
||||
git='https://gitlab.dune-project.org/core/dune-geometry.git',
|
||||
branch=branch,
|
||||
when='@%s+geometry' % vers,
|
||||
when='@%s' % vers,
|
||||
)
|
||||
|
||||
resource(
|
||||
name='dune-grid',
|
||||
git='https://gitlab.dune-project.org/core/dune-grid.git',
|
||||
branch=branch,
|
||||
when='@%s+grid' % vers,
|
||||
when='@%s' % vers,
|
||||
)
|
||||
|
||||
resource(
|
||||
name='dune-istl',
|
||||
git='https://gitlab.dune-project.org/core/dune-istl.git',
|
||||
branch=branch,
|
||||
when='@%s+istl' % vers,
|
||||
when='@%s' % vers,
|
||||
)
|
||||
|
||||
resource(
|
||||
name='dune-localfunctions',
|
||||
git='https://gitlab.dune-project.org/core/dune-localfunctions.git',
|
||||
branch=branch,
|
||||
when='@%s+localfunctions' % vers,
|
||||
when='@%s' % vers,
|
||||
)
|
||||
|
||||
resource(
|
||||
|
@ -232,29 +275,7 @@ class Dune(CMakePackage):
|
|||
submodules=True,
|
||||
)
|
||||
|
||||
# Dependencies between modules - not necessarily the full set
|
||||
# as the closure of module dependencies is built later on.
|
||||
module_dependencies = {}
|
||||
module_dependencies["dune-alugrid"] = ["dune-grid", "dune-geometry", "dune-common"]
|
||||
module_dependencies["dune-codegen"] = ["dune-pdelab", "dune-testtools", "dune-alugrid"]
|
||||
module_dependencies["dune-common"] = []
|
||||
module_dependencies["dune-fem"] = ["dune-grid"]
|
||||
module_dependencies["fune-fempy"] = ["dune-fem"]
|
||||
module_dependencies["dune-foamgrid"] = ["dune-grid"]
|
||||
module_dependencies["dune-functions"] = ["dune-grid", "dune-typetree", "dune-localfunctions", "dune-istl"]
|
||||
module_dependencies["dune-geometry"] = ["dune-common"]
|
||||
module_dependencies["dune-grid"] = ["dune-common", "dune-geometry"]
|
||||
module_dependencies["dune-grid-glue"] = ["dune-grid"]
|
||||
module_dependencies["dune-istl"] = ["dune-common"]
|
||||
module_dependencies["dune-localfunctions"] = ["dune-common", "dune-geometry"]
|
||||
module_dependencies["dune-multidomaingrid"] = ["dune-grid", "dune-typetree"]
|
||||
module_dependencies["dune-pdelab"] = ["dune-common", "dune-grid", "dune-istl", "dune-functions"]
|
||||
module_dependencies["dune-polygongrid"] = ["dune-grid"]
|
||||
module_dependencies["dune-python"] = ["dune-common"]
|
||||
module_dependencies["dune-testtools"] = ["dune-common"]
|
||||
module_dependencies["dune-typetree"] = ["dune-common"]
|
||||
module_dependencies["dune-uggrid"] = ["dune-common"]
|
||||
|
||||
# Make sure that Python components integrate well into Spack
|
||||
extends('python')
|
||||
python_components = [ 'dune' ]
|
||||
|
||||
|
@ -280,13 +301,9 @@ class Dune(CMakePackage):
|
|||
depends_on('python@3.0:', type=('build', 'run'))
|
||||
depends_on('py-setuptools', type='build', when='+python')
|
||||
depends_on('py-numpy', type=('build', 'run'), when='+python')
|
||||
depends_on('py-pip', type=('build', 'run'), when='+codegen')
|
||||
depends_on('py-pip', type=('build', 'run'), when='+python')
|
||||
depends_on('py-pip', type=('build', 'run'), when='+testtools')
|
||||
depends_on('py-pip', type=('build', 'run'))
|
||||
depends_on('py-sphinx', type=('build', 'run'), when='+doc')
|
||||
depends_on('py-wheel', type='build', when='+codegen')
|
||||
depends_on('py-wheel', type='build', when='+python')
|
||||
depends_on('py-wheel', type='build', when='+testtools')
|
||||
depends_on('py-wheel', type='build')
|
||||
depends_on('scotch+mpi', when='+ptscotch')
|
||||
depends_on('sionlib', when='+sionlib')
|
||||
depends_on('suite-sparse', when='+suitesparse')
|
||||
|
@ -297,9 +314,8 @@ class Dune(CMakePackage):
|
|||
|
||||
# Apply patches
|
||||
patch('virtualenv_from_envvariable.patch', when='+testtools')
|
||||
patch('virtualenv_from_envvariable.patch', when='+codegen')
|
||||
|
||||
# Some conflicts
|
||||
# Some additional variant conflicts of Dune modules and upstream dependencies
|
||||
conflicts('dune~superlu', when='+codegen')
|
||||
|
||||
def setup_build_environment(self, env):
|
||||
|
@ -356,7 +372,7 @@ class Dune(CMakePackage):
|
|||
'-DCMAKE_DISABLE_FIND_PACKAGE_ZOLTAN:BOOL=%s' % nvariant_bool('+zoltan'),
|
||||
]
|
||||
|
||||
if '+testtools' in spec or '+codegen' in spec:
|
||||
if '+testtools' in spec:
|
||||
cmake_args.append('-DDUNE_PYTHON_VIRTUALENV_SETUP:BOOL=ON')
|
||||
cmake_args.append('-DDUNE_PYTHON_ALLOW_GET_PIP:BOOL=ON')
|
||||
cmake_args.append('-DDUNE_PYTHON_VIRTUALENV_PATH:STRING="%s"' % join_path(Path.home(), '.cache', 'dune-python-env', self.spec.dag_hash()))
|
||||
|
@ -370,34 +386,6 @@ class Dune(CMakePackage):
|
|||
|
||||
return cmake_args
|
||||
|
||||
def module_dependency_closure(self, when, reslist):
|
||||
# Get a list of all modules that share the version requirement
|
||||
all_resources = []
|
||||
for w, rl in self.resources.items():
|
||||
if w.version == when.version:
|
||||
all_resources.extend(rl)
|
||||
|
||||
# And build the closure of modules from the given reslist
|
||||
closure = set(reslist)
|
||||
old_closure = set()
|
||||
while (len(closure) > len(old_closure)):
|
||||
old_closure = closure.copy()
|
||||
|
||||
for res in old_closure:
|
||||
for mod in self.module_dependencies.get(res.name, []):
|
||||
for r in all_resources:
|
||||
if r.name == mod:
|
||||
closure.add(r)
|
||||
|
||||
return list(closure)
|
||||
|
||||
def _get_needed_resources(self):
|
||||
# Modify the list of resources by building a transitive closure of Dune module dependencies.
|
||||
self.resources = {when: self.module_dependency_closure(when, reslist) for when, reslist in self.resources.items()}
|
||||
|
||||
# and call the original implementation
|
||||
return CMakePackage._get_needed_resources(self)
|
||||
|
||||
def cmake(self, spec, prefix):
|
||||
# dune-codegen delivers its own set of patches for its submodules
|
||||
# that we can apply with a script delivered by dune-codegen.
|
||||
|
|
Loading…
Reference in New Issue