spack/var/spack/repos/builtin/packages/axom/package.py
Tom Scogland 18c2f1a57a
refactor: packages import spack.package explicitly (#30404)
Explicitly import package utilities in all packages, and corresponding fallout.

This includes:

* rename `spack.package` to `spack.package_base`
* rename `spack.pkgkit` to `spack.package`
* update all packages in builtin, builtin_mock and tutorials to include `from spack.package import *`
* update spack style
  * ensure packages include the import
  * automatically add the new import and remove any/all imports of `spack` and `spack.pkgkit`
    from packages when using `--fix`
  * add support for type-checking packages with mypy when SPACK_MYPY_CHECK_PACKAGES
    is set in the environment
* fix all type checking errors in packages in spack upstream
* update spack create to include the new imports
* update spack repo to inject the new import, injection persists to allow for a deprecation period

Original message below:
 
As requested @adamjstewart, update all packages to use pkgkit.  I ended up using isort to do this,
so repro is easy:

```console
$ isort -a 'from spack.pkgkit import *' --rm 'spack' ./var/spack/repos/builtin/packages/*/package.py
$ spack style --fix
```

There were several line spacing fixups caused either by space manipulation in isort or by packages
that haven't been touched since we added requirements, but there are no functional changes in here.

* [x] add config to isort to make sure this is maintained going forward
2022-05-28 12:55:44 -04:00

445 lines
17 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)
import os
import socket
from os.path import join as pjoin
from spack.package import *
def get_spec_path(spec, package_name, path_replacements={}, use_bin=False):
"""Extracts the prefix path for the given spack package
path_replacements is a dictionary with string replacements for the path.
"""
if not use_bin:
path = spec[package_name].prefix
else:
path = spec[package_name].prefix.bin
path = os.path.realpath(path)
for key in path_replacements:
path = path.replace(key, path_replacements[key])
return path
class Axom(CachedCMakePackage, CudaPackage):
"""Axom provides a robust, flexible software infrastructure for the development
of multi-physics applications and computational tools."""
maintainers = ['white238']
homepage = "https://github.com/LLNL/axom"
git = "https://github.com/LLNL/axom.git"
tags = ['radiuss']
version('main', branch='main')
version('develop', branch='develop')
version('0.6.1', tag='v0.6.1')
version('0.6.0', tag='v0.6.0')
version('0.5.0', tag='v0.5.0')
version('0.4.0', tag='v0.4.0')
version('0.3.3', tag='v0.3.3')
version('0.3.2', tag='v0.3.2')
version('0.3.1', tag='v0.3.1')
version('0.3.0', tag='v0.3.0')
version('0.2.9', tag='v0.2.9')
@property
def submodules(self):
return True
patch('scr_examples_gtest.patch', when='@0.6.0:0.6.1')
root_cmakelists_dir = 'src'
# -----------------------------------------------------------------------
# Variants
# -----------------------------------------------------------------------
variant('shared', default=True,
description='Enable build of shared libraries')
variant('debug', default=False,
description='Build debug instead of optimized version')
variant('examples', default=True, description='Build examples')
variant('tools', default=True, description='Build tools')
variant('cpp14', default=True, description="Build with C++14 support")
variant('fortran', default=True, description="Build with Fortran support")
variant("python", default=False, description="Build python support")
variant("mpi", default=True, description="Build MPI support")
variant('openmp', default=True, description='Turn on OpenMP support.')
variant("mfem", default=False, description="Build with mfem")
variant("hdf5", default=True, description="Build with hdf5")
variant("lua", default=True, description="Build with Lua")
variant("scr", default=False, description="Build with SCR")
variant("umpire", default=True, description="Build with umpire")
variant("raja", default=True, description="Build with raja")
varmsg = "Build development tools (such as Sphinx, Doxygen, etc...)"
variant("devtools", default=False, description=varmsg)
# -----------------------------------------------------------------------
# Dependencies
# -----------------------------------------------------------------------
# Basics
depends_on("cmake@3.8.2:", type='build')
depends_on("mpi", when="+mpi")
# Libraries
depends_on("conduit+python", when="+python")
depends_on("conduit~python", when="~python")
depends_on("conduit+hdf5", when="+hdf5")
depends_on("conduit~hdf5", when="~hdf5")
depends_on("lua", when="+lua")
depends_on("scr", when="+scr")
depends_on("kvtree@main", when="+scr")
depends_on("dtcmp", when="+scr")
with when('+umpire'):
depends_on('umpire@6.0.0:', when='@0.6.0:')
depends_on('umpire@5:5.0.1', when='@:0.5.0')
depends_on('umpire +openmp', when='+openmp')
depends_on('umpire +cuda', when='+cuda')
with when('+raja'):
depends_on('raja@0.14.0:', when='@0.6.0:')
depends_on('raja@:0.13.0', when='@:0.5.0')
depends_on("raja~openmp", when="~openmp")
depends_on("raja+openmp", when="+openmp")
depends_on("raja+cuda", when="+cuda")
for sm_ in CudaPackage.cuda_arch_values:
depends_on('raja cuda_arch={0}'.format(sm_),
when='+raja cuda_arch={0}'.format(sm_))
depends_on('umpire cuda_arch={0}'.format(sm_),
when='+umpire cuda_arch={0}'.format(sm_))
depends_on("mfem", when="+mfem")
depends_on("mfem~mpi", when="+mfem~mpi")
depends_on("python", when="+python")
# Devtools
depends_on("cppcheck", when="+devtools")
depends_on("doxygen", when="+devtools")
depends_on("graphviz", when="+devtools")
depends_on("python", when="+devtools")
depends_on("py-sphinx", when="+devtools")
depends_on("py-shroud", when="+devtools")
depends_on("llvm+clang@10.0.0", when="+devtools", type='build')
# Conduit's cmake config files moved and < 0.4.0 can't find it
conflicts("^conduit@0.7.2:", when="@:0.4.0")
# Sidre requires conduit_blueprint_mpi.hpp
conflicts("^conduit@:0.6.0", when="@0.5.0:")
def flag_handler(self, name, flags):
if self.spec.satisfies('%cce') and name == 'fflags':
flags.append('-ef')
if name in ('cflags', 'cxxflags', 'cppflags', 'fflags'):
return (None, None, None) # handled in the cmake cache
return (flags, None, None)
def _get_sys_type(self, spec):
sys_type = spec.architecture
# if on llnl systems, we can use the SYS_TYPE
if "SYS_TYPE" in env:
sys_type = env["SYS_TYPE"]
return sys_type
@property
def cache_name(self):
hostname = socket.gethostname()
if "SYS_TYPE" in env:
# Are we on a LLNL system then strip node number
hostname = hostname.rstrip('1234567890')
return "{0}-{1}-{2}@{3}.cmake".format(
hostname,
self._get_sys_type(self.spec),
self.spec.compiler.name,
self.spec.compiler.version
)
def initconfig_compiler_entries(self):
spec = self.spec
entries = super(Axom, self).initconfig_compiler_entries()
if "+fortran" in spec or self.compiler.fc is not None:
entries.append(cmake_cache_option("ENABLE_FORTRAN", True))
else:
entries.append(cmake_cache_option("ENABLE_FORTRAN", False))
if ((self.compiler.fc is not None)
and ("gfortran" in self.compiler.fc)
and ("clang" in self.compiler.cxx)):
libdir = pjoin(os.path.dirname(
os.path.dirname(self.compiler.cxx)), "lib")
flags = ""
for _libpath in [libdir, libdir + "64"]:
if os.path.exists(_libpath):
flags += " -Wl,-rpath,{0}".format(_libpath)
description = ("Adds a missing libstdc++ rpath")
if flags:
entries.append(cmake_cache_string("BLT_EXE_LINKER_FLAGS", flags,
description))
if "+cpp14" in spec:
entries.append(cmake_cache_string("BLT_CXX_STD", "c++14", ""))
return entries
def initconfig_hardware_entries(self):
spec = self.spec
entries = super(Axom, self).initconfig_hardware_entries()
if "+cuda" in spec:
entries.append(cmake_cache_option("ENABLE_CUDA", True))
entries.append(cmake_cache_option("CUDA_SEPARABLE_COMPILATION",
True))
entries.append(
cmake_cache_option("AXOM_ENABLE_ANNOTATIONS", True))
# CUDA_FLAGS
cudaflags = "-restrict --expt-extended-lambda "
if not spec.satisfies('cuda_arch=none'):
cuda_arch = spec.variants['cuda_arch'].value[0]
entries.append(cmake_cache_string(
"CMAKE_CUDA_ARCHITECTURES",
cuda_arch))
cudaflags += '-arch sm_${CMAKE_CUDA_ARCHITECTURES} '
else:
entries.append(
"# cuda_arch could not be determined\n\n")
if "+cpp14" in spec:
cudaflags += " -std=c++14"
else:
cudaflags += " -std=c++11"
entries.append(
cmake_cache_string("CMAKE_CUDA_FLAGS", cudaflags))
entries.append(
"# nvcc does not like gtest's 'pthreads' flag\n")
entries.append(
cmake_cache_option("gtest_disable_pthreads", True))
entries.append("#------------------{0}".format("-" * 30))
entries.append("# Hardware Specifics")
entries.append("#------------------{0}\n".format("-" * 30))
# OpenMP
entries.append(cmake_cache_option("ENABLE_OPENMP",
spec.satisfies('+openmp')))
# Enable death tests
entries.append(cmake_cache_option(
"ENABLE_GTEST_DEATH_TESTS",
not spec.satisfies('+cuda target=ppc64le:')
))
if (self.compiler.fc is not None) and ("xlf" in self.compiler.fc):
# Grab lib directory for the current fortran compiler
libdir = pjoin(os.path.dirname(
os.path.dirname(self.compiler.fc)),
"lib")
description = ("Adds a missing rpath for libraries "
"associated with the fortran compiler")
linker_flags = "${BLT_EXE_LINKER_FLAGS} -Wl,-rpath," + libdir
entries.append(cmake_cache_string("BLT_EXE_LINKER_FLAGS",
linker_flags, description))
if "+shared" in spec:
linker_flags = "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath," \
+ libdir
entries.append(cmake_cache_string(
"CMAKE_SHARED_LINKER_FLAGS",
linker_flags, description))
description = ("Converts C-style comments to Fortran style "
"in preprocessed files")
entries.append(cmake_cache_string(
"BLT_FORTRAN_FLAGS",
"-WF,-C! -qxlf2003=polymorphic",
description))
if spec.satisfies('target=ppc64le:'):
# Fix for working around CMake adding implicit link directories
# returned by the BlueOS compilers to link executables with
# non-system default stdlib
_roots = ["/usr/tce/packages/gcc/gcc-4.9.3",
"/usr/tce/packages/gcc/gcc-4.9.3/gnu"]
_subdirs = ["lib64",
"lib64/gcc/powerpc64le-unknown-linux-gnu/4.9.3"]
_existing_paths = []
for root in _roots:
for subdir in _subdirs:
_curr_path = pjoin(root, subdir)
if os.path.exists(_curr_path):
_existing_paths.append(_curr_path)
if _existing_paths:
entries.append(cmake_cache_string(
"BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE",
";".join(_existing_paths)))
return entries
def initconfig_mpi_entries(self):
spec = self.spec
entries = super(Axom, self).initconfig_mpi_entries()
if "+mpi" in spec:
entries.append(cmake_cache_option("ENABLE_MPI", True))
if spec['mpi'].name == 'spectrum-mpi':
entries.append(cmake_cache_string("BLT_MPI_COMMAND_APPEND",
"mpibind"))
else:
entries.append(cmake_cache_option("ENABLE_MPI", False))
return entries
def initconfig_package_entries(self):
spec = self.spec
entries = []
# TPL locations
entries.append("#------------------{0}".format("-" * 60))
entries.append("# TPLs")
entries.append("#------------------{0}\n".format("-" * 60))
# Try to find the common prefix of the TPL directory, including the
# compiler. If found, we will use this in the TPL paths
compiler_str = str(spec.compiler).replace('@', '-')
prefix_paths = prefix.split(compiler_str)
path_replacements = {}
if len(prefix_paths) == 2:
tpl_root = os.path.realpath(pjoin(prefix_paths[0], compiler_str))
path_replacements[tpl_root] = "${TPL_ROOT}"
entries.append("# Root directory for generated TPLs\n")
entries.append(cmake_cache_path("TPL_ROOT", tpl_root))
conduit_dir = get_spec_path(spec, "conduit", path_replacements)
entries.append(cmake_cache_path("CONDUIT_DIR", conduit_dir))
# optional tpls
for dep in ('mfem', 'hdf5', 'lua', 'raja', 'umpire'):
if '+%s' % dep in spec:
dep_dir = get_spec_path(spec, dep, path_replacements)
entries.append(cmake_cache_path('%s_DIR' % dep.upper(),
dep_dir))
else:
entries.append('# %s not built\n' % dep.upper())
if '+scr' in spec:
dep_dir = get_spec_path(spec, 'scr', path_replacements)
entries.append(cmake_cache_path('SCR_DIR', dep_dir))
# scr's dependencies
for dep in ('kvtree', 'dtcmp'):
if spec.satisfies('^{0}'.format(dep)):
dep_dir = get_spec_path(spec, dep, path_replacements)
entries.append(cmake_cache_path('%s_DIR' % dep.upper(), dep_dir))
else:
entries.append('# scr not built\n')
##################################
# Devtools
##################################
entries.append("#------------------{0}".format("-" * 60))
entries.append("# Devtools")
entries.append("#------------------{0}\n".format("-" * 60))
# Add common prefix to path replacement list
if "+devtools" in spec:
# Grab common devtools root and strip the trailing slash
path1 = os.path.realpath(spec["cppcheck"].prefix)
path2 = os.path.realpath(spec["doxygen"].prefix)
devtools_root = os.path.commonprefix([path1, path2])[:-1]
path_replacements[devtools_root] = "${DEVTOOLS_ROOT}"
entries.append(
"# Root directory for generated developer tools\n")
entries.append(cmake_cache_path("DEVTOOLS_ROOT", devtools_root))
# Only turn on clangformat support if devtools is on
clang_fmt_path = spec['llvm'].prefix.bin.join('clang-format')
entries.append(cmake_cache_path(
"CLANGFORMAT_EXECUTABLE", clang_fmt_path))
else:
entries.append("# ClangFormat disabled due to disabled devtools\n")
entries.append(cmake_cache_option("ENABLE_CLANGFORMAT", False))
if spec.satisfies('^python') or "+devtools" in spec:
python_path = os.path.realpath(spec['python'].command.path)
for key in path_replacements:
python_path = python_path.replace(key, path_replacements[key])
entries.append(cmake_cache_path("PYTHON_EXECUTABLE", python_path))
enable_docs = spec.satisfies('^doxygen') or spec.satisfies('^py-sphinx')
entries.append(cmake_cache_option("ENABLE_DOCS", enable_docs))
if spec.satisfies('^py-sphinx'):
python_bin_dir = get_spec_path(spec, "python",
path_replacements,
use_bin=True)
entries.append(cmake_cache_path("SPHINX_EXECUTABLE",
pjoin(python_bin_dir,
"sphinx-build")))
if spec.satisfies('^py-shroud'):
shroud_bin_dir = get_spec_path(spec, "py-shroud",
path_replacements, use_bin=True)
entries.append(cmake_cache_path("SHROUD_EXECUTABLE",
pjoin(shroud_bin_dir, "shroud")))
for dep in ('cppcheck', 'doxygen'):
if spec.satisfies('^%s' % dep):
dep_bin_dir = get_spec_path(spec, dep, path_replacements,
use_bin=True)
entries.append(cmake_cache_path('%s_EXECUTABLE' % dep.upper(),
pjoin(dep_bin_dir, dep)))
return entries
def cmake_args(self):
options = []
if self.run_tests is False:
options.append('-DENABLE_TESTS=OFF')
else:
options.append('-DENABLE_TESTS=ON')
options.append(self.define_from_variant(
'BUILD_SHARED_LIBS', 'shared'))
options.append(self.define_from_variant(
'AXOM_ENABLE_EXAMPLES', 'examples'))
options.append(self.define_from_variant(
'AXOM_ENABLE_TOOLS', 'tools'))
return options
def patch(self):
if self.spec.satisfies('%cce'):
filter_file('PROPERTIES LINKER_LANGUAGE CXX',
'PROPERTIES LINKER_LANGUAGE CXX \n LINK_FLAGS "-fopenmp"',
'src/axom/quest/examples/CMakeLists.txt')