Skip to content

Implement CMake build system for TIM#16

Merged
hctorres merged 17 commits into
mainfrom
192-feature-cmake-build-system-for-TIM
Jun 22, 2026
Merged

Implement CMake build system for TIM#16
hctorres merged 17 commits into
mainfrom
192-feature-cmake-build-system-for-TIM

Conversation

@hctorres

@hctorres hctorres commented May 12, 2026

Copy link
Copy Markdown
Contributor

Part of issue-192 cross-repo CMake build system effort

This PR is one of four coordinated changes:

Repo PR Base
FMS TURBO-ESM/FMS#6 dev/turbo
TIM this PR main
MOM6 TURBO-ESM/MOM6#25 dev/turbo
turbo-stack TURBO-ESM/turbo-stack#233 main

Recommended merge order: FMS → TIM → MOM6 → turbo-stack.

Summary

  • Adds a full CMake build system with TIMConfig.cmake.in supporting FMS-style find_package(TIM COMPONENTS R4|R8)
    component selection.
  • Builds the C++ infrastructure layer (tim_coms_infra, tim_profile) as a separate tim static library linked into
    tim_r4 / tim_r8.
  • Exports TIM::tim_r4 and TIM::tim_r8 namespace alias targets; config files install to lib/cmake/tim/ for standard
    TIM_DIR hint compatibility.
  • Default component is derived from what was actually built (R8 if 64BIT=ON, else R4) so find_package(TIM) with no
    explicit COMPONENTS succeeds against any valid install.
  • TIMConfig.cmake resolves transitive deps (find_dependency(MPI|NetCDF|AMReX FORTRAN)) before including
    tim-targets.cmake, so the imported targets it references are defined when needed.
  • Adds build.sh with --debug (clean rebuild), --ninja (opt-in; default Unix Makefiles), and --build-dir options.
  • Removes the legacy build_cmake_gnu.yml CI workflow (no longer accurate; CMake build is now exercised end-to-end via
    the turbo-stack workflows).

Environment

For now you'll need MPI, NetCDF, and AMReX (with the FORTRAN component) available on CMAKE_PREFIX_PATH . turbo-stack has a script to set this up for you on derecho.

Test plan

  • find_package(TIM REQUIRED COMPONENTS R8) works from turbo-stack — verified by the turbo-stack workflows (Build
    MOM6 with TIM and FMS, Build Inside NCAR HPC Development Containers) all currently green.
  • Local TIM CI (Linux verification, intel_pr.yml) green on the latest push.from turbo-stack (verified via turbo-stack PR builds)

hctorres and others added 8 commits April 30, 2026 17:44
- Remove if(NOT build_type STREQUAL debug) guard on precision flags so
  -fdefault-real-8 is always applied to Fortran sources; without this,
  tim_chksum generic resolution fails at Debug build time because TIM
  compiles real as 4-byte while MOM6 always uses 8-byte.
- TIMConfig.cmake.in: add FMS-style R4/R8 component validation loop,
  default to R8, emit per-target status lines matching fms-config.cmake.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, --ninja flag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@hctorres hctorres self-assigned this May 12, 2026
@hctorres hctorres added the enhancement New feature or request label May 12, 2026
@hctorres
hctorres marked this pull request as draft May 12, 2026 17:56
@hctorres hctorres changed the title Add CMake build system for TIM Implement CMake build system for TIM May 15, 2026
hctorres and others added 6 commits May 19, 2026 10:57
TIM's C++ object files and the AMReX static archive it depends on
reference the C++ standard library (e.g. __cxa_call_terminate). When
the consuming executable is driven by gfortran -- or by a g++ install
whose CMAKE_CXX_IMPLICIT_LINK_LIBRARIES is empty (some spack-built
compilers on NCAR Derecho) -- libstdc++ never reaches the link line
and amrex symbols come up undefined.

Declare the C++ runtime explicitly via per-compiler generator
expressions so the dependency is honest and the link resolves
regardless of how the consumer's driver was configured.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit attached the stdc++/c++ generator expression to
tim_r{4,8}, which placed -lstdc++ before libamrex_3d.a in the
consumer's link line. GNU ld with --as-needed (default on some Linux
distros incl. NCAR Derecho) then dropped libstdc++ before AMReX's
undefined __cxa_call_terminate refs were seen, so the link still
failed.

Relocate the runtime to the tim target (the actual C++ shim that
pulls in AMReX), positioned after AMReX::amrex. That guarantees
-lstdc++ lands after libamrex_3d.a in the consumer's link order,
which is what --as-needed needs to see.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This workflow tested a standalone "libFMS via cmake" build inside a GFDL
container that has no AMReX. The CMakeLists in this repo now requires
AMReX, so the workflow has been failing on every push since TIM picked
up that dependency. The real cmake build path is covered by
turbo-stack's "Build MOM6 with TIM and FMS" job.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two consumer-facing bugs in the installed TIM cmake package:

1. TIMConfig.cmake.in included tim-targets.cmake BEFORE find_dependency().
   The exported targets reference NetCDF::, MPI::, AMReX::amrex by name;
   cmake errors out at include() because those imported targets don't yet
   exist. Resolve transitive deps first, then include tim-targets.cmake.

2. TIM_FIND_COMPONENTS defaulted to R8 even when TIM was built with the
   cmake default (32BIT=ON, 64BIT=OFF, R8 not installed). find_package(TIM)
   then succeeded with no usable target. Default the requested component
   to one of the components actually built (R8 if 64BIT=ON, else R4).

Plus targeted fixes uncovered during review:

- Save/restore CMAKE_MODULE_PATH instead of REMOVE_ITEM (drops a
  pre-existing matching entry).
- find_dependency(AMReX COMPONENTS FORTRAN) — consumers must get the
  same component TIM linked against.
- Drop CXX from MPI components — Fortran-only consumers shouldn't fail
  on systems lacking C++ MPI bindings.
- target_compile_features(tim PUBLIC cxx_std_20): tim_profile.hpp and
  tim_coms_infra_C_API.h ship in the public include interface, so the
  C++20 requirement must propagate.
- Map IntelLLVM to libstdc++ (its Linux default) instead of libc++ in
  the runtime-link genex.
- Rename installed file to TIMConfigVersion.cmake so versioned
  find_package(TIM <version>) works (cmake derives the version filename
  from the config stem).

@johnmauff johnmauff left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Let me know if you have any questions regarding my comments.

Comment thread CMakeLists.txt Outdated
Comment thread CMakeLists.txt
Comment thread .github/workflows/build_cmake_gnu.yml
Comment thread build.sh Outdated
Comment thread build.sh

@johnmauff johnmauff left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hctorres, thanks for the PR. This now looks good to me.

@mwaxmonsky mwaxmonsky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great @hctorres! Just had one question (that overlaps slightly with the MOM6 comments) but nothing that should hold up the PR.

Comment thread CMakeLists.txt
Comment thread build.sh Outdated
@hctorres
hctorres merged commit 2b1743c into main Jun 22, 2026
6 checks passed
@hctorres
hctorres deleted the 192-feature-cmake-build-system-for-TIM branch June 23, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants