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.
This commit is contained in:
parent
84ab72557a
commit
2e9d0e146e
@ -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
|
@ -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()
|
||||
|
@ -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 @@ def configure_args(self):
|
||||
"--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 @@ def configure_args(self):
|
||||
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 @@ def configure_args(self):
|
||||
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 @@ def configure_args(self):
|
||||
|
||||
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")
|
||||
|
Loading…
Reference in New Issue
Block a user