From 19c9f9f1fc76995f1c3ad220ad85f0eebe846bcd Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Sat, 25 Jul 2026 00:50:41 +0200 Subject: [PATCH 1/4] 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 From 24b84b998821f9026806d24a235d776f55ea52b3 Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Thu, 8 Oct 2026 07:06:38 +0200 Subject: [PATCH 2/4] INSTALL: scope dependency cleanup to the configured prefix --- install/makefile | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/install/makefile b/install/makefile index f1912b8ef..f2f4e57a4 100644 --- a/install/makefile +++ b/install/makefile @@ -111,17 +111,16 @@ realclean: clean clear if [ -f ../deps/src/netcdf-c/Makefile ]; then cd ../deps/src/netcdf-c && make clean; fi if [ -f ../deps/src/netcdf-fortran/Makefile ]; then cd ../deps/src/netcdf-fortran && make clean; fi -# Dependency graph (DEPENDENCIES.inc) maintenance. -# Building GPEC never needs these -- DEPENDENCIES.inc is committed. They are -# 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. +# Source checkouts stay in ../deps/src, independently of DEPSINSTALLDIR. +# Remove only compiler-dependent netcdf/hdf5 libraries and netcdf modules; +# headers and tools are replaced on installation. Other installed libraries, +# including OpenBLAS, are retained. .PHONY: depsclean depsclean: for d in hdf5 netcdf-c netcdf-fortran; do \ @@ -130,7 +129,14 @@ depsclean: 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 + rm -f "$(DEPSINSTALLDIR)"/lib/libnetcdf* "$(DEPSINSTALLDIR)"/lib/libhdf5* \ + "$(DEPSINSTALLDIR)"/include/netcdf*.mod "$(DEPSINSTALLDIR)"/include/typesizes.mod + +# Dependency graph (DEPENDENCIES.inc) maintenance. +# Building GPEC never needs these -- DEPENDENCIES.inc is committed. They are +# 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 .PHONY: deps checkdeps deps: From a1f259696431692176a57e0575bac8f38079775b Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Fri, 9 Oct 2026 13:51:49 +0200 Subject: [PATCH 3/4] INSTALL: centralize compiler exports and use realclean for toolchain changes --- install/DEFAULTS.inc | 12 ++++++------ install/TARGETS.inc | 3 --- install/makefile | 28 +++++----------------------- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/install/DEFAULTS.inc b/install/DEFAULTS.inc index dc59400c6..0c526e1e3 100644 --- a/install/DEFAULTS.inc +++ b/install/DEFAULTS.inc @@ -400,6 +400,10 @@ else $(error "Unsupported C compiler. Must set environment variable CC to a C compiler (e.g. gcc, icc, pgcc)") endif +# Pass the selected toolchain to dependency configure scripts and sub-makes. +export FC CC +export F77 = $(FC) + # List of needed dependencies, will be appended if math or netcdf # libraries are not found NEEDED_DEPS = @@ -520,12 +524,8 @@ 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. +# Embed the configured netcdf library directories for runtime lookup. +# These paths must remain available when running the executables. NETCDF_RPATH = -Wl,-rpath,$(NETCDFDIR) ifneq ($(NETCDF_C_DIR),$(NETCDFDIR)) NETCDF_RPATH += -Wl,-rpath,$(NETCDF_C_DIR) diff --git a/install/TARGETS.inc b/install/TARGETS.inc index 0cbc65125..e20d93276 100644 --- a/install/TARGETS.inc +++ b/install/TARGETS.inc @@ -43,7 +43,6 @@ 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 -Wl,-rpath,$(realpath $(DEPSINSTALLDIR))/lib" \ ./configure --prefix=$(realpath $(DEPSINSTALLDIR)); \ @@ -57,7 +56,6 @@ 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 -Wl,-rpath,$(realpath $(DEPSINSTALLDIR))/lib" \ ./configure --prefix=$(realpath $(DEPSINSTALLDIR)); \ @@ -71,7 +69,6 @@ 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 diff --git a/install/makefile b/install/makefile index f2f4e57a4..46e02b303 100644 --- a/install/makefile +++ b/install/makefile @@ -103,32 +103,14 @@ clear: cd ../docs/examples/solovev_kinetic_example; rm -f *.out *.bin *.nc cd ../docs/examples/solovev_resistive_example; rm -f *.out *.bin *.nc *.dat -# Revert to clean state +# Remove build products and dependency configuration before switching compilers. +# Dependency sources stay in ../deps/src; custom install prefixes are respected. realclean: clean clear rm -rf ../deps/lib/* ../deps/hdf5 ../deps/include/* ../deps/bin/* ../deps/share ../bin if [ -f ../deps/src/OpenBLAS/Makefile ]; then cd ../deps/src/OpenBLAS && make clean; fi - if [ -f ../deps/src/hdf5/Makefile ]; then cd ../deps/src/hdf5 && make clean; fi - if [ -f ../deps/src/netcdf-c/Makefile ]; then cd ../deps/src/netcdf-c && make clean; fi - if [ -f ../deps/src/netcdf-fortran/Makefile ]; then cd ../deps/src/netcdf-fortran && make clean; fi - -# 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. -# Source checkouts stay in ../deps/src, independently of DEPSINSTALLDIR. -# Remove only compiler-dependent netcdf/hdf5 libraries and netcdf modules; -# headers and tools are replaced on installation. Other installed libraries, -# including OpenBLAS, are retained. -.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 + if [ -f ../deps/src/hdf5/Makefile ]; then cd ../deps/src/hdf5 && $(MAKE) distclean; fi + if [ -f ../deps/src/netcdf-c/Makefile ]; then cd ../deps/src/netcdf-c && $(MAKE) distclean; fi + if [ -f ../deps/src/netcdf-fortran/Makefile ]; then cd ../deps/src/netcdf-fortran && $(MAKE) distclean; fi rm -f "$(DEPSINSTALLDIR)"/lib/libnetcdf* "$(DEPSINSTALLDIR)"/lib/libhdf5* \ "$(DEPSINSTALLDIR)"/include/netcdf*.mod "$(DEPSINSTALLDIR)"/include/typesizes.mod From 94f1b04c4095f005914f05318aa713ab1874b68d Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Fri, 9 Oct 2026 13:51:49 +0200 Subject: [PATCH 4/4] CI: check out fork branches from their source repository --- .github/workflows/make_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/make_test.yml b/.github/workflows/make_test.yml index d8077abcf..02a047bbf 100644 --- a/.github/workflows/make_test.yml +++ b/.github/workflows/make_test.yml @@ -18,6 +18,7 @@ jobs: steps: - uses: actions/checkout@v4 with: + repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} ref: ${{ github.head_ref }} - uses: actions/setup-python@v5 with: