From 9aa751721044ac2bffb26627a114b244f1f2f4c8 Mon Sep 17 00:00:00 2001 From: Lachlan Whyborn Date: Thu, 1 Oct 2026 12:06:48 +1000 Subject: [PATCH 1/6] Make PIO selectable via CLI build --- CMakeLists.txt | 17 +++++++++++------ build.bash | 6 +++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab640e4e5..8aa13c3d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,15 +7,20 @@ project( ) option(CABLE_MPI "Build the MPI executable" OFF) +option(CABLE_PIO "Build with PIO support (requires CABLE_MPI)" OFF) option(CABLE_TESTS "Build CABLE tests" OFF) +if(CABLE_PIO AND NOT CABLE_MPI) + message(FATAL_ERROR "CABLE_PIO requires CABLE_MPI to be enabled.") +endif() + # third party libs if(CABLE_MPI) find_package(MPI REQUIRED COMPONENTS Fortran) - find_package(PIO COMPONENTS Fortran QUIET) - if(TARGET PIO::PIO_Fortran) - message(STATUS "Found PIO_Fortran: ${PIO_DIR}") - endif() +endif() +if(CABLE_PIO) + find_package(PIO REQUIRED COMPONENTS Fortran) + message(STATUS "Found PIO_Fortran: ${PIO_DIR}") endif() find_package(PkgConfig REQUIRED) pkg_check_modules(NETCDF REQUIRED IMPORTED_TARGET "netcdf-fortran") @@ -381,7 +386,7 @@ else() target_link_libraries(cable_common PRIVATE MPI::MPI_Fortran) endif() - if(TARGET PIO::PIO_Fortran) + if(CABLE_PIO) target_link_libraries(cable_common PRIVATE PIO::PIO_Fortran) target_sources(cable_common PRIVATE src/util/netcdf/pio/cable_netcdf_pio.F90) else() @@ -424,7 +429,7 @@ else() target_sources(cable-tests PRIVATE tests/utils/fortuno_interface_serial.F90) endif() target_link_libraries(cable-tests PRIVATE cable_common ${fortuno_libs}) - if(NOT TARGET PIO::PIO_Fortran) + if(NOT CABLE_PIO) target_compile_definitions(cable-tests PRIVATE SKIP_PIO_TESTS) endif() if(CABLE_MPI) diff --git a/build.bash b/build.bash index 90e76fc31..d70ea956f 100755 --- a/build.bash +++ b/build.bash @@ -17,6 +17,7 @@ options below will be passed to CMake when generating the build system. Options: -c, --clean Delete build directory before invoking CMake. -m, --mpi Compile MPI executable. + --pio Build with PIO support. Requires --mpi. -C, --compiler Specify the compiler to use. -n, --ncpus @@ -45,7 +46,7 @@ EOF # DEFAULTS # Configure -cmake_args=(-DCMAKE_BUILD_TYPE=Release -DCABLE_MPI=OFF -DCABLE_LIBRARY=OFF) +cmake_args=(-DCMAKE_BUILD_TYPE=Release -DCABLE_MPI=OFF -DCABLE_PIO=OFF -DCABLE_LIBRARY=OFF) # Build build_args=() @@ -67,6 +68,9 @@ while [ ${#} -gt 0 ]; do mpi=1 cmake_args+=(-DCABLE_MPI="ON") ;; + --pio) + cmake_args+=(-DCABLE_PIO="ON") + ;; -l|--library) cmake_args+=(-DCABLE_LIBRARY="ON") cmake_args+=(-DCABLE_LIBRARY_TARGET="${2}") From 811d6f3b13d59ce55ba113f92997b10abe4e0857 Mon Sep 17 00:00:00 2001 From: Lachlan Whyborn Date: Thu, 1 Oct 2026 13:55:44 +1000 Subject: [PATCH 2/6] Minor restructure of CMakeLists.txt (#746) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thank you for submitting a pull request to the CABLE Project. Minor restructuring of `CMakeLists.txt` to make it more logical. The things that apply regardless of the library, which is the default config values, and the build flags are at the start. The branches for the library and non-library builds then encompass the rest of the build- when we build the library, we never want all the bells and whistles e.g. testing, NetCDF, PIO. - [x] Bug fix - [x] The new content is accessible and located in the appropriate section - [x] I have checked that links are valid and point to the intended content - [x] I have checked my code/text and corrected any misspellings - [x] Are the changes bitwise-compatible with the main branch? If working on an optional feature, are the results bitwise-compatible when this feature is off? If yes, copy benchcab output showing successful completion of the bitwise compatibility tests or equivalent results below this line. ---- 📚 Documentation preview 📚: https://cable--746.org.readthedocs.build/en/746/ --- CMakeLists.txt | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8aa13c3d5..b7e8d75c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,42 +10,6 @@ option(CABLE_MPI "Build the MPI executable" OFF) option(CABLE_PIO "Build with PIO support (requires CABLE_MPI)" OFF) option(CABLE_TESTS "Build CABLE tests" OFF) -if(CABLE_PIO AND NOT CABLE_MPI) - message(FATAL_ERROR "CABLE_PIO requires CABLE_MPI to be enabled.") -endif() - -# third party libs -if(CABLE_MPI) - find_package(MPI REQUIRED COMPONENTS Fortran) -endif() -if(CABLE_PIO) - find_package(PIO REQUIRED COMPONENTS Fortran) - message(STATUS "Found PIO_Fortran: ${PIO_DIR}") -endif() -find_package(PkgConfig REQUIRED) -pkg_check_modules(NETCDF REQUIRED IMPORTED_TARGET "netcdf-fortran") - -if(CABLE_TESTS) - if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "2024.0") - message(WARNING "Intel Fortran 2024.0 or higher is recommended for building tests.") - elseif(CMAKE_Fortran_COMPILER_ID MATCHES "GNU" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "14.1") - message(WARNING "GNU Fortran 14.1 or higher is recommended for building tests.") - endif() - enable_testing() - option(FORTUNO_WITH_MPI "Fortuno: whether to build the MPI interface" ${CABLE_MPI}) - if(CABLE_MPI) - set(fortuno_libs Fortuno::fortuno_mpi) - else() - set(fortuno_libs Fortuno::fortuno_serial) - endif () - include(FetchContent) - FetchContent_Declare(Fortuno - GIT_REPOSITORY https://github.com/fortuno-repos/fortuno - GIT_TAG eb61214fd76d6235a3072b6f8ed83d0380c2f266 - ) - FetchContent_MakeAvailable(Fortuno) -endif() - set(CABLE_Intel_Fortran_FLAGS -fp-model precise) set(CABLE_Intel_Fortran_FLAGS_DEBUG -O0 -g -traceback -fpe0) set(CABLE_Intel_Fortran_FLAGS_RELEASE -O2) @@ -70,8 +34,14 @@ endif() # Set the module directory to assist Spack set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include") + +# The library build is minimal: no MPI, no PIO, no NetCDF and no tests if(CABLE_LIBRARY) + if(CABLE_MPI OR CABLE_TESTS) + message(WARNING "CABLE_LIBRARY build: ignoring CABLE_MPI and CABLE_TESTS") + endif() + # Set the core sources set(SOURCES src/offline/cable_iovars.F90 @@ -132,7 +102,7 @@ if(CABLE_LIBRARY) src/science/soilsnow/cbl_surfbv.F90 src/science/soilsnow/cbl_thermal.F90 src/science/soilsnow/cbl_trimb.F90 - src/science/landuse/landuse3.F90 + src/science/landuse/landuse3.F90 src/science/landuse/landuse_constant.F90 src/params/cable_phys_constants_mod.F90 src/params/grid_constants_cbl.F90 @@ -210,7 +180,7 @@ if(CABLE_LIBRARY) src/coupled/AM3/casa/types/casa_dimension.F90 src/coupled/AM3/casa/types/casa_inout.F90 src/coupled/AM3/casa/types/casa_readbiome.F90 - src/offline/cable_surface_types.F90 + src/offline/cable_surface_types.F90 src/coupled/AM3/cable/landuse/casa_ESM15landuse.F90 ) if (CMAKE_Fortran_COMPILER_ID MATCHES "Intel") @@ -241,6 +211,38 @@ if(CABLE_LIBRARY) else() + # third party libs + if(CABLE_MPI) + find_package(MPI REQUIRED COMPONENTS Fortran) + find_package(PIO COMPONENTS Fortran QUIET) + if(TARGET PIO::PIO_Fortran) + message(STATUS "Found PIO_Fortran: ${PIO_DIR}") + endif() + endif() + if(CABLE_TESTS) + if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "2024.0") + message(WARNING "Intel Fortran 2024.0 or higher is recommended for building tests.") + elseif(CMAKE_Fortran_COMPILER_ID MATCHES "GNU" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "14.1") + message(WARNING "GNU Fortran 14.1 or higher is recommended for building tests.") + endif() + enable_testing() + option(FORTUNO_WITH_MPI "Fortuno: whether to build the MPI interface" ${CABLE_MPI}) + if(CABLE_MPI) + set(fortuno_libs Fortuno::fortuno_mpi) + else() + set(fortuno_libs Fortuno::fortuno_serial) + endif () + include(FetchContent) + FetchContent_Declare(Fortuno + GIT_REPOSITORY https://github.com/fortuno-repos/fortuno + GIT_TAG eb61214fd76d6235a3072b6f8ed83d0380c2f266 + ) + FetchContent_MakeAvailable(Fortuno) + endif() + + find_package(PkgConfig REQUIRED) + pkg_check_modules(NETCDF REQUIRED IMPORTED_TARGET "netcdf-fortran") + add_library( cable_common STATIC From 2ec8759029de033e2b3b84267cb25f97e34d92fe Mon Sep 17 00:00:00 2001 From: Lachlan Whyborn Date: Thu, 1 Oct 2026 15:02:09 +1000 Subject: [PATCH 3/6] Make PIO more obviously dependent on MPI --- CMakeLists.txt | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7e8d75c7..4c99835ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,8 +38,8 @@ set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include") # The library build is minimal: no MPI, no PIO, no NetCDF and no tests if(CABLE_LIBRARY) - if(CABLE_MPI OR CABLE_TESTS) - message(WARNING "CABLE_LIBRARY build: ignoring CABLE_MPI and CABLE_TESTS") + if(CABLE_MPI OR CABLE_PIO OR CABLE_TESTS) + message(WARNING "CABLE_LIBRARY build: ignoring CABLE_MPI, CABLE_PIO and CABLE_TESTS") endif() # Set the core sources @@ -211,11 +211,16 @@ if(CABLE_LIBRARY) else() + # PIO is an extension of the MPI build and cannot be enabled without it + if(CABLE_PIO AND NOT CABLE_MPI) + message(FATAL_ERROR "CABLE_PIO requires CABLE_MPI to be enabled") + endif() + # third party libs if(CABLE_MPI) find_package(MPI REQUIRED COMPONENTS Fortran) - find_package(PIO COMPONENTS Fortran QUIET) - if(TARGET PIO::PIO_Fortran) + if(CABLE_PIO) + find_package(PIO REQUIRED COMPONENTS Fortran) message(STATUS "Found PIO_Fortran: ${PIO_DIR}") endif() endif() @@ -384,13 +389,16 @@ else() target_link_libraries(cable_common PRIVATE PkgConfig::NETCDF) if(CABLE_MPI) - target_compile_definitions(cable_common PRIVATE __MPI__) - target_link_libraries(cable_common PRIVATE MPI::MPI_Fortran) - endif() + target_compile_definitions(cable_common PRIVATE __MPI__) + target_link_libraries(cable_common PRIVATE MPI::MPI_Fortran) - if(CABLE_PIO) - target_link_libraries(cable_common PRIVATE PIO::PIO_Fortran) - target_sources(cable_common PRIVATE src/util/netcdf/pio/cable_netcdf_pio.F90) + # PIO is only available as part of the MPI build + if(CABLE_PIO) + target_link_libraries(cable_common PRIVATE PIO::PIO_Fortran) + target_sources(cable_common PRIVATE src/util/netcdf/pio/cable_netcdf_pio.F90) + else() + target_sources(cable_common PRIVATE src/util/netcdf/pio/cable_netcdf_pio_stub.F90) + endif() else() target_sources(cable_common PRIVATE src/util/netcdf/pio/cable_netcdf_pio_stub.F90) endif() From e1643415ce1a32a856d25416d24605ae8ea5545a Mon Sep 17 00:00:00 2001 From: Lachlan Whyborn Date: Thu, 1 Oct 2026 15:48:40 +1000 Subject: [PATCH 4/6] Attempt to locate fortuno locally before cloning --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c99835ef..1379498b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,9 +238,11 @@ else() set(fortuno_libs Fortuno::fortuno_serial) endif () include(FetchContent) + # Use a locally installed Fortuno if one can be found, otherwise clone it FetchContent_Declare(Fortuno GIT_REPOSITORY https://github.com/fortuno-repos/fortuno GIT_TAG eb61214fd76d6235a3072b6f8ed83d0380c2f266 + FIND_PACKAGE_ARGS NAMES Fortuno ) FetchContent_MakeAvailable(Fortuno) endif() From 6b9c4fc0fa3dcb4da80e9f069ddf0df02d9ea0e8 Mon Sep 17 00:00:00 2001 From: Lachlan Whyborn Date: Thu, 1 Oct 2026 16:18:22 +1000 Subject: [PATCH 5/6] Make CI manifests test MPI and PIO builds --- .github/build-ci/manifests/gcc.spack.yaml.j2 | 1 + .github/build-ci/manifests/intel.spack.yaml.j2 | 1 + ...cces-esm1p6.spack.yaml.j2 => um7-access-esm1p6.spack.yaml.j2} | 0 3 files changed, 2 insertions(+) rename .github/build-ci/manifests/{um7-acces-esm1p6.spack.yaml.j2 => um7-access-esm1p6.spack.yaml.j2} (100%) diff --git a/.github/build-ci/manifests/gcc.spack.yaml.j2 b/.github/build-ci/manifests/gcc.spack.yaml.j2 index 259087da1..0ec7b8af5 100644 --- a/.github/build-ci/manifests/gcc.spack.yaml.j2 +++ b/.github/build-ci/manifests/gcc.spack.yaml.j2 @@ -4,6 +4,7 @@ spack: - path: $SPACK_MANIFEST_REPOSITORY_PATH/.github/build-ci/config specs: - cable@git.{{ ref }} + - cable@git.{{ ref }}+mpi+pio packages: all: require: diff --git a/.github/build-ci/manifests/intel.spack.yaml.j2 b/.github/build-ci/manifests/intel.spack.yaml.j2 index 4da5c8b25..9b4b614aa 100644 --- a/.github/build-ci/manifests/intel.spack.yaml.j2 +++ b/.github/build-ci/manifests/intel.spack.yaml.j2 @@ -4,6 +4,7 @@ spack: - path: $SPACK_MANIFEST_REPOSITORY_PATH/.github/build-ci/config specs: - cable@git.{{ ref }} + - cable@git.{{ ref }}+mpi+pio packages: all: require: diff --git a/.github/build-ci/manifests/um7-acces-esm1p6.spack.yaml.j2 b/.github/build-ci/manifests/um7-access-esm1p6.spack.yaml.j2 similarity index 100% rename from .github/build-ci/manifests/um7-acces-esm1p6.spack.yaml.j2 rename to .github/build-ci/manifests/um7-access-esm1p6.spack.yaml.j2 From 944e9dcd34ed8e1fcd103c4ed660a90a272fc818 Mon Sep 17 00:00:00 2001 From: Lachlan Whyborn Date: Tue, 13 Oct 2026 10:59:39 +1100 Subject: [PATCH 6/6] Revert back to automatically including PIO in MPI builds if available --- CMakeLists.txt | 21 +++++++++------------ build.bash | 6 +----- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eaca62be..81abc7eba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ project( ) option(CABLE_MPI "Build the MPI executable" OFF) -option(CABLE_PIO "Build with PIO support (requires CABLE_MPI)" OFF) option(CABLE_TESTS "Build CABLE tests" OFF) # Compiler flags are selected regardless of the type of build @@ -39,8 +38,8 @@ set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include") # The library build is minimal: no MPI, no PIO, no NetCDF and no tests if(CABLE_LIBRARY) - if(CABLE_MPI OR CABLE_PIO OR CABLE_TESTS) - message(WARNING "CABLE_LIBRARY build: ignoring CABLE_MPI, CABLE_PIO and CABLE_TESTS") + if(CABLE_MPI OR CABLE_TESTS) + message(WARNING "CABLE_LIBRARY build: ignoring CABLE_MPI and CABLE_TESTS") endif() # Set the core sources @@ -212,17 +211,15 @@ if(CABLE_LIBRARY) else() - # PIO is an extension of the MPI build and cannot be enabled without it - if(CABLE_PIO AND NOT CABLE_MPI) - message(FATAL_ERROR "CABLE_PIO requires CABLE_MPI to be enabled") - endif() - # third party libs if(CABLE_MPI) find_package(MPI REQUIRED COMPONENTS Fortran) - if(CABLE_PIO) - find_package(PIO REQUIRED COMPONENTS Fortran) + # PIO is an extension of the MPI build, and is used if it can be found + find_package(PIO COMPONENTS Fortran QUIET) + if(TARGET PIO::PIO_Fortran) message(STATUS "Found PIO_Fortran: ${PIO_DIR}") + else() + message(STATUS "PIO_Fortran not found: building without PIO support") endif() endif() if(CABLE_TESTS) @@ -396,7 +393,7 @@ else() target_link_libraries(cable_common PRIVATE MPI::MPI_Fortran) # PIO is only available as part of the MPI build - if(CABLE_PIO) + if(TARGET PIO::PIO_Fortran) target_link_libraries(cable_common PRIVATE PIO::PIO_Fortran) target_sources(cable_common PRIVATE src/util/netcdf/pio/cable_netcdf_pio.F90) else() @@ -442,7 +439,7 @@ else() target_sources(cable-tests PRIVATE tests/utils/fortuno_interface_serial.F90) endif() target_link_libraries(cable-tests PRIVATE cable_common ${fortuno_libs}) - if(NOT CABLE_PIO) + if(NOT TARGET PIO::PIO_Fortran) target_compile_definitions(cable-tests PRIVATE SKIP_PIO_TESTS) endif() if(CABLE_MPI) diff --git a/build.bash b/build.bash index d70ea956f..90e76fc31 100755 --- a/build.bash +++ b/build.bash @@ -17,7 +17,6 @@ options below will be passed to CMake when generating the build system. Options: -c, --clean Delete build directory before invoking CMake. -m, --mpi Compile MPI executable. - --pio Build with PIO support. Requires --mpi. -C, --compiler Specify the compiler to use. -n, --ncpus @@ -46,7 +45,7 @@ EOF # DEFAULTS # Configure -cmake_args=(-DCMAKE_BUILD_TYPE=Release -DCABLE_MPI=OFF -DCABLE_PIO=OFF -DCABLE_LIBRARY=OFF) +cmake_args=(-DCMAKE_BUILD_TYPE=Release -DCABLE_MPI=OFF -DCABLE_LIBRARY=OFF) # Build build_args=() @@ -68,9 +67,6 @@ while [ ${#} -gt 0 ]; do mpi=1 cmake_args+=(-DCABLE_MPI="ON") ;; - --pio) - cmake_args+=(-DCABLE_PIO="ON") - ;; -l|--library) cmake_args+=(-DCABLE_LIBRARY="ON") cmake_args+=(-DCABLE_LIBRARY_TARGET="${2}")