CMake build system modifications for fms#6
Conversation
The combined fms_r{4,8} library bundles both C and Fortran object
files; the C objects reference libnetcdf, but only NetCDF::NetCDF_Fortran
was being re-exported to consumers. On NetCDF installs with split
lib/lib64 layouts (e.g. NCAR Derecho module: libnetcdf in lib64,
libnetcdff in lib), bare -lnetcdf flags from nf-config --flibs fail
to resolve at link time. Re-exporting NetCDF::NetCDF_C ensures its
absolute path reaches the link line.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates FMS’s CMake build so downstream find_package(FMS) consumers correctly build/link when using NetCDF installations where the C and Fortran libraries are split across different library directories.
Changes:
- Add
diag_manager/mppnccombine.cto the C source list so it is built under CMake (matching the existing automake build). - Export
NetCDF::NetCDF_Cas a PUBLIC link dependency offms_r4/fms_r8so downstream link lines reliably include the NetCDF C library via the imported target.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
johnmauff
left a comment
There was a problem hiding this comment.
@hctorres, Here is what Claude said about one of your changes.
Change 2: diag_manager/mppnccombine.c — likely a build-breaking bug
mppnccombine is a standalone post-processing utility that combines distributed NetCDF output files written by parallel MPI tasks. It has its own main() function. Adding it to the fms_c_src_files list means it gets compiled into libfms_r4.a and libfms_r8.a.
Any program that links against FMS will then have two main() symbols — its own and the one from mppnccombine.c — which causes a link error:
error: multiple definition of main
In FMS's existing Makefile build, mppnccombine is compiled as a separate standalone executable, not as part of the library. The CMake change should mirror that: a separate add_executable(mppnccombine diag_manager/mppnccombine.c) target with its own target_link_libraries, not an entry in the library source list.
The reason this may not have been caught in the turbo-stack end-to-end validation is that the test builds the FMS library and links MOM6 against it — but if no program in that test chain ever exercises the specific translation unit containing main() from mppnccombine.c, some linkers (particularly with static libraries) may silently omit it and only fail when a linker with stricter symbol resolution is used.
Recommendation: Remove diag_manager/mppnccombine.c from fms_c_src_files and replace with:
add_executable(mppnccombine diag_manager/mppnccombine.c)
target_link_libraries(mppnccombine PRIVATE NetCDF::NetCDF_C)
install(TARGETS mppnccombine RUNTIME DESTINATION bin)
|
@johnmauff I cant seem to get the duplicate main bug mentioned in the previous comment to trigger. I think we might be ok. |
Description
Two small CMake changes needed by turbo-stack's
find_package(FMS)consumer:diag_manager/mppnccombine.cto the cmake C source list (was already in the makefile build).NetCDF::NetCDF_Cto the PUBLIC link interface offms_r4andfms_r8. Without it, downstream consumers see onlyNetCDF::NetCDF_Fortran+ bare-lnetcdfflags fromnf-config --flibs, which fail to resolve at link time on NetCDF installs with splitlib/lib64layouts (e.g. NCAR Derecho's NetCDF module).This is part of the issue-192 cross-repo CMake build-system effort:
dev/turbomaindev/turbomainRecommended merge order: FMS → TIM → MOM6 → turbo-stack. turbo-stack consumes the other three via
find_package(FMS|TIM)andadd_subdirectory(${MOM6_SOURCE_DIR} ...).How Has This Been Tested?
Exercised end-to-end via the turbo-stack PR, which builds FMS2 from this branch and then links MOM6 against
FMS::fms_r8.