spack/var/spack/repos/builtin/packages/yambo/package.py
Massimiliano Culpo c4521535e7 Multi-valued variants: better support for combinations (#9481)
This enforces conventions that allow for correct handling of
multi-valued variants where specifying no value is an option,
and adds convenience functionality for specifying multi-valued
variants with conflicting sets of values. This also adds a notion
of "feature values" for variants, which are those that are understood
by the build system (e.g. those that would appear as configure
options). In more detail:

* Add documentation on variants to the packaging guide
* Forbid usage of '' or None as a possible variant value, in
  particular as a default. To indicate choosing no value, the user
  must explicitly define an option like 'none'. Without this,
  multi-valued variants with default set to None were not parsable
  from the command line (Fixes #6314)
* Add "disjoint_sets" function to support the declaration of
  multi-valued variants with conflicting sets of options. For example
  a variant "foo" with possible values "a", "b", and "c" where "c"
  is exclusive of the other values ("foo=a,b" and "foo=c" are
  valid but "foo=a,c" is not).
* Add "any_combination_of" function to support the declaration of
  multi-valued variants where it is valid to choose none of the
  values. This automatically defines "none" as an option (exclusive
  with all other choices); this value does not appear when iterating
  over the variant's values, for example in "with_or_without" (which
  constructs autotools option strings from variant values).
* The "disjoint_sets" and "any_combination_of" methods return an
  object which tracks the possible values. It is also possible to
  indicate that some of these values do not correspond to options
  understood by the package's build system, such that methods like
  "with_or_without" will not define options for those values (this
  occurs automatically for "none")
* Add documentation for usage of new functions for specifying
  multi-valued variants
2019-01-04 19:02:34 -08:00

146 lines
5.1 KiB
Python

# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
class Yambo(AutotoolsPackage):
"""Yambo is a FORTRAN/C code for Many-Body calculations in solid
state and molecular physics.
Yambo relies on the Kohn-Sham wavefunctions generated by two DFT
public codes: abinit, and PWscf. The code was originally developed
in the Condensed Matter Theoretical Group of the Physics Department
at the University of Rome "Tor Vergata" by Andrea Marini. Previous
to its release under the GPL license, yambo was known as SELF.
"""
homepage = "http://www.yambo-code.org/index.php"
url = "https://github.com/yambo-code/yambo/archive/4.2.2.tar.gz"
version('4.2.2', '97f3513bd726141be5e18072118b6fb5')
version('4.2.1', '99027014192c0f0f4b5d9b48414ad85d')
version('4.2.0', '0cbb4d7c9790596d163ebe872d95bd30')
variant('dp', default=False, description='Enable double precision')
variant(
'profile', values=any_combination_of('time', 'memory'),
description='Activate profiling of specific sections'
)
variant(
'io', values=any_combination_of('iotk', 'etsf-io'),
description='Activate support for different io formats (requires network access)', # noqa
)
# MPI + OpenMP parallelism
variant('mpi', default=True, description='Enable MPI support')
variant('openmp', default=False, description='Enable OpenMP support')
depends_on('blas')
depends_on('lapack')
# MPI dependencies are forced, until we have proper forwarding of variants
#
# Note that yambo is used as an application, and not linked as a library,
# thus there will be no case where another package pulls-in e.g. netcdf+mpi
# and wants to depend on yambo~mpi.
depends_on('mpi', when='+mpi')
depends_on('netcdf+mpi', when='+mpi')
depends_on('hdf5+mpi', when='+mpi')
depends_on('fftw+mpi', when='+mpi')
depends_on('scalapack', when='+mpi')
depends_on('netcdf~mpi', when='~mpi')
depends_on('hdf5~mpi', when='~mpi')
depends_on('fftw~mpi', when='~mpi')
depends_on('hdf5+fortran')
depends_on('netcdf')
depends_on('netcdf-fortran')
depends_on('libxc@2.0.3:')
build_targets = ['all']
parallel = False
# The configure in the package has the string 'cat config/report'
# hard-coded, which causes a failure at configure time due to the
# current working directory in Spack. Fix this by using the absolute
# path to the file.
@run_before('configure')
def filter_configure(self):
report_abspath = join_path(self.build_directory, 'config', 'report')
filter_file('config/report', report_abspath, 'configure')
def enable_or_disable_time(self, activated):
return '--enable-time-profile' if activated else '--disable-time-profile' # noqa: E501
def enable_or_disable_memory(self, activated):
return '--enable-memory-profile' if activated else '--disable-memory-profile' # noqa: E501
def enable_or_disable_openmp(self, activated):
return '--enable-open-mp' if activated else '--disable-open-mp'
def configure_args(self):
args = [
# As of version 4.2.1 there are hard-coded paths that make
# the build process fail if the target prefix is not the
# configure directory
'--prefix={0}'.format(self.stage.source_path),
'--disable-keep-objects',
'--with-editor=none'
]
spec = self.spec
# Double precision
args.extend(self.enable_or_disable('dp'))
# Application profiling
args.extend(self.enable_or_disable('profile'))
# MPI + threading
args.extend(self.enable_or_disable('mpi'))
args.extend(self.enable_or_disable('openmp'))
# LAPACK
if '+mpi' in spec:
args.append('--with-scalapack-libs={0}'.format(
spec['scalapack'].libs +
spec['lapack'].libs +
spec['blas'].libs
))
args.extend([
'--with-blas-libs={0}'.format(spec['blas'].libs),
'--with-lapack-libs={0}'.format(spec['lapack'].libs)
])
# Netcdf
args.extend([
'--enable-netcdf-hdf5',
'--enable-hdf5-compression',
'--with-hdf5-libs={0}'.format(spec['hdf5'].libs),
'--with-netcdf-path={0}'.format(spec['netcdf'].prefix),
'--with-netcdff-path={0}'.format(spec['netcdf-fortran'].prefix)
])
args.extend(self.enable_or_disable('io'))
# Other dependencies
args.append('--with-fft-path={0}'.format(spec['fftw'].prefix))
args.append('--with-libxc-path={0}'.format(spec['libxc'].prefix))
return args
def install(self, spec, prefix):
# As of version 4.2.1 an 'install' target is advertized,
# but not present
install_tree('bin', prefix.bin)
install_tree('lib', prefix.lib)
install_tree('include', prefix.include)
install_tree('driver', prefix.driver)