chore: version and changelog updates for 2024.03 (#1574)
[FMS.git] / CMakeLists.txt
blobaa2b9c015e88ea2d4bee81202282aa5a8a2eba59
1 #***********************************************************************
2 #*                   GNU Lesser General Public License
3 #*
4 #* This file is part of the GFDL Flexible Modeling System (FMS).
5 #*
6 #* FMS is free software: you can redistribute it and/or modify it under
7 #* the terms of the GNU Lesser General Public License as published by
8 #* the Free Software Foundation, either version 3 of the License, or (at
9 #* your option) any later version.
11 #* FMS is distributed in the hope that it will be useful, but WITHOUT
12 #* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 #* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 #* for more details.
16 #* You should have received a copy of the GNU Lesser General Public
17 #* License along with FMS.  If not, see <http://www.gnu.org/licenses/>.
18 #***********************************************************************
20 # Copyright (c) GFDL, @underwoo
22 cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
24 # Define the CMake project
25 project(FMS
26   VERSION 2024.03.0
27   DESCRIPTION  "GFDL FMS Library"
28   HOMEPAGE_URL "https://www.gfdl.noaa.gov/fms"
29   LANGUAGES C Fortran)
31 include(GNUInstallDirs)
33 if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)$")
34   message(STATUS "Setting build type to 'Release' as none was specified.")
35   set(CMAKE_BUILD_TYPE
36       "Release"
37       CACHE STRING "Choose the type of build." FORCE)
38   set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
39 endif()
41 if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Intel|GNU|Clang|IntelLLVM)$")
42   message(
43     WARNING "Compiler not officially supported: ${CMAKE_C_COMPILER_ID}")
44 endif()
46 if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|GNU|IntelLLVM)$")
47   message(
48     WARNING "Compiler not officially supported: ${CMAKE_Fortran_COMPILER_ID}")
49 endif()
51 # Append directory that contains CMake Modules for building FMS
52 list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
54 # Build options
55 option(OPENMP      "Build FMS with OpenMP support"        OFF)
56 option(32BIT       "Build 32-bit (r4) FMS library"         ON)
57 option(64BIT       "Build 64-bit (r8) FMS library"        OFF)
58 option(FPIC        "Build with position independent code" OFF)
59 option(SHARED_LIBS "Build shared/dynamic libraries"       OFF)
61 # Options for compiler definitions
62 option(INTERNAL_FILE_NML     "Enable compiler definition -DINTERNAL_FILE_NML"      ON)
63 option(ENABLE_QUAD_PRECISION "Enable compiler definition -DENABLE_QUAD_PRECISION"  ON)
64 option(GFS_PHYS              "Enable compiler definition -DGFS_PHYS"              OFF)
65 option(LARGEFILE             "Enable compiler definition -Duse_LARGEFILE"         OFF)
66 option(WITH_YAML             "Enable compiler definition -Duse_yaml"              OFF)
67 option(USE_DEPRECATED_IO     "Enable compiler definition -Duse_deprecated_io (compile with fms_io/mpp_io)"   OFF)
69 if(32BIT)
70   list(APPEND kinds "r4")
71 endif()
72 if(64BIT)
73   list(APPEND kinds "r8")
74 endif()
75 if(NOT kinds)
76   message(STATUS "Single Precision 32BIT: ${32BIT}")
77   message(STATUS "Double Precision 64BIT: ${64BIT}")
78   message(FATAL_ERROR "Either 32BIT or 64BIT should be ON")
79 endif()
81 # Find dependencies
82 find_package(MPI REQUIRED COMPONENTS C Fortran)
83 find_package(NetCDF REQUIRED COMPONENTS C Fortran)
85 # Check for the OpenMP library and set the required compile flags
86 if (OPENMP)
87   find_package(OpenMP REQUIRED COMPONENTS C Fortran)
88 endif()
90 if (WITH_YAML)
91   find_package(libyaml REQUIRED)
92   include_directories(${LIBYAML_INCLUDE_DIR})
93 endif ()
95 # Enables position independent code (i.e., -fPIC)
96 if (FPIC)
97   set(CMAKE_POSITION_INDEPENDENT_CODE ON)
98 endif ()
100 # Collect FMS Fortran source files
101 list(APPEND fms_fortran_src_files
102   affinity/fms_affinity.F90
103   amip_interp/amip_interp.F90
104   astronomy/astronomy.F90
105   axis_utils/axis_utils.F90
106   axis_utils/axis_utils2.F90
107   block_control/block_control.F90
108   column_diagnostics/column_diagnostics.F90
109   constants/constants.F90
110   constants/fmsconstants.F90
111   constants4/constantsr4.F90
112   constants4/fmsconstantsr4.F90
113   coupler/atmos_ocean_fluxes.F90
114   coupler/coupler_types.F90
115   coupler/ensemble_manager.F90
116   data_override/get_grid_version.F90
117   data_override/data_override.F90
118   diag_integral/diag_integral.F90
119   diag_manager/diag_axis.F90
120   diag_manager/diag_data.F90
121   diag_manager/diag_grid.F90
122   diag_manager/diag_manager.F90
123   diag_manager/diag_output.F90
124   diag_manager/diag_table.F90
125   diag_manager/diag_util.F90
126   diag_manager/fms_diag_time_utils.F90
127   diag_manager/fms_diag_object.F90
128   diag_manager/fms_diag_yaml.F90
129   diag_manager/fms_diag_file_object.F90
130   diag_manager/fms_diag_field_object.F90
131   diag_manager/fms_diag_axis_object.F90
132   diag_manager/fms_diag_output_buffer.F90
133   diag_manager/fms_diag_input_buffer.F90
134   diag_manager/fms_diag_time_reduction.F90
135   diag_manager/fms_diag_outfield.F90
136   diag_manager/fms_diag_elem_weight_procs.F90
137   diag_manager/fms_diag_fieldbuff_update.F90
138   diag_manager/fms_diag_bbox.F90
139   diag_manager/fms_diag_reduction_methods.F90
140   drifters/cloud_interpolator.F90
141   drifters/drifters.F90
142   drifters/drifters_comm.F90
143   drifters/drifters_core.F90
144   drifters/drifters_input.F90
145   drifters/drifters_io.F90
146   drifters/quicksort.F90
147   exchange/stock_constants.F90
148   exchange/xgrid.F90
149   field_manager/field_manager.F90
150   field_manager/fm_util.F90
151   field_manager/fm_yaml.F90
152   fms/fms_io.F90
153   fms/fms.F90
154   fms2_io/blackboxio.F90
155   fms2_io/fms_io_utils.F90
156   fms2_io/fms_netcdf_domain_io.F90
157   fms2_io/fms_netcdf_unstructured_domain_io.F90
158   fms2_io/fms2_io.F90
159   fms2_io/netcdf_io.F90
160   horiz_interp/horiz_interp_bicubic.F90
161   horiz_interp/horiz_interp_bilinear.F90
162   horiz_interp/horiz_interp_conserve.F90
163   horiz_interp/horiz_interp_spherical.F90
164   horiz_interp/horiz_interp_type.F90
165   horiz_interp/horiz_interp.F90
166   interpolator/interpolator.F90
167   memutils/memutils.F90
168   monin_obukhov/monin_obukhov_inter.F90
169   monin_obukhov/monin_obukhov.F90
170   mosaic/gradient.F90
171   mosaic/grid.F90
172   mosaic/mosaic.F90
173   mosaic2/grid2.F90
174   mosaic2/mosaic2.F90
175   mpp/mpp.F90
176   mpp/mpp_data.F90
177   mpp/mpp_domains.F90
178   mpp/mpp_efp.F90
179   mpp/mpp_io.F90
180   mpp/mpp_memutils.F90
181   mpp/mpp_parameter.F90
182   mpp/mpp_utilities.F90
183   parser/yaml_parser.F90
184   parser/fms_yaml_output.F90
185   platform/platform.F90
186   random_numbers/mersennetwister.F90
187   random_numbers/random_numbers.F90
188   sat_vapor_pres/sat_vapor_pres_k.F90
189   sat_vapor_pres/sat_vapor_pres.F90
190   string_utils/fms_string_utils.F90
191   time_interp/time_interp_external.F90
192   time_interp/time_interp_external2.F90
193   time_interp/time_interp.F90
194   time_manager/get_cal_time.F90
195   time_manager/time_manager.F90
196   topography/gaussian_topog.F90
197   topography/topography.F90
198   tracer_manager/tracer_manager.F90
199   tridiagonal/tridiagonal.F90
200   libFMS.F90
203 # Collect FMS C source files
204 list(APPEND fms_c_src_files
205   affinity/affinity.c
206   fms/fms_stacksize.c
207   mosaic/create_xgrid.c
208   mosaic/gradient_c2l.c
209   mosaic/interp.c
210   mosaic/mosaic_util.c
211   mosaic/read_mosaic.c
212   mpp/mpp_memuse.c
213   parser/yaml_parser_binding.c
214   parser/yaml_output_functions.c
215   string_utils/fms_string_utils_binding.c
218 # Collect FMS header files
219 list(APPEND fms_header_files
220   include/file_version.h
221   include/fms_platform.h
224 # Standard FMS compiler definitions
225 list(APPEND fms_defs
226   use_libMPI
227   use_netCDF)
229 # check gettid
230 include(CheckFunctionExists)
231 check_function_exists(gettid HAVE_GETTID)
232 if(HAVE_GETTID)
233   list(APPEND fms_defs HAVE_GETTID)
234 endif()
236 # Additional (optional) compiler definitions
237 if(NOT CONSTANTS)
238     set(CONSTANTS GFDL)
239 endif()
240 if(CONSTANTS STREQUAL "GFS")
241   list(APPEND fms_defs GFS_CONSTANTS)
242 elseif(CONSTANTS STREQUAL "GEOS")
243   list(APPEND fms_defs GEOS_CONSTANTS)
244 elseif(CONSTANTS STREQUAL "GFDL")
245   list(APPEND fms_defs GFDL_CONSTANTS)
246 else()
247   message(FATAL_ERROR "CONSTANTS=${CONSTANTS} option not supported")
248 endif()
250 if(GFS_PHYS)
251   list(APPEND fms_defs GFS_PHYS)
252 endif()
254 if(WITH_YAML)
255   list(APPEND fms_defs use_yaml)
256 endif()
258 if(USE_DEPRECATED_IO)
259   list(APPEND fms_defs use_deprecated_io)
260 endif()
262 if(INTERNAL_FILE_NML)
263   list(APPEND fms_defs INTERNAL_FILE_NML)
264 endif()
266 if(ENABLE_QUAD_PRECISION)
267   list(APPEND fms_defs ENABLE_QUAD_PRECISION)
268 endif()
270 if(LARGEFILE)
271   list(APPEND fms_defs use_LARGEFILE)
272 endif()
274 # Precision-based compiler definitions
275 if(32BIT)
276   list(APPEND r4_defs OVERLOAD_R4 OVERLOAD_R8)
277 endif()
279 # Add platform specific compiler definitions
280 if(APPLE)
281   list(APPEND fms_defs __APPLE__)
282 endif()
284 # Obtain compiler-specific flags
285 include(fms_compiler_flags)
287 foreach(kind ${kinds})
289   set(libTgt fms_${kind})
290   set(includeDir "include_${kind}")
291   set(moduleDir "${CMAKE_CURRENT_BINARY_DIR}/${includeDir}")
293   # C
294   add_library(${libTgt}_c OBJECT ${fms_c_src_files})
296   target_include_directories(${libTgt}_c PRIVATE include)
297   target_compile_definitions(${libTgt}_c PRIVATE "${fms_defs}")
299   target_link_libraries(${libTgt}_c PRIVATE NetCDF::NetCDF_C
300                                             MPI::MPI_C)
302   if(OpenMP_C_FOUND)
303     target_link_libraries(${libTgt}_c PRIVATE OpenMP::OpenMP_C)
304   endif()
306   # Fortran
307   add_library(${libTgt}_f OBJECT ${fms_fortran_src_files})
309   target_include_directories(${libTgt}_f PRIVATE include
310                                                  fms
311                                                  fms/include
312                                                  fms2_io/include
313                                                  string_utils/include
314                                                  mpp/include
315                                                  column_diagnostics/include
316                                                  monin_obukhov/include
317                                                  sat_vapor_pres/include
318                                                  horiz_interp/include
319                                                  diag_integral/include
320                                                  random_numbers/include
321                                                  diag_manager/include
322                                                  constants4
323                                                  topography/include
324                                                  axis_utils/include
325                                                  mosaic2/include
326                                                  constants
327                                                  astronomy/include
328                                                  field_manager/include
329                                                  time_interp/include
330                                                  tracer_manager/include
331                                                  tridiagonal/include
332                                                  interpolator/include
333                                                  coupler/include
334                                                  data_override/include
335                                                  amip_interp/include)
337   target_compile_definitions(${libTgt}_f PRIVATE "${fms_defs}")
338   target_compile_definitions(${libTgt}_f PRIVATE "${${kind}_defs}")
340   set_target_properties(${libTgt}_f PROPERTIES COMPILE_FLAGS "${${kind}_flags}")
342   set_target_properties(${libTgt}_f PROPERTIES Fortran_MODULE_DIRECTORY
343                                                ${moduleDir})
345   target_link_libraries(${libTgt}_f PRIVATE NetCDF::NetCDF_Fortran
346                                             MPI::MPI_Fortran)
348   if(OpenMP_Fortran_FOUND)
349     target_link_libraries(${libTgt}_f PRIVATE OpenMP::OpenMP_Fortran)
350   endif()
352   # Check if gnu 10 or higher
353   # this should only be needed with mpich, but wasn't able to find a good way to find the MPI flavor consistently
354   if ( CMAKE_Fortran_COMPILER_VERSION MATCHES "1[0-9]\.[0-9]*\.[0-9]*" AND CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
355     include(CheckFortranCompilerFlag)
356     check_fortran_compiler_flag("-fallow-argument-mismatch" _arg_mismatch_flag)
357     if(_arg_mismatch_flag)
358       message(STATUS "Adding -fallow-argument-mismatch flag to compile with GCC >=10 and MPICH")
359       target_compile_options(${libTgt}_f PRIVATE "-fallow-argument-mismatch;-w")
360     endif()
361   endif()
363   # FMS (C + Fortran)
364   if (SHARED_LIBS)
365       message(STATUS "Shared library target: ${libTgt}")
366       add_library(${libTgt} SHARED $<TARGET_OBJECTS:${libTgt}_c>
367                                    $<TARGET_OBJECTS:${libTgt}_f>)
368   else ()
369       message(STATUS "Static library target: ${libTgt}")
370       add_library(${libTgt} STATIC $<TARGET_OBJECTS:${libTgt}_c>
371                                    $<TARGET_OBJECTS:${libTgt}_f>)
372   endif ()
374   target_include_directories(${libTgt} PUBLIC
375     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
376     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fms>
377     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fms/include>
378     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fms2_io/include>
379     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/column_diagnostics/include>
380     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/astronomy/include>
381     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/monin_obukhov/include>
382     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/sat_vapor_pres/include>
383     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/field_manager/include>
384     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/horiz_interp/include>
385     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mosaic2/include>
386     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/string_utils/include>
387     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mpp/include>
388     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/diag_manager/include>
389     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/topography/include>
390     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/random_numbers/include>
391     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/diag_integral/include>
392     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/diag_manager/include>
393     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/tracer_manager/include>
394     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/interpolator/include>
395     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/coupler/include>
396     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mosaic2/include>
397     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/data_override/include>
398     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/tridiagonal/include>
399     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/amip_interp/include>)
401   target_include_directories(${libTgt} INTERFACE
402     $<BUILD_INTERFACE:${moduleDir}>
403     $<INSTALL_INTERFACE:${includeDir}>)
405   target_compile_definitions(${libTgt} PRIVATE "${fms_defs}")
406   target_compile_definitions(${libTgt} PRIVATE "${${kind}_defs}")
408   target_link_libraries(${libTgt} PUBLIC NetCDF::NetCDF_C
409                                          NetCDF::NetCDF_Fortran
410                                          MPI::MPI_Fortran)
412   if(OpenMP_Fortran_FOUND)
413     target_link_libraries(${libTgt} PRIVATE OpenMP::OpenMP_C OpenMP::OpenMP_Fortran)
414   endif()
416   add_library(FMS::${libTgt} ALIAS ${libTgt})
418   list(APPEND LIB_TARGETS ${libTgt})
419   install(DIRECTORY ${moduleDir}    DESTINATION ${CMAKE_INSTALL_PREFIX})
420   install(FILES ${fms_header_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/${includeDir})
422 endforeach()
424 install(
425   TARGETS ${LIB_TARGETS}
426   EXPORT FMSExports
427   RUNTIME DESTINATION bin
428   LIBRARY DESTINATION lib
429   ARCHIVE DESTINATION lib)
431 ### Package config
432 include(CMakePackageConfigHelpers)
433 set(CONFIG_INSTALL_DESTINATION lib/cmake/fms)
435 export(EXPORT FMSExports
436   NAMESPACE FMS::
437   FILE fms-targets.cmake)
439 configure_package_config_file(
440   ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FMSConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/fms-config.cmake
441   INSTALL_DESTINATION ${CONFIG_INSTALL_DESTINATION})
442 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fms-config.cmake
443   DESTINATION ${CONFIG_INSTALL_DESTINATION})
445 write_basic_package_version_file(
446   ${CMAKE_CURRENT_BINARY_DIR}/fms-config-version.cmake
447   VERSION ${PROJECT_VERSION}
448   COMPATIBILITY AnyNewerVersion)
449 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fms-config-version.cmake
450   DESTINATION ${CONFIG_INSTALL_DESTINATION})
452 install(EXPORT FMSExports
453   NAMESPACE FMS::
454   FILE fms-targets.cmake
455   DESTINATION ${CONFIG_INSTALL_DESTINATION})