revert: log_diag_field_info argument changes (#1136)
[FMS.git] / CMakeLists.txt
blobb1f06a27076aa363af8225f9a29c76703cb9490b
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 # add build type for debug, overrides default flags (set with $FCFLAGS, $CFLAGS)
25 set(CMAKE_Fortran_FLAGS_DEBUG)
27 # Define the CMake project
28 project(FMS
29   VERSION 2022.04.0
30   DESCRIPTION  "GFDL FMS Library"
31   HOMEPAGE_URL "https://www.gfdl.noaa.gov/fms"
32   LANGUAGES C Fortran)
34 include(GNUInstallDirs)
36 if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)$")
37   message(STATUS "Setting build type to 'Release' as none was specified.")
38   set(CMAKE_BUILD_TYPE
39       "Release"
40       CACHE STRING "Choose the type of build." FORCE)
41   set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
42 endif()
44 if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Intel|GNU|Clang|IntelLLVM)$")
45   message(
46     WARNING "Compiler not officially supported: ${CMAKE_C_COMPILER_ID}")
47 endif()
49 if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|GNU|IntelLLVM)$")
50   message(
51     WARNING "Compiler not officially supported: ${CMAKE_Fortran_COMPILER_ID}")
52 endif()
54 # Append directory that contains CMake Modules for building FMS
55 list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
57 # Build options
58 option(OPENMP "Build FMS with OpenMP support"        OFF)
59 option(32BIT  "Build 32-bit (r4) FMS library"         ON)
60 option(64BIT  "Build 64-bit (r8) FMS library"        OFF)
61 option(FPIC   "Build with position independent code" OFF)
63 # Options for compiler definitions
64 option(INTERNAL_FILE_NML     "Enable compiler definition -DINTERNAL_FILE_NML"      ON)
65 option(ENABLE_QUAD_PRECISION "Enable compiler definition -DENABLE_QUAD_PRECISION"  ON)
66 option(GFS_PHYS              "Enable compiler definition -DGFS_PHYS"              OFF)
67 option(LARGEFILE             "Enable compiler definition -Duse_LARGEFILE"         OFF)
68 option(WITH_YAML             "Enable compiler definition -Duse_yaml"              OFF)
70 if(32BIT)
71   list(APPEND kinds "r4")
72 endif()
73 if(64BIT)
74   list(APPEND kinds "r8")
75 endif()
76 if(NOT kinds)
77   message(STATUS "Single Precision 32BIT: ${32BIT}")
78   message(STATUS "Double Precision 64BIT: ${64BIT}")
79   message(FATAL_ERROR "Either 32BIT or 64BIT should be ON")
80 endif()
82 # Find dependencies
83 find_package(MPI REQUIRED COMPONENTS C Fortran)
84 find_package(NetCDF REQUIRED COMPONENTS C Fortran)
86 # Check for the OpenMP library and set the required compile flags
87 if (OPENMP)
88   find_package(OpenMP REQUIRED COMPONENTS C Fortran)
89 endif()
91 if (WITH_YAML)
92   find_package(libyaml REQUIRED)
93   include_directories(${LIBYAML_INCLUDE_DIR})
94 endif ()
96 # Enables position independent code (i.e., -fPIC)
97 if (FPIC)
98   set(CMAKE_POSITION_INDEPENDENT_CODE ON)
99 endif ()
101 # Collect FMS Fortran source files
102 list(APPEND fms_fortran_src_files
103   affinity/fms_affinity.F90
104   amip_interp/amip_interp.F90
105   astronomy/astronomy.F90
106   axis_utils/axis_utils.F90
107   axis_utils/axis_utils2.F90
108   block_control/block_control.F90
109   column_diagnostics/column_diagnostics.F90
110   constants/constants.F90
111   constants/fmsconstants.F90
112   constants4/constantsr4.F90
113   constants4/fmsconstantsr4.F90
114   coupler/atmos_ocean_fluxes.F90
115   coupler/coupler_types.F90
116   coupler/ensemble_manager.F90
117   data_override/get_grid_version.F90
118   data_override/data_override.F90
119   diag_integral/diag_integral.F90
120   diag_manager/diag_axis.F90
121   diag_manager/diag_data.F90
122   diag_manager/diag_grid.F90
123   diag_manager/diag_manager.F90
124   diag_manager/diag_output.F90
125   diag_manager/diag_table.F90
126   diag_manager/diag_util.F90
127   drifters/cloud_interpolator.F90
128   drifters/drifters.F90
129   drifters/drifters_comm.F90
130   drifters/drifters_core.F90
131   drifters/drifters_input.F90
132   drifters/drifters_io.F90
133   drifters/quicksort.F90
134   exchange/stock_constants.F90
135   exchange/xgrid.F90
136   field_manager/field_manager.F90
137   field_manager/fm_util.F90
138   field_manager/fm_yaml.F90
139   fms/fms_io.F90
140   fms/fms.F90
141   fms2_io/blackboxio.F90
142   fms2_io/fms_io_utils.F90
143   fms2_io/fms_netcdf_domain_io.F90
144   fms2_io/fms_netcdf_unstructured_domain_io.F90
145   fms2_io/fms2_io.F90
146   fms2_io/netcdf_io.F90
147   horiz_interp/horiz_interp_bicubic.F90
148   horiz_interp/horiz_interp_bilinear.F90
149   horiz_interp/horiz_interp_conserve.F90
150   horiz_interp/horiz_interp_spherical.F90
151   horiz_interp/horiz_interp_type.F90
152   horiz_interp/horiz_interp.F90
153   interpolator/interpolator.F90
154   memutils/memutils.F90
155   monin_obukhov/monin_obukhov_inter.F90
156   monin_obukhov/monin_obukhov.F90
157   mosaic/gradient.F90
158   mosaic/grid.F90
159   mosaic/mosaic.F90
160   mosaic2/grid2.F90
161   mosaic2/mosaic2.F90
162   mpp/mpp.F90
163   mpp/mpp_data.F90
164   mpp/mpp_domains.F90
165   mpp/mpp_efp.F90
166   mpp/mpp_io.F90
167   mpp/mpp_memutils.F90
168   mpp/mpp_parameter.F90
169   mpp/mpp_utilities.F90
170   parser/yaml_parser.F90
171   parser/fms_yaml_output.F90
172   platform/platform.F90
173   random_numbers/mersennetwister.F90
174   random_numbers/random_numbers.F90
175   sat_vapor_pres/sat_vapor_pres_k.F90
176   sat_vapor_pres/sat_vapor_pres.F90
177   string_utils/fms_string_utils.F90
178   time_interp/time_interp_external.F90
179   time_interp/time_interp_external2.F90
180   time_interp/time_interp.F90
181   time_manager/get_cal_time.F90
182   time_manager/time_manager.F90
183   topography/gaussian_topog.F90
184   topography/topography.F90
185   tracer_manager/tracer_manager.F90
186   tridiagonal/tridiagonal.F90
187   libFMS.F90
190 # Collect FMS C source files
191 list(APPEND fms_c_src_files
192   affinity/affinity.c
193   mosaic/create_xgrid.c
194   mosaic/gradient_c2l.c
195   mosaic/interp.c
196   mosaic/mosaic_util.c
197   mosaic/read_mosaic.c
198   mpp/mpp_memuse.c
199   parser/yaml_parser_binding.c
200   parser/yaml_output_functions.c
201   string_utils/fms_string_utils_binding.c
204 # Collect FMS header files
205 list(APPEND fms_header_files
206   include/file_version.h
207   include/fms_platform.h
210 # Standard FMS compiler definitions
211 list(APPEND fms_defs
212   use_libMPI
213   use_netCDF)
215 # check gettid
216 include(CheckFunctionExists)
217 check_function_exists(gettid HAVE_GETTID)
218 if(HAVE_GETTID)
219   list(APPEND fms_defs HAVE_GETTID)
220 endif()
222 # Additional (optional) compiler definitions
223 if(NOT CONSTANTS)
224     set(CONSTANTS GFDL)
225 endif()
226 if(CONSTANTS STREQUAL "GFS")
227   list(APPEND fms_defs GFS_CONSTANTS)
228 elseif(CONSTANTS STREQUAL "GEOS")
229   list(APPEND fms_defs GEOS_CONSTANTS)
230 elseif(CONSTANTS STREQUAL "GFDL")
231   list(APPEND fms_defs GFDL_CONSTANTS)
232 else()
233   message(FATAL_ERROR "CONSTANTS=${CONSTANTS} option not supported")
234 endif()
236 if(GFS_PHYS)
237   list(APPEND fms_defs GFS_PHYS)
238 endif()
240 if(WITH_YAML)
241   list(APPEND fms_defs use_yaml)
242 endif()
244 if(INTERNAL_FILE_NML)
245   list(APPEND fms_defs INTERNAL_FILE_NML)
246 endif()
248 if(ENABLE_QUAD_PRECISION)
249   list(APPEND fms_defs ENABLE_QUAD_PRECISION)
250 endif()
252 if(LARGEFILE)
253   list(APPEND fms_defs use_LARGEFILE)
254 endif()
256 # Precision-based compiler definitions
257 if(32BIT)
258   list(APPEND r4_defs OVERLOAD_R4 OVERLOAD_R8)
259 endif()
261 # Add platform specific compiler definitions
262 if(APPLE)
263   list(APPEND fms_defs __APPLE__)
264 endif()
266 # Obtain compiler-specific flags
267 include(fms_compiler_flags)
269 foreach(kind ${kinds})
271   set(libTgt fms_${kind})
272   set(includeDir "include_${kind}")
273   set(moduleDir "${CMAKE_CURRENT_BINARY_DIR}/${includeDir}")
275   # C
276   add_library(${libTgt}_c OBJECT ${fms_c_src_files})
278   target_include_directories(${libTgt}_c PRIVATE include)
279   target_compile_definitions(${libTgt}_c PRIVATE "${fms_defs}")
281   target_link_libraries(${libTgt}_c PRIVATE NetCDF::NetCDF_C
282                                             MPI::MPI_C)
284   if(OpenMP_C_FOUND)
285     target_link_libraries(${libTgt}_c PRIVATE OpenMP::OpenMP_C)
286   endif()
288   # Fortran
289   add_library(${libTgt}_f OBJECT ${fms_fortran_src_files})
291   target_include_directories(${libTgt}_f PRIVATE include
292                                                  fms
293                                                  fms2_io/include
294                                                  mpp/include
295                                                  constants4
296                                                  constants)
297   target_compile_definitions(${libTgt}_f PRIVATE "${fms_defs}")
298   target_compile_definitions(${libTgt}_f PRIVATE "${${kind}_defs}")
300   string(TOLOWER ${CMAKE_BUILD_TYPE} build_type)
301   if (NOT build_type STREQUAL debug)
302     set_target_properties(${libTgt}_f PROPERTIES COMPILE_FLAGS
303                                                "${${kind}_flags}")
304   endif()
305   set_target_properties(${libTgt}_f PROPERTIES Fortran_MODULE_DIRECTORY
306                                                ${moduleDir})
308   target_link_libraries(${libTgt}_f PRIVATE NetCDF::NetCDF_Fortran
309                                             MPI::MPI_Fortran)
311   if(OpenMP_Fortran_FOUND)
312     target_link_libraries(${libTgt}_f PRIVATE OpenMP::OpenMP_Fortran)
313   endif()
315   # Check if gnu 10 or higher with mpich
316   if ( CMAKE_Fortran_COMPILER_VERSION MATCHES "1[0-9]\.[0-9]*\.[0-9]*" AND CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
317     if(MPI_C_COMPILER MATCHES ".*mpich.*" )
318       message(STATUS "Adding -fallow-argument-mismatch flag to compile with GCC >=10 and MPICH")
319       set_target_properties(${libTgt}_f PROPERTIES COMPILE_FLAGS "-fallow-argument-mismatch -w")
320     endif()
321   endif()
323   # FMS (C + Fortran)
324   add_library(${libTgt} STATIC $<TARGET_OBJECTS:${libTgt}_c>
325                                $<TARGET_OBJECTS:${libTgt}_f>)
327   target_include_directories(${libTgt} PUBLIC
328     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
329     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fms>
330     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fms2_io/include>
331     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mpp/include>)
333   target_include_directories(${libTgt} INTERFACE
334     $<BUILD_INTERFACE:${moduleDir}>
335     $<INSTALL_INTERFACE:${includeDir}>)
337   target_compile_definitions(${libTgt} PRIVATE "${fms_defs}")
338   target_compile_definitions(${libTgt} PRIVATE "${${kind}_defs}")
340   target_link_libraries(${libTgt} PUBLIC NetCDF::NetCDF_Fortran
341                                          MPI::MPI_Fortran)
343   if(OpenMP_Fortran_FOUND)
344     target_link_libraries(${libTgt} PRIVATE OpenMP::OpenMP_Fortran)
345   endif()
347   add_library(FMS::${libTgt} ALIAS ${libTgt})
349   list(APPEND LIB_TARGETS ${libTgt})
350   install(DIRECTORY ${moduleDir}    DESTINATION ${CMAKE_INSTALL_PREFIX})
351   install(FILES ${fms_header_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/${includeDir})
353 endforeach()
355 install(
356   TARGETS ${LIB_TARGETS}
357   EXPORT FMSExports
358   RUNTIME DESTINATION bin
359   LIBRARY DESTINATION lib
360   ARCHIVE DESTINATION lib)
362 ### Package config
363 include(CMakePackageConfigHelpers)
364 set(CONFIG_INSTALL_DESTINATION lib/cmake/fms)
366 export(EXPORT FMSExports
367   NAMESPACE FMS::
368   FILE fms-targets.cmake)
370 configure_package_config_file(
371   ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FMSConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/fms-config.cmake
372   INSTALL_DESTINATION ${CONFIG_INSTALL_DESTINATION})
373 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fms-config.cmake
374   DESTINATION ${CONFIG_INSTALL_DESTINATION})
376 write_basic_package_version_file(
377   ${CMAKE_CURRENT_BINARY_DIR}/fms-config-version.cmake
378   VERSION ${PROJECT_VERSION}
379   COMPATIBILITY AnyNewerVersion)
380 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fms-config-version.cmake
381   DESTINATION ${CONFIG_INSTALL_DESTINATION})
383 install(EXPORT FMSExports
384   NAMESPACE FMS::
385   FILE fms-targets.cmake
386   DESTINATION ${CONFIG_INSTALL_DESTINATION})