Improve NCL variant support and fix hdf-eos5 issues (#41259)

This commit is contained in:
Brian Vanderwende 2024-01-29 07:28:32 -07:00 committed by GitHub
parent 6c48effbf5
commit 2170386ad9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 80 additions and 19 deletions

View File

@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
from os import chmod
from spack.package import *
@ -77,15 +78,24 @@ def url_for_version(self, version):
"version/checksum not found in version_list".format(version)
)
@run_before("configure")
def fix_configure(self):
# spack patches the configure file unless autoconf is run,
# and this fails because configure has the wrong permissions (644)
if not self.force_autoreconf:
chmod(join_path(self.stage.source_path, "configure"), 0o755)
# The configure script as written really wants you to use h5cc. This causes
# problems because h5cc differs when HDF5 is built with autotools vs cmake,
# and we lose all nice flags from the Spack wrappers. These filter operations
# allow use to use the Spack wrappers again.
with keep_modification_time("configure"):
filter_file(r"$CC -show &> /dev/null", "true", "configure", string=True)
filter_file(r"CC=./$SZIP_CC", "", "configure", string=True)
def configure_args(self):
extra_args = []
# Package really wants h5cc to be used
if self.spec["mpi"]:
extra_args.append("CC={0}/bin/h5pcc -Df2cFortran".format(self.spec["hdf5"].prefix))
else:
extra_args.append("CC={0}/bin/h5cc -Df2cFortran".format(self.spec["hdf5"].prefix))
# We always build PIC code
extra_args.append("--with-pic")
# We always enable installation of include directories

View File

