From 19c9f9f1fc76995f1c3ad220ad85f0eebe846bcd Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Sat, 25 Jul 2026 00:50:41 +0200 Subject: [PATCH] INSTALL - FIX - Make bundled-dependency builds honour FC/CC and embed rpath Three related build failures when the bundled netcdf/hdf5 stack is used with a compiler other than the one that first configured it. 1. The netcdf-c, netcdf-fortran and hdf5 rules run ./configure only when no Makefile is present, and never pass FC or CC to it. A tree first built with gfortran therefore keeps its gfortran configuration after FC is changed, and the Fortran codes then fail with error #7013: This module file was not generated by any release of this compiler. [NETCDF] followed by a long cascade of error #6683: A kind type parameter must be a compile-time constant. [R8] The second message is misleading: r8 is a PARAMETER in equil/local.f and is perfectly valid. The kind errors are collateral damage from the failed module read, and disappear once the module matches the compiler. This cost real debugging time, so the configure calls now pass CC, FC and F77 explicitly. 2. netcdf-fortran's configure links and *runs* test programs against the freshly installed netcdf-c. Without the install lib directory on the runtime search path those tests build but abort, and configure stops with the unhelpful configure: error: cannot compute sizeof (off_t) The configure calls now add -Wl,-rpath alongside the existing -L. 3. The codes themselves linked with -L$(NETCDFDIR) but no rpath, so they resolved against whatever libnetcdff the loader found first. That produced symbol lookup error: undefined symbol: netcdf_mp_nf90_create_ when a system netcdf shadowed the bundled one. NETCDF_EXTRA_LIBS now carries -Wl,-rpath for the Fortran and C library directories. A depsclean target is added, since plain clean leaves the dependency configuration in place and there was no supported way to switch toolchains. Verified by building the full stack and dcon, gpec and pentrc from scratch with FC=ifx CC=icx on Linux, and separately with FC=gfortran CC=gcc. --- install/DEFAULTS.inc | 12 ++++++++++++ install/TARGETS.inc | 8 ++++++-- install/makefile | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/install/DEFAULTS.inc b/install/DEFAULTS.inc index ec7793b67..dc59400c6 100644 --- a/install/DEFAULTS.inc +++ b/install/DEFAULTS.inc @@ -520,6 +520,18 @@ else endif endif +# Embed the netcdf library directories in the executables. Without this the +# codes link against $(NETCDFDIR) but resolve at run time against whatever the +# loader finds first, which fails with e.g. +# symbol lookup error: undefined symbol: netcdf_mp_nf90_create_ +# when a system netcdf shadows the bundled one, and silently mixes libraries +# when the two were built by different compilers. +NETCDF_RPATH = -Wl,-rpath,$(NETCDFDIR) +ifneq ($(NETCDF_C_DIR),$(NETCDFDIR)) + NETCDF_RPATH += -Wl,-rpath,$(NETCDF_C_DIR) +endif +NETCDF_EXTRA_LIBS += $(NETCDF_RPATH) + # Intel specifics #---------------- # include compiler specific libs for intel fast moves diff --git a/install/TARGETS.inc b/install/TARGETS.inc index b596e8c0a..0cbc65125 100644 --- a/install/TARGETS.inc +++ b/install/TARGETS.inc @@ -43,8 +43,9 @@ netcdf-c: v hdf5 cd ../; git submodule update --init deps/src/netcdf-c; if [ ! -f ../deps/src/netcdf-c/Makefile ]; then \ cd ../deps/src/netcdf-c; \ + CC="$(CC)" FC="$(FC)" F77="$(FC)" \ CPPFLAGS="-I$(realpath $(DEPSINSTALLDIR))/include" \ - LDFLAGS="-L$(realpath $(DEPSINSTALLDIR))/lib" \ + LDFLAGS="-L$(realpath $(DEPSINSTALLDIR))/lib -Wl,-rpath,$(realpath $(DEPSINSTALLDIR))/lib" \ ./configure --prefix=$(realpath $(DEPSINSTALLDIR)); \ fi cd ../deps/src/netcdf-c; \ @@ -56,8 +57,9 @@ netcdf-fortran: v netcdf-c cd ../; git submodule update --init deps/src/netcdf-fortran; if [ ! -f ../deps/src/netcdf-fortran/Makefile ]; then \ cd ../deps/src/netcdf-fortran; \ + CC="$(CC)" FC="$(FC)" F77="$(FC)" \ CPPFLAGS="-I$(realpath $(DEPSINSTALLDIR))/include" \ - LDFLAGS="-L$(realpath $(DEPSINSTALLDIR))/lib" \ + LDFLAGS="-L$(realpath $(DEPSINSTALLDIR))/lib -Wl,-rpath,$(realpath $(DEPSINSTALLDIR))/lib" \ ./configure --prefix=$(realpath $(DEPSINSTALLDIR)); \ fi cd ../deps/src/netcdf-fortran; \ @@ -69,6 +71,8 @@ hdf5: v cd ../; git submodule update --init deps/src/hdf5; if [ ! -f ../deps/src/hdf5/Makefile ]; then \ cd ../deps/src/hdf5; \ + CC="$(CC)" FC="$(FC)" \ + LDFLAGS="-Wl,-rpath,$(realpath $(DEPSINSTALLDIR))/lib" \ ./configure --prefix=$(realpath $(DEPSINSTALLDIR)); \ fi cd ../deps/src/hdf5; \ diff --git a/install/makefile b/install/makefile index 056de2ab6..f1912b8ef 100644 --- a/install/makefile +++ b/install/makefile @@ -116,6 +116,22 @@ realclean: clean clear # only for regenerating it when source USE/MODULE relationships change, and # require python3 (used by maintainers and the CI deps job, not end users). PYTHON ?= python3 +# Remove the autotools configuration of the bundled dependencies. The netcdf +# and hdf5 rules only run ./configure when no Makefile is present, so a plain +# `clean` keeps whatever toolchain configured them first. Switching FC/CC +# without this leaves gfortran-built module files in place, and the codes then +# fail with a confusing "module file was not generated by any release of this +# compiler" followed by cascading kind-parameter errors. +.PHONY: depsclean +depsclean: + for d in hdf5 netcdf-c netcdf-fortran; do \ + if [ -f ../deps/src/$$d/Makefile ]; then \ + (cd ../deps/src/$$d && $(MAKE) distclean >/dev/null 2>&1 || true); \ + fi; \ + rm -f ../deps/src/$$d/Makefile ../deps/src/$$d/config.cache; \ + done + rm -rf ../deps/lib/* ../deps/include/* ../deps/bin/* ../deps/share ../deps/hdf5 + .PHONY: deps checkdeps deps: $(PYTHON) gen_deps.py > DEPENDENCIES.inc