esmf package: add (optional) Python bindings (#45504)
* Add `+python` variant * `esmf` package installs Python bindings when `+python` is set Note: this does not inherit `PythonPackage`, which force an either/or choice between the Makefile and Pip builder: it instantiates a `PythonPipBuilder` as needed (when `+python` is set).
This commit is contained in:
parent
9ec8eaa0d3
commit
f0f9a16e4f
@ -10,7 +10,7 @@
|
||||
from spack.package import *
|
||||
|
||||
|
||||
class Esmf(MakefilePackage):
|
||||
class Esmf(MakefilePackage, PythonExtension):
|
||||
"""The Earth System Modeling Framework (ESMF) is high-performance, flexible
|
||||
software infrastructure for building and coupling weather, climate, and
|
||||
related Earth science applications. The ESMF defines an architecture for
|
||||
@ -97,6 +97,10 @@ class Esmf(MakefilePackage):
|
||||
description="Named variant for snapshots versions (e.g., 'b09')",
|
||||
)
|
||||
|
||||
# The way python is handled here is only avialable >=8.4.0
|
||||
# https://github.com/esmf-org/esmf/releases/tag/v8.4.0
|
||||
variant("python", default=False, description="Build python bindings", when="@8.4.0:")
|
||||
|
||||
# Optional dependencies
|
||||
depends_on("mpi", when="+mpi")
|
||||
depends_on("lapack@3:", when="+external-lapack")
|
||||
@ -112,6 +116,20 @@ class Esmf(MakefilePackage):
|
||||
depends_on("parallelio@2.5.10: ~mpi", when="@8.5:+external-parallelio~mpi")
|
||||
depends_on("cmake@3.5.2:", type="build", when="~external-parallelio")
|
||||
|
||||
# python library
|
||||
with when("+python"):
|
||||
extends("python")
|
||||
depends_on("py-pip")
|
||||
depends_on("py-setuptools", type="build")
|
||||
depends_on("py-wheel", type="build")
|
||||
depends_on("py-mpi4py", when="+mpi")
|
||||
depends_on("py-numpy")
|
||||
|
||||
# In esmf@8.4.0, esmx was introduced which depends on py-pyyaml
|
||||
with when("@8.4.0:"):
|
||||
depends_on("python", type="run")
|
||||
depends_on("py-pyyaml", type="run")
|
||||
|
||||
# Testing dependencies
|
||||
depends_on("perl", type="test")
|
||||
|
||||
@ -143,6 +161,29 @@ class Esmf(MakefilePackage):
|
||||
# https://github.com/spack/spack/issues/35957
|
||||
patch("esmf_cpp_info.patch")
|
||||
|
||||
@when("+python")
|
||||
def patch(self):
|
||||
# The pyproject.toml file uses a dynamically generated version from git
|
||||
# However, this results in a version of 0.0.0 and a mismatch with the loaded version
|
||||
# so this hardcodes it to match the library's version
|
||||
filter_file(
|
||||
"""dynamic = \\[\\s+"version"\\s+\\]""",
|
||||
f"""version = "{self.version}" """,
|
||||
os.path.join("src/addon/esmpy/pyproject.toml"),
|
||||
)
|
||||
|
||||
def setup_run_environment(self, env):
|
||||
env.set("ESMFMKFILE", os.path.join(self.prefix.lib, "esmf.mk"))
|
||||
|
||||
|
||||
class PythonPipBuilder(spack.build_systems.python.PythonPipBuilder):
|
||||
|
||||
@property
|
||||
def build_directory(self):
|
||||
return os.path.join(self.stage.source_path, "src/addon/esmpy")
|
||||
|
||||
|
||||
class MakefileBuilder(spack.build_systems.makefile.MakefileBuilder):
|
||||
# This is strictly required on Cray systems that use
|
||||
# the Cray compiler wrappers, where we need to swap
|
||||
# out the spack compiler wrappers in esmf.mk with the
|
||||
@ -214,38 +255,38 @@ def setup_build_environment(self, env):
|
||||
# ESMF_COMPILER must be set to select which Fortran and
|
||||
# C++ compilers are being used to build the ESMF library.
|
||||
|
||||
if self.compiler.name == "gcc":
|
||||
if self.pkg.compiler.name == "gcc":
|
||||
env.set("ESMF_COMPILER", "gfortran")
|
||||
with self.compiler.compiler_environment():
|
||||
with self.pkg.compiler.compiler_environment():
|
||||
gfortran_major_version = int(
|
||||
spack.compiler.get_compiler_version_output(
|
||||
self.compiler.fc, "-dumpversion"
|
||||
self.pkg.compiler.fc, "-dumpversion"
|
||||
).split(".")[0]
|
||||
)
|
||||
elif self.compiler.name == "intel" or self.compiler.name == "oneapi":
|
||||
elif self.pkg.compiler.name == "intel" or self.pkg.compiler.name == "oneapi":
|
||||
env.set("ESMF_COMPILER", "intel")
|
||||
elif self.compiler.name in ["clang", "apple-clang"]:
|
||||
elif self.pkg.compiler.name in ["clang", "apple-clang"]:
|
||||
env.set("ESMF_COMPILER", "gfortranclang")
|
||||
with self.compiler.compiler_environment():
|
||||
with self.pkg.compiler.compiler_environment():
|
||||
gfortran_major_version = int(
|
||||
spack.compiler.get_compiler_version_output(
|
||||
self.compiler.fc, "-dumpversion"
|
||||
self.pkg.compiler.fc, "-dumpversion"
|
||||
).split(".")[0]
|
||||
)
|
||||
elif self.compiler.name == "nag":
|
||||
elif self.pkg.compiler.name == "nag":
|
||||
env.set("ESMF_COMPILER", "nag")
|
||||
elif self.compiler.name == "pgi":
|
||||
elif self.pkg.compiler.name == "pgi":
|
||||
env.set("ESMF_COMPILER", "pgi")
|
||||
elif self.compiler.name == "nvhpc":
|
||||
elif self.pkg.compiler.name == "nvhpc":
|
||||
env.set("ESMF_COMPILER", "nvhpc")
|
||||
elif self.compiler.name == "cce":
|
||||
elif self.pkg.compiler.name == "cce":
|
||||
env.set("ESMF_COMPILER", "cce")
|
||||
elif self.compiler.name == "aocc":
|
||||
elif self.pkg.compiler.name == "aocc":
|
||||
env.set("ESMF_COMPILER", "aocc")
|
||||
else:
|
||||
msg = "The compiler you are building with, "
|
||||
msg += '"{0}", is not supported by ESMF.'
|
||||
raise InstallError(msg.format(self.compiler.name))
|
||||
raise InstallError(msg.format(self.pkg.compiler.name))
|
||||
|
||||
if "+mpi" in spec:
|
||||
env.set("ESMF_CXX", spec["mpi"].mpicxx)
|
||||
@ -265,7 +306,7 @@ def setup_build_environment(self, env):
|
||||
env.set("ESMF_BOPT", "O")
|
||||
|
||||
if (
|
||||
self.compiler.name in ["gcc", "clang", "apple-clang"]
|
||||
self.pkg.compiler.name in ["gcc", "clang", "apple-clang"]
|
||||
and gfortran_major_version >= 10
|
||||
and (self.spec.satisfies("@:8.2.99") or self.spec.satisfies("@8.3.0b09"))
|
||||
):
|
||||
@ -277,7 +318,7 @@ def setup_build_environment(self, env):
|
||||
|
||||
# ESMF_OS must be set for Cray systems
|
||||
# But spack no longer gives arch == cray
|
||||
if self.compiler.name == "cce" or "^cray-mpich" in self.spec:
|
||||
if self.pkg.compiler.name == "cce" or "^cray-mpich" in self.spec:
|
||||
env.set("ESMF_OS", "Unicos")
|
||||
|
||||
# Allow override of ESMF_OS:
|
||||
@ -430,5 +471,10 @@ def check(self):
|
||||
def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
env.set("ESMFMKFILE", os.path.join(self.prefix.lib, "esmf.mk"))
|
||||
|
||||
def setup_run_environment(self, env):
|
||||
env.set("ESMFMKFILE", os.path.join(self.prefix.lib, "esmf.mk"))
|
||||
def install(self, pkg, spec, prefix):
|
||||
make("install")
|
||||
|
||||
if "+python" in spec:
|
||||
# build the python library
|
||||
python_builder = PythonPipBuilder(pkg)
|
||||
python_builder.install(pkg, spec, prefix)
|
||||
|
Loading…
Reference in New Issue
Block a user