1 #***********************************************************************
2 #* GNU Lesser General Public License
4 #* This file is part of the GFDL Flexible Modeling System (FMS).
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
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
27 DESCRIPTION "GFDL FMS Library"
28 HOMEPAGE_URL "https://www.gfdl.noaa.gov/fms"
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.")
37 CACHE STRING "Choose the type of build." FORCE)
38 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
41 if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Intel|GNU|Clang)$")
43 WARNING "Compiler not officially supported: ${CMAKE_C_COMPILER_ID}")
46 if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|GNU)$")
48 WARNING "Compiler not officially supported: ${CMAKE_Fortran_COMPILER_ID}")
51 # Append directory that contains CMake Modules for building FMS
52 list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
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)
59 # Options for compiler definitions
60 option(INTERNAL_FILE_NML "Enable compiler definition -DINTERNAL_FILE_NML" ON)
61 option(ENABLE_QUAD_PRECISION "Enable compiler definition -DENABLE_QUAD_PRECISION" ON)
62 option(GFS_PHYS "Enable compiler definition -DGFS_PHYS" OFF)
63 option(LARGEFILE "Enable compiler definition -Duse_LARGEFILE" OFF)
64 option(WITH_YAML "Enable compiler definition -Duse_yaml" OFF)
67 list(APPEND kinds "r4")
70 list(APPEND kinds "r8")
73 message(STATUS "Single Precision 32BIT: ${32BIT}")
74 message(STATUS "Double Precision 64BIT: ${64BIT}")
75 message(FATAL_ERROR "Either 32BIT or 64BIT should be ON")
79 find_package(MPI REQUIRED COMPONENTS C Fortran)
80 find_package(NetCDF REQUIRED COMPONENTS C Fortran)
82 # Check for the OpenMP library and set the required compile flags
84 find_package(OpenMP REQUIRED COMPONENTS C Fortran)
88 find_package(libyaml REQUIRED)
89 include_directories(${LIBYAML_INCLUDE_DIR})
92 # Collect FMS Fortran source files
93 list(APPEND fms_fortran_src_files
94 affinity/fms_affinity.F90
95 amip_interp/amip_interp.F90
96 astronomy/astronomy.F90
97 axis_utils/axis_utils.F90
98 axis_utils/axis_utils2.F90
99 block_control/block_control.F90
100 column_diagnostics/column_diagnostics.F90
101 constants/constants.F90
102 constants/fmsconstants.F90
103 coupler/atmos_ocean_fluxes.F90
104 coupler/coupler_types.F90
105 coupler/ensemble_manager.F90
106 data_override/get_grid_version.F90
107 data_override/data_override.F90
108 diag_integral/diag_integral.F90
109 diag_manager/diag_axis.F90
110 diag_manager/diag_data.F90
111 diag_manager/diag_grid.F90
112 diag_manager/diag_manager.F90
113 diag_manager/diag_output.F90
114 diag_manager/diag_table.F90
115 diag_manager/diag_util.F90
116 drifters/cloud_interpolator.F90
117 drifters/drifters.F90
118 drifters/drifters_comm.F90
119 drifters/drifters_core.F90
120 drifters/drifters_input.F90
121 drifters/drifters_io.F90
122 drifters/quicksort.F90
123 exchange/stock_constants.F90
125 field_manager/field_manager.F90
126 field_manager/fm_util.F90
129 fms2_io/blackboxio.F90
130 fms2_io/fms_io_utils.F90
131 fms2_io/fms_netcdf_domain_io.F90
132 fms2_io/fms_netcdf_unstructured_domain_io.F90
134 fms2_io/netcdf_io.F90
135 horiz_interp/horiz_interp_bicubic.F90
136 horiz_interp/horiz_interp_bilinear.F90
137 horiz_interp/horiz_interp_conserve.F90
138 horiz_interp/horiz_interp_spherical.F90
139 horiz_interp/horiz_interp_type.F90
140 horiz_interp/horiz_interp.F90
141 interpolator/interpolator.F90
142 memutils/memutils.F90
143 monin_obukhov/monin_obukhov_inter.F90
144 monin_obukhov/monin_obukhov.F90
156 mpp/mpp_parameter.F90
157 mpp/mpp_utilities.F90
158 parser/yaml_parser.F90
159 platform/platform.F90
160 random_numbers/mersennetwister.F90
161 random_numbers/random_numbers.F90
162 sat_vapor_pres/sat_vapor_pres_k.F90
163 sat_vapor_pres/sat_vapor_pres.F90
164 time_interp/time_interp_external.F90
165 time_interp/time_interp_external2.F90
166 time_interp/time_interp.F90
167 time_manager/get_cal_time.F90
168 time_manager/time_manager.F90
169 topography/gaussian_topog.F90
170 topography/topography.F90
171 tracer_manager/tracer_manager.F90
172 tridiagonal/tridiagonal.F90
176 # Collect FMS C source files
177 list(APPEND fms_c_src_files
180 mosaic/create_xgrid.c
181 mosaic/gradient_c2l.c
186 parser/yaml_parser_binding.c
189 # Collect FMS header files
190 list(APPEND fms_header_files
191 include/file_version.h
192 include/fms_platform.h
196 # Standard FMS compiler definitions
202 include(CheckFunctionExists)
203 check_function_exists(gettid HAVE_GETTID)
205 list(APPEND fms_defs HAVE_GETTID)
208 # Additional (optional) compiler definitions
210 list(APPEND fms_defs GFS_PHYS)
214 list(APPEND fms_defs use_yaml)
217 if(INTERNAL_FILE_NML)
218 list(APPEND fms_defs INTERNAL_FILE_NML)
221 if(ENABLE_QUAD_PRECISION)
222 list(APPEND fms_defs ENABLE_QUAD_PRECISION)
226 list(APPEND fms_defs use_LARGEFILE)
229 # Precision-based compiler definitions
231 list(APPEND r4_defs OVERLOAD_R4 OVERLOAD_R8)
234 # Add platform specific compiler definitions
236 list(APPEND fms_defs __APPLE__)
239 # Obtain compiler-specific flags
240 include(fms_compiler_flags)
242 foreach(kind ${kinds})
244 set(libTgt fms_${kind})
245 set(includeDir "include_${kind}")
246 set(moduleDir "${CMAKE_CURRENT_BINARY_DIR}/${includeDir}")
249 add_library(${libTgt}_c OBJECT ${fms_c_src_files})
251 target_include_directories(${libTgt}_c PRIVATE include)
252 target_compile_definitions(${libTgt}_c PRIVATE "${fms_defs}")
254 target_link_libraries(${libTgt}_c PRIVATE NetCDF::NetCDF_C
258 target_link_libraries(${libTgt}_c PRIVATE OpenMP::OpenMP_C)
262 add_library(${libTgt}_f OBJECT ${fms_fortran_src_files})
264 target_include_directories(${libTgt}_f PRIVATE include
268 target_compile_definitions(${libTgt}_f PRIVATE "${fms_defs}")
269 target_compile_definitions(${libTgt}_f PRIVATE "${${kind}_defs}")
271 set_target_properties(${libTgt}_f PROPERTIES COMPILE_FLAGS
273 set_target_properties(${libTgt}_f PROPERTIES Fortran_MODULE_DIRECTORY
276 target_link_libraries(${libTgt}_f PRIVATE NetCDF::NetCDF_Fortran
279 if(OpenMP_Fortran_FOUND)
280 target_link_libraries(${libTgt}_f PRIVATE OpenMP::OpenMP_Fortran)
284 add_library(${libTgt} STATIC $<TARGET_OBJECTS:${libTgt}_c>
285 $<TARGET_OBJECTS:${libTgt}_f>)
287 target_include_directories(${libTgt} PUBLIC
288 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
289 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fms>
290 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fms2_io/include>
291 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mpp/include>)
293 target_include_directories(${libTgt} INTERFACE
294 $<BUILD_INTERFACE:${moduleDir}>
295 $<INSTALL_INTERFACE:${includeDir}>)
297 target_compile_definitions(${libTgt} PRIVATE "${fms_defs}")
298 target_compile_definitions(${libTgt} PRIVATE "${${kind}_defs}")
300 target_link_libraries(${libTgt} PUBLIC NetCDF::NetCDF_Fortran
303 if(OpenMP_Fortran_FOUND)
304 target_link_libraries(${libTgt} PRIVATE OpenMP::OpenMP_Fortran)
307 add_library(FMS::${libTgt} ALIAS ${libTgt})
309 list(APPEND LIB_TARGETS ${libTgt})
310 install(DIRECTORY ${moduleDir} DESTINATION ${CMAKE_INSTALL_PREFIX})
311 install(FILES ${fms_header_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/${includeDir})
316 TARGETS ${LIB_TARGETS}
318 RUNTIME DESTINATION bin
319 LIBRARY DESTINATION lib
320 ARCHIVE DESTINATION lib)
323 include(CMakePackageConfigHelpers)
324 set(CONFIG_INSTALL_DESTINATION lib/cmake/fms)
326 export(EXPORT FMSExports
328 FILE fms-targets.cmake)
330 configure_package_config_file(
331 ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FMSConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/fms-config.cmake
332 INSTALL_DESTINATION ${CONFIG_INSTALL_DESTINATION})
333 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fms-config.cmake
334 DESTINATION ${CONFIG_INSTALL_DESTINATION})
336 write_basic_package_version_file(
337 ${CMAKE_CURRENT_BINARY_DIR}/fms-config-version.cmake
338 VERSION ${PROJECT_VERSION}
339 COMPATIBILITY AnyNewerVersion)
340 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fms-config-version.cmake
341 DESTINATION ${CONFIG_INSTALL_DESTINATION})
343 install(EXPORT FMSExports
345 FILE fms-targets.cmake
346 DESTINATION ${CONFIG_INSTALL_DESTINATION})