1 cmake_minimum_required( VERSION 3.20 )
2 cmake_policy( SET CMP0118 NEW )
6 enable_language( Fortran )
9 set( EXPORT_NAME ${PROJECT_NAME} )
11 if ( DEFINED CMAKE_TOOLCHAIN_FILE )
12 set( WRF_CONFIG ${CMAKE_TOOLCHAIN_FILE} )
13 # message( STATUS "Loading configuration file... : ${WRF_CONFIG}" )
14 # include( ${WRF_CONFIG} )
17 # list( APPEND CMAKE_MODULE_PATH )
18 list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/ ${PROJECT_SOURCE_DIR}/cmake/modules )
20 # Use link paths as rpaths
21 set( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE )
22 set( CMAKE_Fortran_PREPROCESS ON )
25 list( APPEND CMAKE_C_PREPROCESSOR_FLAGS -P -nostdinc -traditional )
27 include( CMakePackageConfigHelpers )
28 include( CheckIPOSupported )
31 include( target_copy )
34 include( printOption )
35 include( wrf_case_setup )
36 include( wrf_get_version )
38 check_ipo_supported( RESULT IPO_SUPPORT )
42 RESULT_VAR GIT_VERSION
43 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
46 # Configure file for usage
48 ${PROJECT_SOURCE_DIR}/cmake/template/commit_decl.cmake
49 ${PROJECT_BINARY_DIR}/inc/commit_decl
54 wrf_get_version( ${PROJECT_SOURCE_DIR}/README )
56 ################################################################################
58 ## Options that can be user configured
60 ################################################################################
63 set( OPTIMIZATION_LEVEL "" )
67 if ( "${CMAKE_BUILD_TYPE}" STREQUAL "" )
68 set( CMAKE_BUILD_TYPE Release )
69 message( STATUS "Set default build type to ${CMAKE_BUILD_TYPE}" )
71 ################################################################################
73 ################################################################################
77 CONVERT # This exists in compile but not configure
83 set( WRF_CORE "" CACHE STRING "WRF_CORE" )
84 if ( "${WRF_CORE}" STREQUAL "" )
85 # Set default WRF_CORE
86 list( GET WRF_CORE_OPTIONS 0 WRF_CORE )
89 ################################################################################
90 ## WRF Nesting selection
91 ################################################################################
92 set( WRF_NESTING_OPTIONS
100 set( WRF_NESTING "" CACHE STRING "WRF_NESTING" )
101 if ( "${WRF_NESTING}" STREQUAL "" )
102 # Set default WRF_NESTING
103 list( GET WRF_NESTING_OPTIONS 0 WRF_NESTING )
106 ################################################################################
107 ## WRF Case selection
108 ##!TODO Maybe one day make it so this doesn't need to be a selection and all are
110 ################################################################################
111 set( WRF_CASE_OPTIONS
112 # Options listed here
113 EM_REAL # make this the default
114 # EM_IDEAL # Technically doable but does anyone build this? It is not a target option in make
120 # These are sub-categories of ideal - Keep these lower in the list
121 EM_B_WAVE # Keep this one here as it is used to check index
131 # No case selected, for situations where we are not compiling ARW
135 set( WRF_CASE "" CACHE STRING "WRF_CASE" )
136 if ( "${WRF_CASE}" STREQUAL "" )
137 # Set default WRF_CASE
138 list( GET WRF_CASE_OPTIONS 0 WRF_CASE )
141 # DO NOT USE OPTION - IT DOES NOT WORK AS ANTICIPATED EVEN WHEN CLEARING CACHE - YOU HAVE BEEN WARNED
142 # If you add anything here, the description should be the name itself - this helps the configuration script
143 set( USE_DOUBLE OFF CACHE BOOL "USE_DOUBLE" )
144 set( USE_MPI OFF CACHE BOOL "USE_MPI" )
145 set( USE_OPENMP OFF CACHE BOOL "USE_OPENMP" )
146 set( USE_HDF5 OFF CACHE BOOL "USE_HDF5" )
147 set( USE_JASPER OFF CACHE BOOL "USE_JASPER" )
148 set( USE_PIO OFF CACHE BOOL "USE_PIO" )
149 set( USE_IPO OFF CACHE BOOL "USE_IPO" )
152 set( ENABLE_CHEM OFF CACHE BOOL "ENABLE_CHEM" )
153 set( ENABLE_CMAQ OFF CACHE BOOL "ENABLE_CMAQ" )
154 set( ENABLE_CTSM OFF CACHE BOOL "ENABLE_CTSM" )
155 set( ENABLE_DFI_RADAR OFF CACHE BOOL "ENABLE_DFI_RADAR" )
156 set( ENABLE_HYDRO OFF CACHE BOOL "ENABLE_HYDRO" )
157 set( ENABLE_KPP OFF CACHE BOOL "ENABLE_KPP" )
158 set( ENABLE_MARS OFF CACHE BOOL "ENABLE_MARS" )
159 set( ENABLE_TERRAIN OFF CACHE BOOL "ENABLE_TERRAIN" )
160 set( ENABLE_TITAN OFF CACHE BOOL "ENABLE_TITAN" )
161 set( ENABLE_VENUS OFF CACHE BOOL "ENABLE_VENUS" )
163 # What do these defines even do if they are always on????
164 set( USE_ALLOCATABLES ON CACHE BOOL "USE_ALLOCATABLES" )
165 set( wrfmodel ON CACHE BOOL "wrfmodel" )
166 set( GRIB1 ON CACHE BOOL "GRIB1" )
167 set( INTIO ON CACHE BOOL "INTIO" )
168 set( KEEP_INT_AROUND ON CACHE BOOL "KEEP_INT_AROUND" )
169 set( LIMIT_ARGS ON CACHE BOOL "LIMIT_ARGS" )
171 # Toggles, how do we want to best address these options? Environment vars are not
173 set( WRFIO_NCD_NO_LARGE_FILE_SUPPORT OFF CACHE BOOL "WRFIO_NCD_NO_LARGE_FILE_SUPPORT" )
174 set( FORCE_NETCDF_CLASSIC OFF CACHE BOOL "FORCE_NETCDF_CLASSIC" )
175 set( BUILD_RRTMG_FAST OFF CACHE BOOL "BUILD_RRTMG_FAST" )
176 set( BUILD_RRTMK OFF CACHE BOOL "BUILD_RRTMK" )
177 set( BUILD_SBM_FAST ON CACHE BOOL "BUILD_SBM_FAST" )
178 set( SHOW_ALL_VARS_USED OFF CACHE BOOL "SHOW_ALL_VARS_USED" )
181 # TODO investigate if this needs set
182 # Not cached, cannot be changed, do not touch
184 # Same thing -what do these defines even do if they are always on????
189 # Special internal flag for profiling compilation
190 set( PROFILE_COMPILATION OFF CACHE BOOL "PROFILE_COMPILATION" )
194 #### Single location for defining total number of domains. You need
195 #### at least 1 + 2*(number of total nests). For example, 1 coarse
196 #### grid + three fine grids = 1 + 2(3) = 7, so MAX_DOMAINS=7.
197 set( MAX_DOMAINS_F 21 )
200 #### DM buffer length for the configuration flags.
202 set( CONFIG_BUF_LEN 65536 )
204 #### Size of bitmasks (in 4byte integers) of stream masks for WRF I/O
206 set( MAX_HISTORY 25 )
213 ########################
215 ################################################################################
217 ## Load options selected and any ancillary logic
219 ################################################################################
222 if ( NOT ${WRF_CORE} IN_LIST WRF_CORE_OPTIONS )
223 message( FATAL_ERROR "WRF Core option not recognized : ${WRF_CORE}" )
226 if ( NOT ${WRF_CORE} STREQUAL "ARW" )
227 message( STATUS "All non-ARW Cores requires using pointers in grid state struct" )
228 set( USE_ALLOCATABLES OFF CACHE BOOL "Required by configuration" FORCE )
231 if ( NOT ${WRF_NESTING} IN_LIST WRF_NESTING_OPTIONS )
232 message( FATAL_ERROR "WRF Nesting option not recognized : ${WRF_NESTING}" )
235 if ( NOT ${WRF_CASE} IN_LIST WRF_CASE_OPTIONS )
236 message( FATAL_ERROR "WRF Case option not recognized : ${WRF_CASE}" )
241 # Far easier to write this one as normal logic rather than generator expression
242 if( ${WRF_CORE} STREQUAL "CONVERT" OR ${WRF_CORE} STREQUAL "COAMPS" )
247 # Far easier to write this one as normal logic rather than generator expression
248 if( ${WRF_NESTING} STREQUAL "MOVES" OR ${WRF_NESTING} STREQUAL "VORTEX" )
252 if ( ${ENABLE_KPP} AND NOT ${ENABLE_CHEM} )
253 message( WARNING "ENABLE_KPP requires ENABLE_CHEM but is not set, ignoring" )
257 # Additional information on the type of case we are compiling
258 string( TOLOWER ${WRF_CASE} WRF_CASE_FOLDER )
259 string( REPLACE "em_" "" WRF_CASE_MODULE ${WRF_CASE_FOLDER} )
261 # Find if it is a specialized ideal case or general
262 list( FIND WRF_CASE_OPTIONS EM_B_WAVE START_GENERAL_IDEAL_CASE_IDX )
263 list( FIND WRF_CASE_OPTIONS ${WRF_CASE} CURRENT_CASE_IDX )
264 set( WRF_GENERAL_IDEAL_CASE TRUE )
265 if ( ${CURRENT_CASE_IDX} LESS ${START_GENERAL_IDEAL_CASE_IDX} )
266 set( WRF_GENERAL_IDEAL_CASE FALSE )
269 if ( NOT ${WRFIO_NCD_NO_LARGE_FILE_SUPPORT} )
270 message( STATUS "netCDF large file support not suppressed, if available it will be used" )
273 # Hydro option requires MPI
274 if ( ${ENABLE_HYDRO} AND NOT ${USE_MPI} )
275 message( STATUS "WRF Hydro requires MPI usage" )
276 set( USE_MPI ON CACHE BOOL "Required by configuration" FORCE )
279 # Handle double promotion - doing this here instead of from config.cmake toolchain
280 # file since the double promotion logic is a nightmare
281 list( FIND WRF_CORE_OPTIONS ${WRF_CORE} CURRENT_WRF_CORE_IDX )
282 list( FIND WRF_CORE_OPTIONS "DA" START_DA_IDX )
283 # DA + WRF PLUS cores require double precision
284 if ( ${CURRENT_WRF_CORE_IDX} GREATER_EQUAL ${START_DA_IDX} AND NOT ${USE_DOUBLE} )
285 # if ( # Apparently set regardless of compiler
286 # ${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU" OR
287 # ${CMAKE_Fortran_COMPILER_ID} STREQUAL "Fujitsu" )
288 message( STATUS "DA and PLUS Core builds require double precision" )
289 set( USE_DOUBLE ON CACHE BOOL "Required by configuration" FORCE )
295 if ( ${BUILD_SBM_FAST} )
296 set( BUILD_SBM_FAST OFF CACHE BOOL "Required by configuration" FORCE )
297 message( STATUS "BUILD_SBM_FAST does not support double, turning off" )
303 math( EXPR RWORDSIZE_B "8 * ${RWORDSIZE}" )
308 if ( NOT ${IPO_SUPPORT} )
309 message( STATUS "IPO/LTO not supported, request ignored" )
310 set( USE_IPO OFF CACHE BOOL "Required by configuration" FORCE )
314 ################################################################################
316 ## Now find packages that cross-compilation is potentially handled
318 ################################################################################
319 # If nesting is enabled, DM_PARALLEL must be set, but if this is a non-MPI compilation
320 # we must stub its usage
321 list( FIND WRF_NESTING_OPTIONS ${WRF_NESTING} CURRENT_NESTING_IDX )
324 set( USE_RSL_LITE OFF )
326 # Through ***MUCH*** debugging, if utilizing MPI_<LANG>_COMPILER
327 # https://cmake.org/cmake/help/latest/module/FindMPI.html#variables-for-locating-mpi
328 # the find logic makes a mess of things by utilizing <mpi> -show[me]
329 # Which may or may not get polluted by the environment
330 # It still technically finds MPI but the output is nonintuitive
331 # saying things like hdf5 or pthread
332 find_package( MPI REQUIRED COMPONENTS Fortran C )
333 list( APPEND PROJECT_COMPILE_DEFINITIONS
338 if ( DEFINED WRF_MPI_Fortran_FLAGS AND NOT "${WRF_MPI_Fortran_FLAGS}" STREQUAL "" )
339 list( APPEND PROJECT_COMPILE_OPTIONS
340 $<$<COMPILE_LANGUAGE:Fortran>:${WRF_MPI_Fortran_FLAGS}>
344 if ( DEFINED WRF_MPI_C_FLAGS AND NOT "${WRF_MPI_C_FLAGS}" STREQUAL "" )
345 list( APPEND PROJECT_COMPILE_OPTIONS
346 $<$<COMPILE_LANGUAGE:C>:${WRF_MPI_C_FLAGS}>
350 # Check if MPI in all its glory has forced IPO down our throats due to hard-coding the wrapper flags
351 # https://www.open-mpi.org/faq/?category=mpi-apps#why-no-rpath LOL!
352 # Quote "The default installation of Open MPI tries very hard to not include any non-essential flags in the wrapper compilers"
353 # Okay, yea sure. Maybe it's the distro's lib config that does add all the bloatware flags
354 if ( NOT ${USE_IPO} )
356 message( STATUS "Checking if MPI requires IPO" )
357 foreach( IPO_FLAG IN LISTS CMAKE_Fortran_COMPILE_OPTIONS_IPO )
358 string( FIND "${MPI_Fortran_COMPILE_OPTIONS}" ${IPO_FLAG} MPI_FORCE_IPO )
359 # Note we are not using IN_LIST since certain IPO settings might not exactly match (e.g. -flto vs -flto=auto)
360 if ( NOT ${MPI_FORCE_IPO} EQUAL -1 )
361 # An IPO flag was found
362 if ( ${IPO_SUPPORT} )
363 message( STATUS "NOTE: ${MPI_Fortran_COMPILER} requires IPO flags be enabled, forcing USE_IPO=ON" )
364 set( USE_IPO ON CACHE BOOL "Required by MPI" FORCE )
367 message( FATAL_ERROR "${MPI_Fortran_COMPILER} requires IPO support but selected compiler does not support it, would fail to link" )
373 set( USE_RSL_LITE ON )
374 # We know NONE is the zero index so compare against that
375 elseif( ${CURRENT_NESTING_IDX} GREATER 0 )
376 list( APPEND PROJECT_COMPILE_DEFINITIONS
380 set( USE_RSL_LITE ON )
384 find_package( OpenMP REQUIRED COMPONENTS Fortran C )
385 list( APPEND PROJECT_COMPILE_DEFINITIONS
397 set( M4_FLAGS ${WRF_M4_FLAGS} -Uinclude -Uindex -Ulen )
402 # HDF5 has some funky weirdness between versions where the casing has changed
410 find_package( Jasper 1.900.1...<1.900.24 )
415 find_package( PIO QUIET )
418 if ( ${ENABLE_TERRAIN} )
422 if ( ${ENABLE_CTSM} )
423 # Will need our own finder
424 # find_package( CTSM REQUIRED )
427 # Will need our own finder
428 # find_package( GPFS REQUIRED )
430 # Included is a lightweight finder, but we really should switch to using UniData's netCDF cmake config
431 # The reason these are two separate and not COMPONENTS of one larger package is because that is the way UniData
432 # has laid out the cmake configs for each respective package
433 find_package( netCDF REQUIRED )
434 find_package( netCDF-Fortran REQUIRED )
436 # Make use of version checking here and not in find_package for previous versions that did not use cmake
437 if ( ( NOT netCDF_VERSION GREATER_EQUAL "4.1.3" ) OR ( NOT netCDF-Fortran_VERSION GREATER_EQUAL "4.1.3" ) )
438 message( FATAL "Please make sure NETCDF versions are 4.1.3 or later. " )
441 find_package( pnetCDF QUIET )
443 # Attempt to find zlib packaged with netcdf first
444 set( ZLIB_ROOT ${netCDF_PREFIX} )
445 find_package( ZLIB REQUIRED )
446 find_package( CURL REQUIRED )
448 ################################################################################
450 ## Print out final set of options to be used
451 ## DO NOT MODIFY OPTIONS BEYOND THIS POINT
453 ################################################################################
455 if ( DEFINED CMAKE_TOOLCHAIN_FILE )
456 print_option( WRF_CONFIG 20 ${BOLD_CYAN} )
459 print_option( CMAKE_BUILD_TYPE 20 ${BOLD_CYAN} )
462 print_option( WRF_CORE 20 ${BOLD_CYAN} )
463 print_option( WRF_NESTING 20 ${BOLD_CYAN} )
464 print_option( WRF_CASE 20 ${BOLD_CYAN} )
467 print_option( USE_DOUBLE 20 )
468 print_option( USE_MPI 20 )
469 print_option( USE_OPENMP 20 )
470 print_option( USE_IPO 20 )
472 print_option( ENABLE_CHEM 20 )
473 print_option( ENABLE_CLM 20 )
474 print_option( ENABLE_CMAQ 20 )
475 print_option( ENABLE_DFI_RADAR 20 )
476 print_option( ENABLE_HYDRO 20 )
477 print_option( ENABLE_KPP 20 )
478 print_option( ENABLE_MARS 20 )
479 print_option( ENABLE_TERRAIN 20 )
480 print_option( ENABLE_TITAN 20 )
481 print_option( ENABLE_VENUS 20 )
483 print_option( USE_ALLOCATABLES 20 )
484 print_option( wrfmodel 20 )
485 print_option( GRIB1 20 )
486 print_option( INTIO 20 )
487 print_option( KEEP_INT_AROUND 20 )
488 print_option( LIMIT_ARGS 20 )
490 print_option( FORCE_NETCDF_CLASSIC 20 )
491 print_option( BUILD_RRTMG_FAST 20 )
492 print_option( BUILD_RRTMK 20 )
493 print_option( BUILD_SBM_FAST 20 )
494 print_option( SHOW_ALL_VARS_USED 20 )
496 print_option( WRFIO_NCD_NO_LARGE_FILE_SUPPORT 36 )
498 ################################################################################
500 ## Set any global cmake options decided by particular configuration
502 ################################################################################
503 set( CMAKE_INTERPROCEDURAL_OPTIMIZATION ${USE_IPO} )
505 ################################################################################
507 ## Configuration checks for features & intrinsices
509 ################################################################################
510 add_subdirectory( confcheck )
512 ################################################################################
514 ## Adjust flags based on compiler and linker used
516 ################################################################################
518 # https://stackoverflow.com/a/47927921
519 # Define compile options to be inherited for directories
522 PROPERTY COMPILE_FLAGS
524 BRIEF_DOCS "brief-doc"
530 PROPERTY COMPILE_FLAGS
532 BRIEF_DOCS "brief-doc"
536 # Get current build type flags and put them in there
537 if ( "${CMAKE_BUILD_TYPE}" STREQUAL "Release" )
538 set_directory_properties(
541 $<$<COMPILE_LANGUAGE:Fortran>:${WRF_FCOPTIM}>
544 # # Assume no optimization
545 # set_directory_properties(
548 # $<$<COMPILE_LANGUAGE:Fortran>:${WRF_FCNOOPT}>
553 # This is really ugly but such is the cost of supporting many ways to say the same thing
554 # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
555 list( APPEND PROJECT_COMPILE_OPTIONS
556 # Use "" and ; specifically to evaluate correctly
557 # "$<$<COMPILE_LANG_AND_ID:Fortran,Absoft>:>" #@ Absoft Fortran
558 # "$<$<COMPILE_LANG_AND_ID:Fortran,ADSP>:>" #@ Analog VisualDSP++
559 # "$<$<COMPILE_LANG_AND_ID:Fortran,AppleClang>:>" #@ Apple Clang
560 # "$<$<COMPILE_LANG_AND_ID:Fortran,ARMCC>:>" #@ ARM Compiler
561 # "$<$<COMPILE_LANG_AND_ID:Fortran,ARMClang>:>" #@ ARM Compiler based on Clang
562 # "$<$<COMPILE_LANG_AND_ID:Fortran,Bruce>:>" #@ Bruce C Compiler
563 # "$<$<COMPILE_LANG_AND_ID:Fortran,CCur>:>" #@ Concurrent Fortran
564 # "$<$<COMPILE_LANG_AND_ID:Fortran,Clang>:>" #@ LLVM Clang
565 "$<$<COMPILE_LANG_AND_ID:Fortran,Cray>:-s;integer32;-s;real${RWORDSIZE_B}>" #@ Cray Compiler
566 # "$<$<COMPILE_LANG_AND_ID:Fortran,Embarcadero>:>" #@ Embarcadero
567 "$<$<AND:$<BOOL:${USE_DOUBLE}>,$<COMPILE_LANG_AND_ID:Fortran,Flang>>:-fdefault-real-${RWORDSIZE}>" #@ Classic Flang Fortran Compiler
568 # "$<$<COMPILE_LANG_AND_ID:Fortran,LLVMFlang>:>" #@ LLVM Flang Fortran Compiler
569 "$<$<COMPILE_LANG_AND_ID:Fortran,Fujitsu>:-CcdRR${RWORDSIZE}>" #@ Fujitsu HPC compiler (Trad mode)
570 # "$<$<COMPILE_LANG_AND_ID:Fortran,FujitsuClang>:>" #@ Fujitsu HPC compiler (Clang mode)
571 "$<$<COMPILE_LANG_AND_ID:Fortran,G95>:-r${RWORDSIZE};-i4>" #@ G95 Fortran
572 "$<$<AND:$<BOOL:${USE_DOUBLE}>,$<COMPILE_LANG_AND_ID:Fortran,GNU>>:-fdefault-real-${RWORDSIZE}>" #@ GNU Compiler Collection
573 # "$<$<COMPILE_LANG_AND_ID:Fortran,GHS>:>" #@ Green Hills Software
574 # "$<$<COMPILE_LANG_AND_ID:Fortran,HP>:>" #@ Hewlett-Packard Compiler
575 # "$<$<COMPILE_LANG_AND_ID:Fortran,IAR>:>" #@ IAR Systems
576 "$<$<COMPILE_LANG_AND_ID:Fortran,Intel>:-real-size;${RWORDSIZE_B};-i4>" #@ Intel Classic Compiler
577 "$<$<COMPILE_LANG_AND_ID:Fortran,IntelLLVM>:-real-size;${RWORDSIZE_B};-i4>" #@ Intel LLVM-Based Compiler
578 # "$<$<COMPILE_LANG_AND_ID:Fortran,LCC>:>" #@ MCST Elbrus C/C++/Fortran Compiler
579 # "$<$<COMPILE_LANG_AND_ID:Fortran,MSVC>:>" #@ Microsoft Visual Studio
580 "$<$<COMPILE_LANG_AND_ID:Fortran,NVHPC>:-r${RWORDSIZE};-i4>" #@ NVIDIA HPC Compiler
581 # "$<$<COMPILE_LANG_AND_ID:Fortran,NVIDIA>:>" #@ NVIDIA CUDA Compiler
582 # "$<$<COMPILE_LANG_AND_ID:Fortran,OpenWatcom>:>" #@ Open Watcom
583 "$<$<COMPILE_LANG_AND_ID:Fortran,PGI>:-r${RWORDSIZE};-i4>" #@ The Portland Group
584 "$<$<COMPILE_LANG_AND_ID:Fortran,PathScale>:-r${RWORDSIZE};-i4>" #@ PathScale
585 # "$<$<COMPILE_LANG_AND_ID:Fortran,SDCC>:>" #@ Small Device C Compiler
586 # "$<$<COMPILE_LANG_AND_ID:Fortran,SunPro>:>" #@ Oracle Solaris Studio
587 # "$<$<COMPILE_LANG_AND_ID:Fortran,Tasking>:>" #@ Tasking Compiler Toolsets
588 # "$<$<COMPILE_LANG_AND_ID:Fortran,TI>:>" #@ Texas Instruments
589 # "$<$<COMPILE_LANG_AND_ID:Fortran,TinyCC>:>" #@ Tiny C Compiler
590 "$<$<COMPILE_LANG_AND_ID:Fortran,XL>:-qrealsize=${RWORDSIZE};-qintsize=4>" #@ IBM XL
591 # "$<$<COMPILE_LANG_AND_ID:Fortran,XLClang>:>" #@ IBM Clang-based XL
592 # "$<$<COMPILE_LANG_AND_ID:Fortran,IBMClang>:>" #@ IBM LLVM-based Compiler
593 # Todo find how to handle default selection or add new compiler IDs
594 # unknown how to add support for sxf90
597 "$<$<COMPILE_LANG_AND_ID:Fortran,GNU>:-ffree-line-length-none>" #@ GNU Compiler Collection
601 # https://stackoverflow.com/a/53155812
602 # set( Fortran_COMPILER_ID ${CMAKE_Fortran_COMPILER_ID} )
603 # message( STATUS "Set Fortran_COMPILER_ID to : ${Fortran_COMPILER_ID}" )
606 # Whole project flags
607 list( APPEND PROJECT_COMPILE_OPTIONS
608 # $<$<COMPILE_LANGUAGE:Fortran>:-cpp>
609 # Use "" and ; specifically to evaluate correctly
610 "$<$<COMPILE_LANG_AND_ID:Fortran,Intel>:-diag-disable;6843>"
611 $<$<AND:$<COMPILE_LANG_AND_ID:Fortran,GNU>,$<VERSION_GREATER_EQUAL:${CMAKE_Fortran_COMPILER_VERSION},10>>:-fallow-argument-mismatch>
612 $<$<AND:$<COMPILE_LANG_AND_ID:Fortran,GNU>,$<VERSION_GREATER_EQUAL:${CMAKE_Fortran_COMPILER_VERSION},10>>:-fallow-invalid-boz>
613 $<$<AND:$<COMPILE_LANG_AND_ID:Fortran,GNU>,$<VERSION_GREATER_EQUAL:${CMAKE_Fortran_COMPILER_VERSION},10>>:-ffree-line-length-none>
615 # $<AND:$<COMPILE_LANGUAGE:Fortran>,$<STREQUAL:${Fortran_COMPILER_ID},Intel>:-diag-disable;6843>
618 if ( ${PROFILE_COMPILATION} )
619 message( STATUS "Attemping to add compilation profiling..." )
620 list( APPEND PROJECT_COMPILE_OPTIONS $<$<COMPILE_LANG_AND_ID:Fortran,GNU>:-ftime-report> )
623 list( APPEND PROJECT_COMPILE_DEFINITIONS
624 MAX_DOMAINS_F=${MAX_DOMAINS_F}
625 CONFIG_BUF_LEN=${CONFIG_BUF_LEN}
626 MAX_HISTORY=${MAX_HISTORY}
627 IWORDSIZE=${IWORDSIZE}
628 DWORDSIZE=${DWORDSIZE}
629 LWORDSIZE=${LWORDSIZE}
630 RWORDSIZE=${RWORDSIZE}
637 #!TODO Change this to a confcheck
638 NONSTANDARD_SYSTEM_SUBR
645 # Only define if set, this is to use #ifdef/#ifndef preprocessors
646 # in code since cmake cannot handle basically any others :(
647 # https://gitlab.kitware.com/cmake/cmake/-/issues/17398
648 if ( ${ENABLE_CHEM} )
649 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_CHEM=1 )
651 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_KPP=1 )
654 if ( ${ENABLE_CHEM} )
655 list( APPEND PROJECT_COMPILE_DEFINITIONS BUILD_CHEM=1 )
657 if ( ${ENABLE_CMAQ} )
658 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_CMAQ=1 )
660 if ( ${ENABLE_DFI_RADAR} )
661 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_DFI_RADAR=1 )
663 if ( ${ENABLE_TITAN} )
664 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_TITAN=1 )
666 if ( ${ENABLE_MARS} )
667 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_MARS=1 )
669 if ( ${ENABLE_VENUS} )
670 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_VENUS=1 )
672 if ( ${ENABLE_HYDRO} )
673 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_HYDRO=1 )
676 # Because once again we need two defines to control one thing
677 if ( ${ENABLE_CTSM} )
678 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_USE_CTSM )
680 #!TODO there are some files that rely on this being 1, but that is never set by the legacy make system
681 list( APPEND PROJECT_COMPILE_DEFINITIONS WRF_USE_CLM )
684 # If force classic or no nc-4 support enable classic
685 if ( ${FORCE_NETCDF_CLASSIC} OR ( NOT ${netCDF_NC4} ) )
686 list( APPEND PROJECT_COMPILE_DEFINITIONS NETCDF_classic=1 )
688 if ( ${WRFIO_NCD_NO_LARGE_FILE_SUPPORT} OR ( NOT ${netCDF_LARGE_FILE_SUPPORT} ) )
689 list( APPEND PROJECT_COMPILE_DEFINITIONS WRFIO_NCD_NO_LARGE_FILE_SUPPORT=1 )
691 # May need a check for WRFIO_ncdpar_LARGE_FILE_SUPPORT
693 # Now set the opposite in different defines, because why not :)
694 if ( ( NOT ${FORCE_NETCDF_CLASSIC} ) AND ${netCDF_NC4} )
695 list( APPEND PROJECT_COMPILE_DEFINITIONS USE_NETCDF4_FEATURES=1 )
697 if ( ( NOT ${WRFIO_NCD_NO_LARGE_FILE_SUPPORT} ) AND ${netCDF_LARGE_FILE_SUPPORT} )
698 list( APPEND PROJECT_COMPILE_DEFINITIONS WRFIO_NCD_LARGE_FILE_SUPPORT=1 )
701 # Could simplify logic to just check if RPC is available but to be explicit
702 # Does this actually need to check for EM_CORE (Config.pl:443)
703 # not enable terran or not rpc_found do
704 # not ( enable terrain and rpc_found )
705 # if ( NOT ( ${ENABLE_TERRAIN} AND ${RPC_FOUND} ) ) # this is wrong, needs fixing
706 # list( APPEND PROJECT_COMPILE_DEFINITIONS LANDREAD_STUB )
708 if ( ${ENABLE_TERRAIN} AND ${MOVE_NESTS} )
709 list( APPEND PROJECT_COMPILE_DEFINITIONS TERRAIN_AND_LANDUSE )
711 list( APPEND PROJECT_COMPILE_DEFINITIONS LANDREAD_STUB )
714 if ( ${USE_ALLOCATABLES} )
715 list( APPEND PROJECT_COMPILE_DEFINITIONS USE_ALLOCATABLES )
718 list( APPEND PROJECT_COMPILE_DEFINITIONS wrfmodel )
721 list( APPEND PROJECT_COMPILE_DEFINITIONS GRIB1 )
724 list( APPEND PROJECT_COMPILE_DEFINITIONS INTIO )
726 if ( ${KEEP_INT_AROUND} )
727 list( APPEND PROJECT_COMPILE_DEFINITIONS KEEP_INT_AROUND )
730 list( APPEND PROJECT_COMPILE_DEFINITIONS LIMIT_ARGS )
734 if ( ${BUILD_RRTMG_FAST} )
735 list( APPEND PROJECT_COMPILE_DEFINITIONS BUILD_RRTMG_FAST=1 )
737 list( APPEND PROJECT_COMPILE_DEFINITIONS BUILD_RRTMG_FAST=0 )
739 if ( ${BUILD_RRTMK} )
740 list( APPEND PROJECT_COMPILE_DEFINITIONS BUILD_RRTMK=1 )
742 list( APPEND PROJECT_COMPILE_DEFINITIONS BUILD_RRTMK=0 )
744 if ( ${BUILD_SBM_FAST} )
745 list( APPEND PROJECT_COMPILE_DEFINITIONS BUILD_SBM_FAST=1 )
747 list( APPEND PROJECT_COMPILE_DEFINITIONS BUILD_SBM_FAST=0 )
749 if ( ${SHOW_ALL_VARS_USED} )
750 list( APPEND PROJECT_COMPILE_DEFINITIONS SHOW_ALL_VARS_USED=1 )
752 list( APPEND PROJECT_COMPILE_DEFINITIONS SHOW_ALL_VARS_USED=0 )
755 list( APPEND PROJECT_COMPILE_DEFINITIONS NMM_CORE=1 )
757 list( APPEND PROJECT_COMPILE_DEFINITIONS NMM_CORE=0 )
760 if ( "${WRF_CORE}" STREQUAL "PLUS" )
761 list( APPEND PROJECT_COMPILE_DEFINITIONS WRFPLUS=1 )
763 list( APPEND PROJECT_COMPILE_DEFINITIONS WRFPLUS=0 )
766 if ( "${WRF_CORE}" STREQUAL "DA_CORE" OR "${WRF_CORE}" STREQUAL "DA_4D_VAR" )
767 list( APPEND PROJECT_COMPILE_DEFINITIONS DA_CORE=1 )
769 list( APPEND PROJECT_COMPILE_DEFINITIONS DA_CORE=0 )
771 # DFI_RADAR=$<BOOL:${NMM_CORE}>
775 list( APPEND PROJECT_COMPILE_DEFINITIONS MOVE_NESTS )
777 if ( "${WRF_NESTING}" STREQUAL "VORTEX" )
778 list( APPEND PROJECT_COMPILE_DEFINITIONS VORTEX_CENTER )
781 # Configuration checks
782 if ( NOT ${Fortran_2003_IEEE} )
783 list( APPEND PROJECT_COMPILE_DEFINITIONS NO_IEEE_MODULE )
785 if ( NOT ${Fortran_2003_ISO_C} )
786 list( APPEND PROJECT_COMPILE_DEFINITIONS NO_ISO_C_SUPPORT )
788 # If flush fails, check if we can fall back to fflush, and if not no support
789 if ( NOT ${Fortran_2003_FLUSH} )
790 if ( "${Fortran_2003_FFLUSH}" )
791 list( APPEND PROJECT_COMPILE_DEFINITIONS USE_FFLUSH )
793 list( APPEND PROJECT_COMPILE_DEFINITIONS NO_FLUSH_SUPPORT )
796 if ( NOT ${Fortran_2003_GAMMA} )
797 list( APPEND PROJECT_COMPILE_DEFINITIONS NO_GAMMA_SUPPORT )
800 #!TODO Leaving as is in WRF for now but investigate why we don't do this
801 # https://stackoverflow.com/a/1035713
802 # If fseeko64 succeeds, use that, else check if we can fall back to fseeko, and if not just use fseek
804 list( APPEND PROJECT_COMPILE_DEFINITIONS FSEEKO64_OK )
805 elseif( "${FSEEKO}" )
806 list( APPEND PROJECT_COMPILE_DEFINITIONS FSEEKO_OK )
808 list( APPEND PROJECT_COMPILE_DEFINITIONS FSEEK_OK )
811 # I don't believe these are used anymore...
812 # $<$<BOOL:${MPI2_SUPPORT}>:MPI2_SUPPORT=$<BOOL:${MPI2_SUPPORT}>>
813 # $<$<BOOL:${MPI2_THREAD_SUPPORT}>:MPI2_THREAD_SUPPORT=$<BOOL:${MPI2_THREAD_SUPPORT}>>
821 target_compile_options(
824 ${PROJECT_COMPILE_OPTIONS}
828 target_compile_definitions(
831 ${PROJECT_COMPILE_DEFINITIONS}
834 # Supplemental to core, or rather should be, some stuff in external is legitimately part of WRF and others
835 # are source code from truly external repositories - albeit old versions
836 add_subdirectory( external )
837 add_subdirectory( tools )
839 # add_dependencies() does not support generator expressions so whatever we can defer to linking please do so
842 # So many things depend on this that I'm adding a dep here
845 target_include_directories(
848 # List module directories first so the compiler does not get confused
849 # about things "not being compiled yet" - yes, yes it is compiled
850 # These are already set up to be @ install location
851 $<TARGET_PROPERTY:esmf_time_f90,Fortran_MODULE_DIRECTORY>
852 $<TARGET_PROPERTY:io_grib_share,Fortran_MODULE_DIRECTORY>
853 $<TARGET_PROPERTY:io_grib1,Fortran_MODULE_DIRECTORY>
854 $<TARGET_PROPERTY:fftpack5,Fortran_MODULE_DIRECTORY>
855 $<TARGET_PROPERTY:io_netcdf,Fortran_MODULE_DIRECTORY>
856 $<TARGET_PROPERTY:io_int,Fortran_MODULE_DIRECTORY>
858 $<TARGET_PROPERTY:${PROJECT_NAME}_Core,Fortran_MODULE_DIRECTORY>
861 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
862 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/inc>
863 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/frame>
864 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/external/ioapi_share>
866 $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/inc>
867 $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/frame>
869 # For install interface includes, i.e. when used by external tools
871 # $<INSTALL_INTERFACE::${PROJECT_SOURCE_DIR}>
872 $<INSTALL_INTERFACE:include/inc>
873 $<INSTALL_INTERFACE:include/frame>
874 $<INSTALL_INTERFACE:include/external/ioapi_share>
876 # May or may not exist
877 $<$<TARGET_EXISTS:atm_ocn>:$<TARGET_PROPERTY:atm_ocn,Fortran_MODULE_DIRECTORY>>
878 $<$<TARGET_EXISTS:io_adios2>:$<TARGET_PROPERTY:io_adios2,Fortran_MODULE_DIRECTORY>>
879 $<$<TARGET_EXISTS:io_esmf>:$<TARGET_PROPERTY:io_esmf,Fortran_MODULE_DIRECTORY>>
880 $<$<TARGET_EXISTS:io_pio>:$<TARGET_PROPERTY:io_pio,Fortran_MODULE_DIRECTORY>>
881 $<$<TARGET_EXISTS:io_netcdfpar>:$<TARGET_PROPERTY:io_netcdfpar,Fortran_MODULE_DIRECTORY>>
882 $<$<TARGET_EXISTS:io_pnetcdf>:$<TARGET_PROPERTY:io_pnetcdf,Fortran_MODULE_DIRECTORY>>
883 $<$<TARGET_EXISTS:io_phdf5>:$<TARGET_PROPERTY:io_phdf5,Fortran_MODULE_DIRECTORY>>
884 $<$<TARGET_EXISTS:g2lib>:$<TARGET_PROPERTY:g2lib,Fortran_MODULE_DIRECTORY>>
885 $<$<TARGET_EXISTS:bacio-1.3>:$<TARGET_PROPERTY:bacio-1.3,Fortran_MODULE_DIRECTORY>>
889 ${PROJECT_SOURCE_DIR}/dyn_em
892 ${PROJECT_SOURCE_DIR}/external/esmf_time_f90
893 ${PROJECT_SOURCE_DIR}/external/io_grib_share
894 ${PROJECT_SOURCE_DIR}/external/io_netcdf
895 ${PROJECT_SOURCE_DIR}/external/io_int
897 # Found Packages not handled through :: imported target
898 ${netCDF_INCLUDE_DIRS}
899 ${netCDF-Fortran_INCLUDE_DIRS}
900 ${pnetCDF_INCLUDE_DIRS}
903 # Add directly to core
904 add_subdirectory( phys )
905 add_subdirectory( share )
906 add_subdirectory( frame )
907 add_subdirectory( inc )
910 add_subdirectory( chem )
913 if ( ${ENABLE_HYDRO} )
914 add_subdirectory( hydro )
917 add_subdirectory( dyn_em )
920 add_subdirectory( main )
922 ################################################################################
923 # Add subdirectory with case info
924 ################################################################################
925 if ( ${CURRENT_WRF_CORE_IDX} GREATER_EQUAL ${START_DA_IDX} )
926 message( STATUS "DA or PLUS build, WRF_CASE selection ignored" )
928 add_subdirectory( test/${WRF_CASE_FOLDER} )
932 set_target_properties(
935 # Just dump everything in here
936 Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/modules/
938 EXPORT_PROPERTIES Fortran_MODULE_DIRECTORY
941 # Because of the way netCDF provides its info and the way cmake auto-gens RPATH, we need to help it along
942 target_link_directories(
945 ${netCDF_LIBRARY_DIR}
946 ${netCDF-Fortran_LIBRARY_DIR}
950 target_link_libraries( ${PROJECT_NAME}_Core
953 ${netCDF-Fortran_LIBRARIES}
955 $<$<BOOL:${USE_MPI}>:$<TARGET_NAME_IF_EXISTS:MPI::MPI_Fortran>>
956 $<$<BOOL:${USE_OPENMP}>:$<TARGET_NAME_IF_EXISTS:OpenMP::OpenMP_Fortran>>
957 # This will add in target dependencies if they exist
958 $<TARGET_NAME_IF_EXISTS:Jasper::Jasper>
959 $<TARGET_NAME_IF_EXISTS:HDF5::HDF5>
960 $<TARGET_NAME_IF_EXISTS:ZLIB::ZLIB>
961 $<TARGET_NAME_IF_EXISTS:CURL::libcurl>
962 $<TARGET_NAME_IF_EXISTS:RPC::RPC>
977 $<TARGET_NAME_IF_EXISTS:wrfhydro>
978 $<TARGET_NAME_IF_EXISTS:atm_ocn>
979 $<TARGET_NAME_IF_EXISTS:io_adios2>
980 $<TARGET_NAME_IF_EXISTS:io_esmf>
981 $<TARGET_NAME_IF_EXISTS:io_pio>
984 $<TARGET_NAME_IF_EXISTS:io_netcdfpar>
985 $<TARGET_NAME_IF_EXISTS:io_pnetcdf>
986 $<TARGET_NAME_IF_EXISTS:io_phdf5>
988 $<TARGET_NAME_IF_EXISTS:g2lib>
989 $<TARGET_NAME_IF_EXISTS:bacio-1.3>
991 $<TARGET_NAME_IF_EXISTS:RSL_LITE>
994 ################################################################################
996 ## Install and export
998 ################################################################################
999 set( CONFIG_INSTALL_DIRECTORY lib/cmake/${PROJECT_NAME} )
1001 TARGETS ${PROJECT_NAME}_Core
1002 EXPORT ${EXPORT_NAME}Targets
1003 RUNTIME DESTINATION bin/
1004 ARCHIVE DESTINATION lib/
1005 LIBRARY DESTINATION lib/
1008 # Install to namespace
1010 EXPORT ${EXPORT_NAME}Targets
1011 DESTINATION ${CONFIG_INSTALL_DIRECTORY}
1012 FILE ${EXPORT_NAME}Targets.cmake
1013 NAMESPACE ${EXPORT_NAME}::
1016 configure_package_config_file(
1017 ${PROJECT_SOURCE_DIR}/cmake/template/${EXPORT_NAME}Config.cmake.in
1018 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}Config.cmake
1019 INSTALL_DESTINATION ${CONFIG_INSTALL_DIRECTORY}
1022 write_basic_package_version_file(
1023 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}ConfigVersion.cmake
1024 VERSION ${PROJECT_VERSION}
1025 #!TODO Check if this is the type of versioning support we want to use
1026 COMPATIBILITY SameMinorVersion
1031 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}Config.cmake
1032 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}ConfigVersion.cmake
1033 DESTINATION ${CONFIG_INSTALL_DIRECTORY}
1036 # Install some helper files for anyone using this build as part of their code
1039 # Trailing / is important
1040 ${PROJECT_SOURCE_DIR}/cmake/modules/
1048 ${PROJECT_SOURCE_DIR}/cmake/confcheck.cmake
1049 ${PROJECT_SOURCE_DIR}/cmake/gitinfo.cmake
1050 ${PROJECT_SOURCE_DIR}/cmake/printOption.cmake
1051 ${PROJECT_SOURCE_DIR}/cmake/wrf_get_version.cmake