chore: 2022.01 release changes (#941)
[FMS.git] / CMakeLists.txt
blob4ac538209f0c4f643c422ff02972a17570380a85
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 2022.01.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)$")
42   message(
43     WARNING "Compiler not officially supported: ${CMAKE_C_COMPILER_ID}")
44 endif()
46 if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|GNU)$")
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)
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)
66 if(32BIT)
67   list(APPEND kinds "r4")
68 endif()
69 if(64BIT)
70   list(APPEND kinds "r8")
71 endif()
72 if(NOT kinds)
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")
76 endif()
78 # Find dependencies
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
83 if (OPENMP)
84   find_package(OpenMP REQUIRED COMPONENTS C Fortran)
85 endif()
87 if (WITH_YAML)
88   find_package(libyaml REQUIRED)
89   include_directories(${LIBYAML_INCLUDE_DIR})
90 endif ()
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
124   exchange/xgrid.F90
125   field_manager/field_manager.F90
126   field_manager/fm_util.F90
127   fms/fms_io.F90
128   fms/fms.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
133   fms2_io/fms2_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
145   mosaic/gradient.F90
146   mosaic/grid.F90
147   mosaic/mosaic.F90
148   mosaic2/grid2.F90
149   mosaic2/mosaic2.F90
150   mpp/mpp.F90
151   mpp/mpp_data.F90
152   mpp/mpp_domains.F90
153   mpp/mpp_efp.F90
154   mpp/mpp_io.F90
155   mpp/mpp_memutils.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
173   libFMS.F90
176 # Collect FMS C source files
177 list(APPEND fms_c_src_files
178   affinity/affinity.c
179   fms/fms_c.c
180   mosaic/create_xgrid.c
181   mosaic/gradient_c2l.c
182   mosaic/interp.c
183   mosaic/mosaic_util.c
184   mosaic/read_mosaic.c
185   mpp/mpp_memuse.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
193   fms/fms_c.h
196 # Standard FMS compiler definitions
197 list(APPEND fms_defs
198   use_libMPI
199   use_netCDF)
201 # check gettid
202 include(CheckFunctionExists)
203 check_function_exists(gettid HAVE_GETTID)
204 if(HAVE_GETTID)
205   list(APPEND fms_defs HAVE_GETTID)
206 endif()
208 # Additional (optional) compiler definitions
209 if(GFS_PHYS)
210   list(APPEND fms_defs GFS_PHYS)
211 endif()
213 if(WITH_YAML)
214   list(APPEND fms_defs use_yaml)
215 endif()
217 if(INTERNAL_FILE_NML)
218   list(APPEND fms_defs INTERNAL_FILE_NML)
219 endif()
221 if(ENABLE_QUAD_PRECISION)
222   list(APPEND fms_defs ENABLE_QUAD_PRECISION)
223 endif()
225 if(LARGEFILE)
226   list(APPEND fms_defs use_LARGEFILE)
227 endif()
229 # Precision-based compiler definitions
230 if(32BIT)
231   list(APPEND r4_defs OVERLOAD_R4 OVERLOAD_R8)
232 endif()
234 # Add platform specific compiler definitions
235 if(APPLE)
236   list(APPEND fms_defs __APPLE__)
237 endif()
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}")
248   # C
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
255                                             MPI::MPI_C)
257   if(OpenMP_C_FOUND)
258     target_link_libraries(${libTgt}_c PRIVATE OpenMP::OpenMP_C)
259   endif()
261   # Fortran
262   add_library(${libTgt}_f OBJECT ${fms_fortran_src_files})
264   target_include_directories(${libTgt}_f PRIVATE include
265                                                  fms
266                                                  fms2_io/include
267                                                  mpp/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
272                                                "${${kind}_flags}")
273   set_target_properties(${libTgt}_f PROPERTIES Fortran_MODULE_DIRECTORY
274                                                ${moduleDir})
276   target_link_libraries(${libTgt}_f PRIVATE NetCDF::NetCDF_Fortran
277                                             MPI::MPI_Fortran)
279   if(OpenMP_Fortran_FOUND)
280     target_link_libraries(${libTgt}_f PRIVATE OpenMP::OpenMP_Fortran)
281   endif()
283   # FMS (C + 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
301                                          MPI::MPI_Fortran)
303   if(OpenMP_Fortran_FOUND)
304     target_link_libraries(${libTgt} PRIVATE OpenMP::OpenMP_Fortran)
305   endif()
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})
313 endforeach()
315 install(
316   TARGETS ${LIB_TARGETS}
317   EXPORT FMSExports
318   RUNTIME DESTINATION bin
319   LIBRARY DESTINATION lib
320   ARCHIVE DESTINATION lib)
322 ### Package config
323 include(CMakePackageConfigHelpers)
324 set(CONFIG_INSTALL_DESTINATION lib/cmake/fms)
326 export(EXPORT FMSExports
327   NAMESPACE FMS::
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
344   NAMESPACE FMS::
345   FILE fms-targets.cmake
346   DESTINATION ${CONFIG_INSTALL_DESTINATION})