@ -58,11 +58,17 @@ class Ncl(Package):
# http://www.ncl.ucar.edu/Download/build_from_src.shtml
variant("hdf4", default=False, description="Enable HDF4 support.")
variant("hdf-eos2", default=False, when="+hdf4", description="Enable HDF-EOS2 support.")
variant("hdf-eos5", default=False, description="Enable HDF-EOS5 support.")
variant("gdal", default=False, description="Enable GDAL support.")
variant("triangle", default=True, description="Enable Triangle support.")
variant("udunits2", default=True, description="Enable UDUNITS-2 support.")
variant("openmp", default=True, description="Enable OpenMP support.")
variant("grib", default=True, description="Enable GRIB support.")
variant("eemd", default=False, description="Enable EEMD support.")
# The following variant is typically set for little-endian targets
variant("byteswapped", default=True, description="Use byteswapped mode for binary data.")
# Non-optional dependencies according to the manual:
depends_on("jpeg")
@ -107,9 +113,12 @@ class Ncl(Package):
# Some of the optional dependencies according to the manual:
depends_on("hdf", when="+hdf4")
depends_on("hdf-eos2", when="+hdf-eos2")
depends_on("hdf-eos5", when="+hdf-eos5")
depends_on("gdal@:2.4", when="+gdal")
depends_on("udunits", when="+udunits2")
depends_on("jasper@2.0.32", when="+grib")
depends_on("jasper@:2", when="+grib")
depends_on("gsl", when="+eemd")
# We need src files of triangle to appear in ncl's src tree if we want
# triangle's features.
@ -154,14 +163,45 @@ def install(self, spec, prefix):
if "ncl" not in exes:
raise RuntimeError("Installation failed (ncl executable was not created)")
# NCL provides compiler wrappers, but they make assumptions that Spack build
# will not conform to. This section edits the wrappers to fix them.
c_wrappers = ["ncargcc", "nhlcc"]
f77_wrappers = ["ncargf77", "nhlf77"]
f90_wrappers = ["ncargf90", "nhlf90"]
lib_paths = []
for dep in spec.dependencies(deptype="link"):
lib_paths.append(spec[dep.name].prefix.lib)
with working_dir(spec.prefix.bin):
# Change NCARG compiler wrappers to use real compiler, not Spack wrappers
for wrapper in c_wrappers:
filter_file(spack_cc, self.compiler.cc, wrapper)
for wrapper in f77_wrappers:
filter_file(spack_f77, self.compiler.f77, wrapper)
for wrapper in f90_wrappers:
filter_file(spack_fc, self.compiler.fc, wrapper)
# Make library reference and corrections to wrappers
for wrapper in c_wrappers + f77_wrappers + f90_wrappers:
filter_file(
"^(set syslibdir[ ]*=).*",
r'\1 "{}"'.format(" ".join(["-L{}".format(p) for p in lib_paths])),
wrapper,
)
filter_file("^(set cairolib[ ]*=).*", r'\1 "-lcairo -lfreetype"', wrapper)
def setup_run_environment(self, env):
env.set("NCARG_ROOT", self.spec.prefix)
# We cannot rely on Spack knowledge of esmf when NCL is an external
if not self.spec.external:
env.set("ESMFBINDIR", self.spec["esmf"].prefix.bin)
def prepare_site_config(self):
fc_flags = []
cc_flags = []
c2f_flags = []
fc_flags = [self.compiler.fc_pic_flag]
cc_flags = [self.compiler.cc_pic_flag]
c2f_flags = [self.compiler.cc_pic_flag]
if "+openmp" in self.spec:
fc_flags.append(self.compiler.openmp_flag)
@ -196,6 +236,9 @@ def prepare_site_config(self):
f.writelines(
[
"#define HdfDefines\n",
"#define StdDefines -DByteSwapped\n#define ByteSwapped\n"
if self.spec.satisfies("+byteswapped")
else "",
"#define CppCommand '/usr/bin/env cpp -traditional'\n",
"#define CCompiler {0}\n".format(spack_cc),
"#define FCompiler {0}\n".format(spack_fc),
@ -280,17 +323,17 @@ def prepare_install_config(self):
# Build GDAL support (optional) into NCL?
"y\n" if "+gdal" in self.spec else "n\n",
# Build EEMD support (optional) into NCL?
"n\n",
"y\n" if "+eemd" in self.spec else "n\n",
# Build Udunits-2 support (optional) into NCL?
"y\n" if "+udunits2" in self.spec else "n\n",
# Build Vis5d+ support (optional) into NCL?
"n\n",
# Build HDF-EOS2 support (optional) into NCL?
"n\n",
"y\n" if "+hdf-eos2" in self.spec else "n\n",
# Build HDF5 support (optional) into NCL?
"y\n",
# Build HDF-EOS5 support (optional) into NCL?
"n\n",
"y\n" if "+hdf-eos5" in self.spec else "n\n",
# Build GRIB2 support (optional) into NCL?
"y\n" if self.spec.satisfies("+grib") else "n\n",
# Enter local library search path(s) :
@ -300,7 +343,7 @@ def prepare_install_config(self):
+ " "
+ self.spec["bzip2"].prefix.lib
+ (
(" " + self.spec["jasper"].prefix.lib64)
(" " + self.spec["jasper"].libs.directories[0])
if self.spec.satisfies("+grib")
else ""
)
@ -326,11 +369,16 @@ def prepare_install_config(self):
if self.spec.satisfies("^hdf+external-xdr") and not self.spec["hdf"].satisfies("^libc"):
hdf4 = self.spec["hdf"]
replace_str = hdf4["rpc"].libs.link_flags
if self.spec.satisfies("^hdf+szip"):
search_str = "#define HDFlib.*"
else:
search_str = "#define IncSearch.*"
replace_str = "\n#define HDFlib {} {}".format(hdf4.libs.link_flags, replace_str)
filter_file(
"(#define HDFlib.*)",
r"\1 {}".format(hdf4["rpc"].libs.link_flags),
"config/Site.local",
"({})".format(search_str), r"\1 " + "{}".format(replace_str), "config/Site.local"
)
def prepare_src_tree(self):
@ -351,7 +399,10 @@ def delete_files(*filenames):
@when("+grib")
def patch(self):
# Newer versions of libjasper do not provide the inmem property
if self.spec.satisfies("^jasper@2"):
filter_file("image.inmem_=1;", "", "external/g2clib-1.6.0/enc_jpeg2000.c")
filter_file("SUBDIRS = ", "SUBDIRS = g2clib-1.6.0 ", "external/yMakefile")
filter_file(
"INC=.*",