forked from spack/spack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
esmf package: add (optional) Python bindings (spack#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).
- Loading branch information
1 parent
9ec8eaa
commit f0f9a16
Showing
1 changed file
with
64 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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("[email protected]: ~mpi", when="@8.5:+external-parallelio~mpi") | ||
depends_on("[email protected]:", 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 [email protected], 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) |