Add support for different versions (master + 2.7) and refactor a bit

This adds a loop with versions around the resource definitions allowing
for multiple versions of the dune package with the expected behaviour
of dependency forwarding to Dune modules.

Additionally, it avoids the code duplication of _get_needed_resources:
It modifies the resource list to include the transitive closure of
Dune module dependencies and then calls the original implementation.
This commit is contained in:
Dominic Kempf 2020-05-13 18:23:24 +02:00
parent bf5d6f1e23
commit 5bc079bd0a
1 changed files with 107 additions and 113 deletions

View File

@ -24,20 +24,24 @@ import os
from spack import *
class Dune(CMakePackage):
"""
DUNE, the Distributed and Unified Numerics Environment is a modular toolbox for solving partial differential equations (PDEs) with grid-based methods.
"""
homepage = "https://www.dune-project.org"
url = "https://www.dune-project.org/download/2.7.0/dune-common-2.7.0.tar.gz"
list_url = "https://www.dune-project.org/download/"
list_depth = 1
git = "https://gitlab.dune-project.org/core/dune-common.git"
python_components = [ 'dune' ]
version('2.7.0', sha256='3c83c583a45325513113148cb94bd978e601907a6591c765f6253342e00f1890', expand=False)
# This defines a mapping of available versions of the dune Spack package
# and the branch name in the Dune repositories this refers to.
dune_versions_to_branch = {
"master" : "master",
"2.7" : "releases/2.7",
}
variant('2d', default=True, description='Build library for 2d')
variant('3d', default=True, description='Build library for 3d')
@ -83,74 +87,76 @@ class Dune(CMakePackage):
variant('typetree', default=False, description='Build with dune-typetree module')
variant('uggrid', default=False, description='Build with dune-uggrid module')
#Dune common module
resource(
name='dune-common',
git='https://gitlab.dune-project.org/core/dune-common.git',
branch='releases/2.7',
)
#Dune geometry module
resource(
name='dune-geometry',
git='https://gitlab.dune-project.org/core/dune-geometry.git',
branch='releases/2.7',
when='+geometry')
# Iterate over all available Dune versions and define resources for all Dune modules
for vers, branch in dune_versions_to_branch.items():
version(vers, branch=dune_versions_to_branch[vers])
#Dune grid module
resource(
name='dune-grid',
git='https://gitlab.dune-project.org/core/dune-grid.git',
branch='releases/2.7',
when='+grid')
resource(
name='dune-geometry',
git='https://gitlab.dune-project.org/core/dune-geometry.git',
branch=branch,
when='@%s+geometry' % vers,
)
#Dune uggrid module
resource(
name='dune-uggrid',
git='https://gitlab.dune-project.org/staging/dune-uggrid.git',
branch='releases/2.7',
when='+uggrid')
resource(
name='dune-grid',
git='https://gitlab.dune-project.org/core/dune-grid.git',
branch=branch,
when='@%s+grid' % vers,
)
#Dune istl module
resource(
name='dune-istl',
git='https://gitlab.dune-project.org/core/dune-istl.git',
branch='releases/2.7',
when='+istl')
resource(
name='dune-istl',
git='https://gitlab.dune-project.org/core/dune-istl.git',
branch=branch,
when='@%s+istl' % vers,
)
#Dune localfunctions module
resource(
name='dune-localfunctions',
git='https://gitlab.dune-project.org/core/dune-localfunctions.git',
branch='releases/2.7',
when='+localfunctions')
resource(
name='dune-localfunctions',
git='https://gitlab.dune-project.org/core/dune-localfunctions.git',
branch=branch,
when='@%s+localfunctions' % vers,
)
#Dune functions module
resource(
name='dune-functions',
git='https://gitlab.dune-project.org/staging/dune-functions.git',
branch='releases/2.7',
when='+functions')
resource(
name='dune-functions',
git='https://gitlab.dune-project.org/staging/dune-functions.git',
branch=branch,
when='@%s+functions' % vers,
)
#Dune module
resource(
name='dune-python',
git='https://gitlab.dune-project.org/staging/dune-python.git',
branch='releases/2.7',
when='+python')
#Dune module
resource(
name='dune-typetree',
git='https://gitlab.dune-project.org/staging/dune-typetree.git',
branch='releases/2.7',
when='+typetree')
#Dune module
resource(
name='dune-alugrid',
git='https://gitlab.dune-project.org/extensions/dune-alugrid.git',
branch='releases/2.7',
when='+alugrid')
resource(
name='dune-python',
git='https://gitlab.dune-project.org/staging/dune-python.git',
branch=branch,
when='@%s+python' % vers,
)
#Dependence between modules
resource(
name='dune-typetree',
git='https://gitlab.dune-project.org/staging/dune-typetree.git',
branch=branch,
when='@%s+typetree' % vers,
)
resource(
name='dune-alugrid',
git='https://gitlab.dune-project.org/extensions/dune-alugrid.git',
branch=branch,
when='@%s+alugrid' % vers,
)
resource(
name='dune-uggrid',
git='https://gitlab.dune-project.org/staging/dune-uggrid.git',
branch='releases/2.7',
when='@%s+uggrid' % vers,
)
# Dependencies between modules
module_dependencies={"dune-common":[]}
module_dependencies["dune-geometry"]=["dune-common"]
module_dependencies["dune-grid"]=["dune-common","dune-geometry"]
@ -162,13 +168,6 @@ class Dune(CMakePackage):
module_dependencies["dune-python"]=[]
module_dependencies["dune-alugrid"]=["dune-grid","dune-geometry","dune-common"]
def build_module_list(self,module_list,name):
if name in self.module_dependencies.keys():
for dep in self.module_dependencies[name]:
self.build_module_list(module_list,dep)
module_list.append(name)
return
extends('python')
#option
depends_on('gawk')
@ -235,42 +234,37 @@ 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):
# for variant, resource_list in self.resources.items():
resources = []
# Select the resources that are needed for this build
if self.spec.concrete:
module_list=[]
for when_spec, resource_list in self.resources.items():
if when_spec in self.spec:
for res in resource_list:
dune_module=res.name
self.build_module_list(module_list,dune_module)
# resources.extend(resource_list)
module_list = list(dict.fromkeys(module_list))
for when_spec, resource_list in self.resources.items():
for res in resource_list:
if(res.name in module_list):
resources.extend(resource_list)
else:
for when_spec, resource_list in self.resources.items():
# Note that variant checking is always strict for specs where
# the name is not specified. But with strict variant checking,
# only variants mentioned in 'other' are checked. Here we only
# want to make sure that no constraints in when_spec
# conflict with the spec, so we need to invoke
# when_spec.satisfies(self.spec) vs.
# self.spec.satisfies(when_spec)
if when_spec.satisfies(self.spec, strict=False):
resources.extend(resource_list)
# Sorts the resources by the length of the string representing their
# destination. Since any nested resource must contain another
# resource's name in its path, it seems that should work
resources = sorted(resources, key=lambda res: len(res.destination))
return resources
# 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):
os.remove(self.stage.archive_file)
if self.stage.archive_file:
os.remove(self.stage.archive_file)
optFile = open(self.stage.source_path+"/../dune.opts", "w")
optFile.write('CMAKE_FLAGS="')
for flag in self.cmake_args():
@ -278,22 +272,22 @@ class Dune(CMakePackage):
optFile.write('-DCMAKE_INSTALL_PREFIX=%s' % prefix)
optFile.write('"')
optFile.close()
set_executable('dune-common/bin/dunecontrol')
installer = Executable('dune-common/bin/dunecontrol')
set_executable('bin/dunecontrol')
installer = Executable('bin/dunecontrol')
options_file=self.stage.source_path+"/../dune.opts"
installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'cmake')
pass
def install(self, spec, prefix):
set_executable('dune-common/bin/dunecontrol')
installer = Executable('dune-common/bin/dunecontrol')
set_executable('bin/dunecontrol')
installer = Executable('bin/dunecontrol')
options_file=self.stage.source_path+"/../dune.opts"
installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'make', 'install')
pass
def build(self, spec, prefix):
set_executable('dune-common/bin/dunecontrol')
installer = Executable('dune-common/bin/dunecontrol')
set_executable('bin/dunecontrol')
installer = Executable('bin/dunecontrol')
options_file=self.stage.source_path+"/../dune.opts"
installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'make')
pass