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 * from spack import *
class Dune(CMakePackage): class Dune(CMakePackage):
""" """
DUNE, the Distributed and Unified Numerics Environment is a modular toolbox for solving partial differential equations (PDEs) with grid-based methods. 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" homepage = "https://www.dune-project.org"
url = "https://www.dune-project.org/download/2.7.0/dune-common-2.7.0.tar.gz" git = "https://gitlab.dune-project.org/core/dune-common.git"
list_url = "https://www.dune-project.org/download/"
list_depth = 1
python_components = [ 'dune' ] python_components = [ 'dune' ]
# This defines a mapping of available versions of the dune Spack package
version('2.7.0', sha256='3c83c583a45325513113148cb94bd978e601907a6591c765f6253342e00f1890', expand=False) # 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('2d', default=True, description='Build library for 2d')
variant('3d', default=True, description='Build library for 3d') 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('typetree', default=False, description='Build with dune-typetree module')
variant('uggrid', default=False, description='Build with dune-uggrid module') variant('uggrid', default=False, description='Build with dune-uggrid module')
#Dune common module # Iterate over all available Dune versions and define resources for all Dune modules
resource( for vers, branch in dune_versions_to_branch.items():
name='dune-common', version(vers, branch=dune_versions_to_branch[vers])
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')
#Dune grid module resource(
resource( name='dune-geometry',
name='dune-grid', git='https://gitlab.dune-project.org/core/dune-geometry.git',
git='https://gitlab.dune-project.org/core/dune-grid.git', branch=branch,
branch='releases/2.7', when='@%s+geometry' % vers,
when='+grid') )
#Dune uggrid module resource(
resource( name='dune-grid',
name='dune-uggrid', git='https://gitlab.dune-project.org/core/dune-grid.git',
git='https://gitlab.dune-project.org/staging/dune-uggrid.git', branch=branch,
branch='releases/2.7', when='@%s+grid' % vers,
when='+uggrid') )
#Dune istl module resource(
resource( name='dune-istl',
name='dune-istl', git='https://gitlab.dune-project.org/core/dune-istl.git',
git='https://gitlab.dune-project.org/core/dune-istl.git', branch=branch,
branch='releases/2.7', when='@%s+istl' % vers,
when='+istl') )
#Dune localfunctions module resource(
resource( name='dune-localfunctions',
name='dune-localfunctions', git='https://gitlab.dune-project.org/core/dune-localfunctions.git',
git='https://gitlab.dune-project.org/core/dune-localfunctions.git', branch=branch,
branch='releases/2.7', when='@%s+localfunctions' % vers,
when='+localfunctions') )
#Dune functions module resource(
resource( name='dune-functions',
name='dune-functions', git='https://gitlab.dune-project.org/staging/dune-functions.git',
git='https://gitlab.dune-project.org/staging/dune-functions.git', branch=branch,
branch='releases/2.7', when='@%s+functions' % vers,
when='+functions') )
#Dune module resource(
resource( name='dune-python',
name='dune-python', git='https://gitlab.dune-project.org/staging/dune-python.git',
git='https://gitlab.dune-project.org/staging/dune-python.git', branch=branch,
branch='releases/2.7', when='@%s+python' % vers,
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')
#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-common":[]}
module_dependencies["dune-geometry"]=["dune-common"] module_dependencies["dune-geometry"]=["dune-common"]
module_dependencies["dune-grid"]=["dune-common","dune-geometry"] module_dependencies["dune-grid"]=["dune-common","dune-geometry"]
@ -162,13 +168,6 @@ class Dune(CMakePackage):
module_dependencies["dune-python"]=[] module_dependencies["dune-python"]=[]
module_dependencies["dune-alugrid"]=["dune-grid","dune-geometry","dune-common"] 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') extends('python')
#option #option
depends_on('gawk') depends_on('gawk')
@ -235,42 +234,37 @@ class Dune(CMakePackage):
return cmake_args 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): def _get_needed_resources(self):
# for variant, resource_list in self.resources.items(): # Modify the list of resources by building a transitive closure of Dune module dependencies.
resources = [] self.resources = {when: self.module_dependency_closure(when, reslist) for when, reslist in self.resources.items()}
# Select the resources that are needed for this build
if self.spec.concrete: # and call the original implementation
module_list=[] return CMakePackage._get_needed_resources(self)
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
def cmake(self, spec, prefix): 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 = open(self.stage.source_path+"/../dune.opts", "w")
optFile.write('CMAKE_FLAGS="') optFile.write('CMAKE_FLAGS="')
for flag in self.cmake_args(): for flag in self.cmake_args():
@ -278,22 +272,22 @@ class Dune(CMakePackage):
optFile.write('-DCMAKE_INSTALL_PREFIX=%s' % prefix) optFile.write('-DCMAKE_INSTALL_PREFIX=%s' % prefix)
optFile.write('"') optFile.write('"')
optFile.close() optFile.close()
set_executable('dune-common/bin/dunecontrol') set_executable('bin/dunecontrol')
installer = Executable('dune-common/bin/dunecontrol') installer = Executable('bin/dunecontrol')
options_file=self.stage.source_path+"/../dune.opts" options_file=self.stage.source_path+"/../dune.opts"
installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'cmake') installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'cmake')
pass pass
def install(self, spec, prefix): def install(self, spec, prefix):
set_executable('dune-common/bin/dunecontrol') set_executable('bin/dunecontrol')
installer = Executable('dune-common/bin/dunecontrol') installer = Executable('bin/dunecontrol')
options_file=self.stage.source_path+"/../dune.opts" options_file=self.stage.source_path+"/../dune.opts"
installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'make', 'install') installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'make', 'install')
pass pass
def build(self, spec, prefix): def build(self, spec, prefix):
set_executable('dune-common/bin/dunecontrol') set_executable('bin/dunecontrol')
installer = Executable('dune-common/bin/dunecontrol') installer = Executable('bin/dunecontrol')
options_file=self.stage.source_path+"/../dune.opts" options_file=self.stage.source_path+"/../dune.opts"
installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'make') installer('--builddir=%s'%self.build_directory , '--opts=%s' % options_file, 'make')
pass pass