summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn W. Parent <45471568+johnwparent@users.noreply.github.com>2023-03-21 13:15:50 -0400
committerGitHub <noreply@github.com>2023-03-21 10:15:50 -0700
commit2e9d0e146eb71eff256aa250bd29c06840b27760 (patch)
tree190865690f845b0b44036ac58877f1b8df239cab
parent84ab72557ab3199038a12e3bb06b97d4477c2236 (diff)
downloadspack-2e9d0e146eb71eff256aa250bd29c06840b27760.tar.gz
spack-2e9d0e146eb71eff256aa250bd29c06840b27760.tar.bz2
spack-2e9d0e146eb71eff256aa250bd29c06840b27760.tar.xz
spack-2e9d0e146eb71eff256aa250bd29c06840b27760.zip
netcdf-c[xx]: CMake/Windows build (#34935)
netcdf-cxx and netcdf-c now build with CMake rather than Autotools. netcdf-c can still optionally build with Autotools (but defaults to CMake). With some additional patches to the CMake files, netcdf-c can use CMake to build on Windows.
-rw-r--r--var/spack/repos/builtin/packages/netcdf-c/4.8.1-win-hdf5-with-zlib.patch13
-rw-r--r--var/spack/repos/builtin/packages/netcdf-c/netcdfc-mpi-win-support.patch59
-rw-r--r--var/spack/repos/builtin/packages/netcdf-c/package.py157
3 files changed, 169 insertions, 60 deletions
diff --git a/var/spack/repos/builtin/packages/netcdf-c/4.8.1-win-hdf5-with-zlib.patch b/var/spack/repos/builtin/packages/netcdf-c/4.8.1-win-hdf5-with-zlib.patch
new file mode 100644
index 0000000000..6023e6d4ef
--- /dev/null
+++ b/var/spack/repos/builtin/packages/netcdf-c/4.8.1-win-hdf5-with-zlib.patch
@@ -0,0 +1,13 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index ba66a6d4..217aa712 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -856,7 +856,7 @@ IF(USE_HDF5)
+ # This needs to be near the beginning since we
+ # need to know whether to add "-lz" to the symbol
+ # tests below.
+- CHECK_C_SOURCE_COMPILES("#include <H5public.h>
++ CHECK_C_SOURCE_COMPILES("#include <H5pubconf.h>
+ #if !H5_HAVE_ZLIB_H
+ #error
+ #endif
diff --git a/var/spack/repos/builtin/packages/netcdf-c/netcdfc-mpi-win-support.patch b/var/spack/repos/builtin/packages/netcdf-c/netcdfc-mpi-win-support.patch
new file mode 100644
index 0000000000..c873af1daa
--- /dev/null
+++ b/var/spack/repos/builtin/packages/netcdf-c/netcdfc-mpi-win-support.patch
@@ -0,0 +1,59 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 9b057311..37e96a96 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1471,6 +1471,7 @@ ENDIF()
+
+ # Enable Parallel IO with netCDF-4/HDF5 files using HDF5 parallel I/O.
+ SET(STATUS_PARALLEL "OFF")
++set(IMPORT_MPI "")
+ OPTION(ENABLE_PARALLEL4 "Build netCDF-4 with parallel IO" "${HDF5_PARALLEL}")
+ IF(ENABLE_PARALLEL4 AND ENABLE_HDF5)
+ IF(NOT HDF5_PARALLEL)
+@@ -1492,6 +1493,7 @@ IF(ENABLE_PARALLEL4 AND ENABLE_HDF5)
+ FILE(COPY "${netCDF_BINARY_DIR}/tmp/run_par_tests.sh"
+ DESTINATION ${netCDF_BINARY_DIR}/h5_test
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
++ set(IMPORT_MPI "include(CMakeFindDependencyMacro)\nfind_dependency(mpi COMPONENTS C)")
+ ENDIF()
+ ENDIF()
+
+diff --git a/liblib/CMakeLists.txt b/liblib/CMakeLists.txt
+index e3eddc0f..0493cb9d 100644
+--- a/liblib/CMakeLists.txt
++++ b/liblib/CMakeLists.txt
+@@ -50,6 +50,7 @@ ADD_LIBRARY(netcdf nc_initialize.c ${LARGS} )
+
+ IF(MPI_C_INCLUDE_PATH)
+ target_include_directories(netcdf PUBLIC ${MPI_C_INCLUDE_PATH})
++ target_link_libraries(netcdf PUBLIC MPI::MPI_C)
+ ENDIF(MPI_C_INCLUDE_PATH)
+
+ IF(MOD_NETCDF_NAME)
+diff --git a/netCDFConfig.cmake.in b/netCDFConfig.cmake.in
+index 9d68eec5..dae2429e 100644
+--- a/netCDFConfig.cmake.in
++++ b/netCDFConfig.cmake.in
+@@ -14,6 +14,8 @@ set(netCDF_LIBRARIES netCDF::netcdf)
+ # include target information
+ include("${CMAKE_CURRENT_LIST_DIR}/netCDFTargets.cmake")
+
++@IMPORT_MPI@
++
+ # Compiling Options
+ #
+ set(netCDF_C_COMPILER "@CC_VERSION@")
+diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
+index 65891d82..15567c8f 100644
+--- a/plugins/CMakeLists.txt
++++ b/plugins/CMakeLists.txt
+@@ -62,6 +62,9 @@ MACRO(buildplugin TARGET TARGETLIB)
+ set_target_properties(${TARGET} PROPERTIES LINK_FLAGS "/INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF")
+ # Set file name & location
+ set_target_properties(${TARGET} PROPERTIES COMPILE_PDB_NAME ${TARGET} COMPILE_PDB_OUTPUT_DIR ${CMAKE_BINARY_DIR})
++ IF(MPI_C_INCLUDE_PATH)
++ target_include_directories(${TARGET} PRIVATE ${MPI_C_INCLUDE_PATH})
++ ENDIF(MPI_C_INCLUDE_PATH)
+ ENDIF()
+ ENDMACRO()
+
diff --git a/var/spack/repos/builtin/packages/netcdf-c/package.py b/var/spack/repos/builtin/packages/netcdf-c/package.py
index dd106fbc62..f7024353d0 100644
--- a/var/spack/repos/builtin/packages/netcdf-c/package.py
+++ b/var/spack/repos/builtin/packages/netcdf-c/package.py
@@ -4,11 +4,14 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
+import sys
+from spack.build_systems.autotools import AutotoolsBuilder
+from spack.build_systems.cmake import CMakeBuilder
from spack.package import *
-class NetcdfC(AutotoolsPackage):
+class NetcdfC(CMakePackage, AutotoolsPackage):
"""NetCDF (network Common Data Form) is a set of software libraries and
machine-independent data formats that support the creation, access, and
sharing of array-oriented scientific data. This is the C distribution."""
@@ -62,6 +65,9 @@ class NetcdfC(AutotoolsPackage):
when="@4.7.2",
)
+ patch("4.8.1-win-hdf5-with-zlib.patch", when="@4.8.1: platform=windows")
+
+ patch("netcdfc-mpi-win-support.patch", when="platform=windows")
# See https://github.com/Unidata/netcdf-c/pull/1752
patch("4.7.3-spectrum-mpi-pnetcdf-detect.patch", when="@4.7.3:4.7.4 +parallel-netcdf")
@@ -89,11 +95,13 @@ class NetcdfC(AutotoolsPackage):
# description='Enable CDM Remote support')
# The patch for 4.7.0 touches configure.ac. See force_autoreconf below.
- depends_on("autoconf", type="build", when="@4.7.0,main")
- depends_on("automake", type="build", when="@4.7.0,main")
- depends_on("libtool", type="build", when="@4.7.0,main")
+ with when("build_system=autotools"):
+ depends_on("autoconf", type="build", when="@4.7.0,main")
+ depends_on("automake", type="build", when="@4.7.0,main")
+ depends_on("libtool", type="build", when="@4.7.0,main")
+ # CMake system can use m4, but Windows does not yet support
+ depends_on("m4", type="build", when=sys.platform != "win32")
- depends_on("m4", type="build")
depends_on("hdf~netcdf", when="+hdf4")
# curl 7.18.0 or later is required:
@@ -145,13 +153,72 @@ class NetcdfC(AutotoolsPackage):
filter_compiler_wrappers("nc-config", relative_root="bin")
+ default_build_system = "cmake" if sys.platform == "win32" else "autotools"
+
+ build_system("cmake", "autotools", default=default_build_system)
+
+ def setup_run_environment(self, env):
+ if "+zstd" in self.spec:
+ env.append_path("HDF5_PLUGIN_PATH", self.prefix.plugins)
+
+ @property
+ def libs(self):
+ shared = "+shared" in self.spec
+ return find_libraries("libnetcdf", root=self.prefix, shared=shared, recursive=True)
+
+
+class Setup:
+ def setup_dependent_build_environment(self, env, dependent_spec):
+ self.pkg.setup_run_environment(env)
+ # Some packages, e.g. ncview, refuse to build if the compiler path returned by nc-config
+ # differs from the path to the compiler that the package should be built with. Therefore,
+ # we have to shadow nc-config from self.prefix.bin, which references the real compiler,
+ # with a backed up version, which references Spack compiler wrapper.
+ if os.path.exists(self._nc_config_backup_dir):
+ env.prepend_path("PATH", self._nc_config_backup_dir)
+
+
+class BackupStep:
+ @property
+ def _nc_config_backup_dir(self):
+ return join_path(self.pkg.metadata_dir, "spack-nc-config")
+
+ @run_after("install")
+ def backup_nc_config(self):
+ # We expect this to be run before filter_compiler_wrappers:
+ nc_config_file = self.prefix.bin.join("nc-config")
+ if os.path.exists(nc_config_file):
+ mkdirp(self._nc_config_backup_dir)
+ install(nc_config_file, self._nc_config_backup_dir)
+
+
+class CMakeBuilder(CMakeBuilder, BackupStep, Setup):
+ def cmake_args(self):
+ base_cmake_args = [
+ self.define_from_variant("BUILD_SHARED_LIBS", "shared"),
+ self.define("BUILD_UTILITIES", True),
+ self.define("ENABLE_NETCDF_4", True),
+ self.define_from_variant("ENABLE_DAP", "dap"),
+ self.define("CMAKE_INSTALL_PREFIX", self.prefix),
+ self.define_from_variant("ENABLE_HDF4", "hdf4"),
+ self.define("ENABLE_PARALLEL_TESTS", False),
+ self.define_from_variant("ENABLE_FSYNC", "fsync"),
+ self.define("ENABLE_LARGE_FILE_SUPPORT", True),
+ ]
+ if "+parallel-netcdf" in self.pkg.spec:
+ base_cmake_args.append(self.define("ENABLE_PNETCDF", True))
+ if self.pkg.spec.satisfies("@4.3.1:"):
+ base_cmake_args.append(self.define("ENABLE_DYNAMIC_LOADING", True))
+ return base_cmake_args
+
+
+class AutotoolsBuilder(AutotoolsBuilder, BackupStep, Setup):
@property
def force_autoreconf(self):
# The patch for 4.7.0 touches configure.ac.
- return self.spec.satisfies("@4.7.0")
+ return self.pkg.spec.satisfies("@4.7.0")
- @when("@4.6.3:")
- def autoreconf(self, spec, prefix):
+ def autoreconf(self, pkg, spec, prefix):
if not os.path.exists(self.configure_abs_path):
Executable("./bootstrap")()
@@ -169,57 +236,57 @@ class NetcdfC(AutotoolsPackage):
"--enable-netcdf-4",
]
- if "+optimize" in self.spec:
+ if "+optimize" in self.pkg.spec:
cflags.append("-O2")
config_args.extend(self.enable_or_disable("fsync"))
# The flag was introduced in version 4.3.1
- if self.spec.satisfies("@4.3.1:"):
+ if self.pkg.spec.satisfies("@4.3.1:"):
config_args.append("--enable-dynamic-loading")
config_args += self.enable_or_disable("shared")
- if "+pic" in self.spec:
- cflags.append(self.compiler.cc_pic_flag)
+ if "+pic" in self.pkg.spec:
+ cflags.append(self.pkg.compiler.cc_pic_flag)
config_args += self.enable_or_disable("dap")
# config_args += self.enable_or_disable('cdmremote')
- # if '+dap' in self.spec or '+cdmremote' in self.spec:
- if "+dap" in self.spec:
+ # if '+dap' in self.pkg.spec or '+cdmremote' in self.pkg.spec:
+ if "+dap" in self.pkg.spec:
# Make sure Netcdf links against Spack's curl, otherwise it may
# pick up system's curl, which can give link errors, e.g.:
# undefined reference to `SSL_CTX_use_certificate_chain_file
- curl = self.spec["curl"]
+ curl = self.pkg.spec["curl"]
curl_libs = curl.libs
libs.append(curl_libs.link_flags)
ldflags.append(curl_libs.search_flags)
# TODO: figure out how to get correct flags via headers.cpp_flags
cppflags.append("-I" + curl.prefix.include)
- elif self.spec.satisfies("@4.8.0:"):
+ elif self.pkg.spec.satisfies("@4.8.0:"):
# Prevent overlinking to a system installation of libcurl:
config_args.append("ac_cv_lib_curl_curl_easy_setopt=no")
- if self.spec.satisfies("@4.4:"):
- if "+mpi" in self.spec:
+ if self.pkg.spec.satisfies("@4.4:"):
+ if "+mpi" in self.pkg.spec:
config_args.append("--enable-parallel4")
else:
config_args.append("--disable-parallel4")
- if self.spec.satisfies("@4.3.2:"):
+ if self.pkg.spec.satisfies("@4.3.2:"):
config_args += self.enable_or_disable("jna")
# Starting version 4.1.3, --with-hdf5= and other such configure options
# are removed. Variables CPPFLAGS, LDFLAGS, and LD_LIBRARY_PATH must be
# used instead.
- hdf5_hl = self.spec["hdf5:hl"]
+ hdf5_hl = self.pkg.spec["hdf5:hl"]
cppflags.append(hdf5_hl.headers.cpp_flags)
ldflags.append(hdf5_hl.libs.search_flags)
- if "+parallel-netcdf" in self.spec:
+ if "+parallel-netcdf" in self.pkg.spec:
config_args.append("--enable-pnetcdf")
- pnetcdf = self.spec["parallel-netcdf"]
+ pnetcdf = self.pkg.spec["parallel-netcdf"]
cppflags.append(pnetcdf.headers.cpp_flags)
# TODO: change to pnetcdf.libs.search_flags once 'parallel-netcdf'
# package gets custom implementation of 'libs'
@@ -227,17 +294,17 @@ class NetcdfC(AutotoolsPackage):
else:
config_args.append("--disable-pnetcdf")
- if "+mpi" in self.spec or "+parallel-netcdf" in self.spec:
- config_args.append("CC=%s" % self.spec["mpi"].mpicc)
+ if "+mpi" in self.pkg.spec or "+parallel-netcdf" in self.pkg.spec:
+ config_args.append("CC=%s" % self.pkg.spec["mpi"].mpicc)
config_args += self.enable_or_disable("hdf4")
- if "+hdf4" in self.spec:
- hdf4 = self.spec["hdf"]
+ if "+hdf4" in self.pkg.spec:
+ hdf4 = self.pkg.spec["hdf"]
cppflags.append(hdf4.headers.cpp_flags)
# TODO: change to hdf4.libs.search_flags once 'hdf'
# package gets custom implementation of 'libs' property.
ldflags.append("-L" + hdf4.prefix.lib)
- # TODO: change to self.spec['jpeg'].libs.link_flags once the
+ # TODO: change to self.pkg.spec['jpeg'].libs.link_flags once the
# implementations of 'jpeg' virtual package get 'jpeg_libs'
# property.
libs.append("-ljpeg")
@@ -247,12 +314,12 @@ class NetcdfC(AutotoolsPackage):
if "+external-xdr" in hdf4 and hdf4["rpc"].name != "libc":
libs.append(hdf4["rpc"].libs.link_flags)
- if "+zstd" in self.spec:
- zstd = self.spec["zstd"]
+ if "+zstd" in self.pkg.spec:
+ zstd = self.pkg.spec["zstd"]
cppflags.append(zstd.headers.cpp_flags)
ldflags.append(zstd.libs.search_flags)
config_args.append("--with-plugin-dir={}".format(self.prefix.plugins))
- elif "~zstd" in self.spec:
+ elif "~zstd" in self.pkg.spec:
# Prevent linking to system zstd.
# There is no explicit option to disable zstd.
config_args.append("ac_cv_lib_zstd_ZSTD_compress=no")
@@ -268,36 +335,6 @@ class NetcdfC(AutotoolsPackage):
return config_args
- def setup_run_environment(self, env):
- if "+zstd" in self.spec:
- env.append_path("HDF5_PLUGIN_PATH", self.prefix.plugins)
-
- def setup_dependent_build_environment(self, env, dependent_spec):
- self.setup_run_environment(env)
- # Some packages, e.g. ncview, refuse to build if the compiler path returned by nc-config
- # differs from the path to the compiler that the package should be built with. Therefore,
- # we have to shadow nc-config from self.prefix.bin, which references the real compiler,
- # with a backed up version, which references Spack compiler wrapper.
- if os.path.exists(self._nc_config_backup_dir):
- env.prepend_path("PATH", self._nc_config_backup_dir)
-
- @run_after("install")
- def backup_nc_config(self):
- # We expect this to be run before filter_compiler_wrappers:
- nc_config_file = self.prefix.bin.join("nc-config")
- if os.path.exists(nc_config_file):
- mkdirp(self._nc_config_backup_dir)
- install(nc_config_file, self._nc_config_backup_dir)
-
def check(self):
# h5_test fails when run in parallel
make("check", parallel=False)
-
- @property
- def libs(self):
- shared = "+shared" in self.spec
- return find_libraries("libnetcdf", root=self.prefix, shared=shared, recursive=True)
-
- @property
- def _nc_config_backup_dir(self):
- return join_path(self.metadata_dir, "spack-nc-config")