spack/var/spack/repos/builtin/packages/libmesh/package.py
Abhik Sarkar 0ce8b9d398
Make boost minimal and composable (Original PR#22303) (#28623)
* Make boost composable

Currently Boost enables a few components through variants by default,
which means that if you want to use only what you need and no more, you
have to explicitly disable these variants, leading to concretization
errors whenever a second package explicitly needs those components.

For instance if package A only needs `+component_a` it might depend on
`boost +component_a ~component_b`. And if packge B only needs
`+component_b` it might depend on `boost ~component_a +component_b`. If
package C now depends on both A and B, this leads to unsatisfiable
variants and hence a concretization error.

However, if we default to disabling all components, package A can simply
depend on `boost +component_a` and package B on `boost +component_b` and
package C will concretize to depending on `boost +component_a
+component_b`, and whatever you install, you get the bare minimum.

* Fix style

* Added composable boost dependencies for folly

* fixing akantu merge issue

* hpctoolkit boost dependencies already defined

* Fix Styles

* Fixup style once more

* Adding isort fix

* isort one more time

* Fix for package audit issue

Co-authored-by: Harmen Stoppels <harmenstoppels@gmail.com>
Co-authored-by: Ryan O'Malley <rd.omalley@comcast.net>
2022-03-17 17:42:07 -06:00

253 lines
12 KiB
Python

# Copyright 2013-2022 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 *
from spack.pkg.builtin.boost import Boost
class Libmesh(AutotoolsPackage):
"""The libMesh library provides a framework for the numerical simulation of
partial differential equations using arbitrary unstructured
discretizations on serial and parallel platforms."""
homepage = "https://libmesh.github.io/"
url = "https://github.com/libMesh/libmesh/releases/download/v1.0.0/libmesh-1.0.0.tar.bz2"
git = "https://github.com/libMesh/libmesh.git"
version('master', branch='master', submodules=True)
version('1.4.1', sha256='67eb7d5a9c954d891ca1386b70f138333a87a141d9c44213449ca6be69a66414')
version('1.4.0', sha256='62d7fce89096c950d1b38908484856ea63df57754b64cde6582e7ac407c8c81d')
version('1.3.1', sha256='638cf30d05c249315760f16cbae4804964db8857a04d5e640f37617bef17ab0f')
version('1.3.0', sha256='a8cc2cd44f42b960989dba10fa438b04af5798c46db0b4ec3ed29591b8359786')
version('1.2.1', sha256='11c22c7d96874a17de6b8c74caa45d6745d40bf3610e88b2bd28fd3381f5ba70')
version('1.0.0', sha256='8909b0354e147fa50d176caa63ef22b02326d49250e964be23532d89432e727f')
# support for libraries that are only available through the bundled copies:
# TODO libMesh 1.2.1 gained the ability to specify a path to capnproto
variant('capnproto', default=False, description='Compile with the bundled capnproto serialization library')
variant('exodusii', default=False, description='Compile with the bundled ExodusII output library')
variant('vtk', default=False, description='Compile with VTK input/output library')
variant('fparser', default=False, description='Compile with the bundled fparser function parser library')
variant('gmv', default=False, description='Compile with the bundled gmv format IO library')
variant('laspack', default=False, description='Compile with the bundled laspack interative solver library')
variant('libhilbert', default=False, description='Compile with the bundled libHilbert partitioning library')
variant('metaphysicl', default=False, description='Compile with the bundled metaphysicl AD library')
variant('perflog', default=False, description='Compile with performance logging support')
variant('blocked', default=False, description='Compile with support for blocked storage')
variant('metis', default=False, description='Compile with the bundled METIS graph partitioning library')
variant('nanoflann', default=False, description='Compile with the bundled nanoflann graph library')
variant('nemesis', default=False, description='Compile with the bundled nemesis IO library')
variant('netcdf', default=False, description='Compile with the bundled NETCDF IO library')
# TODO the copy of parmetis bundled with libMesh assumes that we use the
# bundled copy of metis, but previous versions of this build script use an
# external metis installation. Be conservative and completely disable
# parmetis support to preserve the old behavior (and to prevent compiling
# with two different copies of metis).
#
# variant('parmetis', default=False,
# description='Compile with the bundled PARMETIS graph library')
variant('qhull', default=False, description='Compile with the bundled qhull mesh generation library')
variant('sfc', default=False, description='Compile with the bundled sfcurves partitioning library')
variant('tetgen', default=False, description='Compile with the bundled tetgen mesh generation library')
variant('triangle', default=False, description='Compile with the bundled Triangle mesh generation library')
# support for libraries that may be externally installed:
variant('boost', default=False, description='Compile with components dependent on boost')
variant('eigen', default=False, description='support for dense linear algebra with Eigen')
variant('hdf5', default=False, description='Compile with support for HDF5 files')
variant('slepc', default=False, description='Compile with support for the SLEPc eigensolver')
variant('petsc', default=False, description='Compile with support for the PETSc')
# other features:
variant('debug', default=False, description='Compile with support for debugging')
variant('mpi', default=True, description='Enables MPI parallelism')
# While it is possible to configure libMesh to use openMP with neither
# pthreads nor TBB, no openMP code can actually be reached without enabling
# pthreads as well. Hence, since enabling openMP while disabling pthreads
# is not useful, we include openMP in the same variant to make it clear
# which scheduler is ultimately used.
variant('threads', default='none',
description='Enable threading support (with a particular '
'scheduler, in the case of openmp and tbb)',
values=('none', 'pthreads', 'tbb', 'openmp'), multi=False)
conflicts('+metaphysicl', when='@:1.2',
msg='The interface to metaphysicl is not available in libMesh '
'versions older than 1.3.0. Please explicitly disable this '
'variant.')
depends_on('boost', when='+boost')
# TODO: replace this with an explicit list of components of Boost,
# for instance depends_on('boost +filesystem')
# See https://github.com/spack/spack/pull/22303 for reference
depends_on(Boost.with_default_variants, when='+boost')
depends_on('eigen', when='+eigen')
depends_on('hdf5+mpi', when='+hdf5+mpi')
depends_on('mpi', when='+mpi')
depends_on('mpi', when='+slepc')
# compilation dependencies depend on perl
depends_on('perl')
depends_on('petsc+mpi', when='+mpi')
depends_on('petsc+metis', when='+metis')
depends_on('slepc', when='+slepc')
depends_on('petsc', when='+petsc')
depends_on('tbb', when='threads=tbb')
depends_on('vtk', when='+vtk')
def configure_args(self):
options = []
# GLIBCXX debugging is not, by default, supported by other libraries,
# so unconditionally disable it for libmesh
options.append('--enable-glibcxx-debugging=no')
# All bundled dependencies are explicitly disabled, so we do not need
# to perform this check:
options.append('--disable-strict-lgpl')
# The Hinnant unique pointer implementation is incompatible with boost
# (and not necessary with C++11 support), so unconditionally disable
# it:
options.append('--disable-hinnant-unique-ptr')
# libMesh does not allow for us to specify an installation location for
# zlib, an undocumented dependency of gzstreams: hence we must
# unconditionally disable gzstreams.
options.append('--enable-gzstreams=no')
# Similarly, since we cannot specify a location for bzip2 or xz, so
# disable them to avoid picking up system installations:
options.append('--disable-bzip2')
options.append('--disable-xz')
# TODO enable GDB backtracing. Disable for now to avoid picking up the
# system gdb installation:
options.append('--without-gdb-command')
# TODO add X11 as a dependency to get tecplot working
options.append('--enable-tecio=no')
options.append('--enable-tecplot=no')
# handle the bundled libraries that are not themselves dependencies of
# other bundled libaries:
for bundled_library in ['capnproto', 'exodusii', 'fparser', 'gmv',
'laspack', 'libHilbert', 'metaphysicl',
'nanoflann', 'nemesis', 'parmetis', 'qhull',
'sfc', 'tetgen', 'triangle']:
if '+' + bundled_library.lower() in self.spec:
options.append('--enable-' + bundled_library + "=yes")
else:
options.append('--enable-' + bundled_library + "=no")
# and the ones which are dependencies of other bundled libraries:
if '+exodusii' in self.spec or '+netcdf' in self.spec:
options.append('--enable-netcdf=yes')
else:
options.append('--enable-netcdf=no')
if '+vtk' in self.spec:
options.append('--enable-vtk')
options.append('--with-vtk=%s' % self.spec['vtk'].prefix)
else:
options.append('--disable-vtk')
# handle external library dependencies:
if '+boost' in self.spec:
options.append('--with-boost=%s' % self.spec['boost'].prefix)
else:
options.append('--enable-boost=no')
if '+eigen' in self.spec:
options.append('--with-eigen=%s' % self.spec['eigen'].prefix)
else:
options.append('--enable-eigen=no')
if '+metaphysicl' in self.spec:
options.append('--enable-metaphysicl')
else:
options.append('--disable-metaphysicl')
if '+perflog' in self.spec:
options.append('--enable-perflog')
else:
options.append('--disable-perflog')
if '+blocked' in self.spec:
options.append('--enable-blocked-storage')
else:
options.append('--disable-blocked-storage')
if '+hdf5' in self.spec:
options.append('--with-hdf5=%s' % self.spec['hdf5'].prefix)
else:
options.append('--enable-hdf5=no')
# This is necessary with libMesh 1.2.1 to prevent a configure
# error:
if '+netcdf' not in self.spec:
options.append('--disable-netcdf-4')
if '+metis' in self.spec:
options.append('--enable-metis')
options.append('--enable-parmetis')
if ('+petsc' in self.spec):
options.append('--with-metis=PETSc')
options.append('--with-parmetis=PETSc')
if '+petsc' in self.spec or '+slepc' in self.spec:
options.append('--enable-petsc=yes')
options.append('PETSC_DIR=%s' % self.spec['petsc'].prefix)
else:
options.append('--enable-petsc=no')
if '+slepc' in self.spec:
options.append('--enable-slepc=yes')
options.append('SLEPC_DIR=%s' % self.spec['slepc'].prefix)
else:
options.append('--enable-slepc=no')
# and, finally, other things:
if '+debug' in self.spec:
options.append('--with-methods=dbg')
else:
options.append('--with-methods=opt')
if '+mpi' in self.spec:
options.append('CC=%s' % self.spec['mpi'].mpicc)
options.append('CXX=%s' % self.spec['mpi'].mpicxx)
options.append('--with-mpi=%s' % self.spec['mpi'].prefix)
else:
options.append('--disable-mpi')
# libMesh will try to link with the system MPI library unless we
# provide explicit overrides
options.append('CC=%s' % self.compiler.cc)
options.append('CXX=%s' % self.compiler.cxx)
if 'threads=openmp' in self.spec:
# OpenMP cannot be used if pthreads is not available: see
# parallel/threads_pthread.h and parallel/threads.h
options.append('--enable-openmp=yes')
options.append('--with-thread-model=pthread')
options.append('--enable-pthreads=yes')
else:
options.append('--enable-openmp=no')
if 'threads=pthreads' in self.spec:
options.append('--with-thread-model=pthread')
options.append('--enable-pthreads=yes')
else:
if 'threads=openmp' not in self.spec:
options.append('--enable-pthreads=no')
if 'threads=tbb' in self.spec:
options.append('--with-thread-model=tbb')
options.append('--enable-tbb=yes')
options.append('--with-tbb=%s' % self.spec['tbb'].prefix)
else:
options.append('--enable-tbb=no')
return options
def setup_dependent_build_environment(self, env, dependent_spec):
env.append_flags('PERL', self.spec['perl'].command.path)