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
132 set( WRF_CASE "" CACHE STRING "WRF_CASE" )
133 if ( "${WRF_CASE}" STREQUAL "" )
134 # Set default WRF_CASE
135 list( GET WRF_CASE_OPTIONS 0 WRF_CASE )
138 # DO NOT USE OPTION - IT DOES NOT WORK AS ANTICIPATED EVEN WHEN CLEARING CACHE - YOU HAVE BEEN WARNED
139 # If you add anything here, the description should be the name itself - this helps the configuration script
140 set( USE_DOUBLE OFF CACHE BOOL "USE_DOUBLE" )
141 set( USE_MPI OFF CACHE BOOL "USE_MPI" )
142 set( USE_OPENMP OFF CACHE BOOL "USE_OPENMP" )
143 set( USE_HDF5 OFF CACHE BOOL "USE_HDF5" )
144 set( USE_JASPER OFF CACHE BOOL "USE_JASPER" )
145 set( USE_PIO OFF CACHE BOOL "USE_PIO" )
146 set( USE_IPO OFF CACHE BOOL "USE_IPO" )
149 set( ENABLE_CHEM OFF CACHE BOOL "ENABLE_CHEM" )
150 set( ENABLE_CMAQ OFF CACHE BOOL "ENABLE_CMAQ" )
151 set( ENABLE_CTSM OFF CACHE BOOL "ENABLE_CTSM" )
152 set( ENABLE_DFI_RADAR OFF CACHE BOOL "ENABLE_DFI_RADAR" )
153 set( ENABLE_HYDRO OFF CACHE BOOL "ENABLE_HYDRO" )
154 set( ENABLE_KPP OFF CACHE BOOL "ENABLE_KPP" )
155 set( ENABLE_MARS OFF CACHE BOOL "ENABLE_MARS" )
156 set( ENABLE_TERRAIN OFF CACHE BOOL "ENABLE_TERRAIN" )
157 set( ENABLE_TITAN OFF CACHE BOOL "ENABLE_TITAN" )
158 set( ENABLE_VENUS OFF CACHE BOOL "ENABLE_VENUS" )
160 # What do these defines even do if they are always on????
161 set( USE_ALLOCATABLES ON CACHE BOOL "USE_ALLOCATABLES" )
162 set( wrfmodel ON CACHE BOOL "wrfmodel" )
163 set( GRIB1 ON CACHE BOOL "GRIB1" )
164 set( INTIO ON CACHE BOOL "INTIO" )
165 set( KEEP_INT_AROUND ON CACHE BOOL "KEEP_INT_AROUND" )
166 set( LIMIT_ARGS ON CACHE BOOL "LIMIT_ARGS" )
168 # Toggles, how do we want to best address these options? Environment vars are not
170 set( WRFIO_NCD_NO_LARGE_FILE_SUPPORT OFF CACHE BOOL "WRFIO_NCD_NO_LARGE_FILE_SUPPORT" )
171 set( FORCE_NETCDF_CLASSIC OFF CACHE BOOL "FORCE_NETCDF_CLASSIC" )
172 set( BUILD_RRTMG_FAST OFF CACHE BOOL "BUILD_RRTMG_FAST" )
173 set( BUILD_RRTMK OFF CACHE BOOL "BUILD_RRTMK" )
174 set( BUILD_SBM_FAST ON CACHE BOOL "BUILD_SBM_FAST" )
175 set( SHOW_ALL_VARS_USED OFF CACHE BOOL "SHOW_ALL_VARS_USED" )
178 # TODO investigate if this needs set
179 # Not cached, cannot be changed, do not touch
181 # Same thing -what do these defines even do if they are always on????
186 # Special internal flag for profiling compilation
187 set( PROFILE_COMPILATION OFF CACHE BOOL "PROFILE_COMPILATION" )
191 #### Single location for defining total number of domains. You need
192 #### at least 1 + 2*(number of total nests). For example, 1 coarse
193 #### grid + three fine grids = 1 + 2(3) = 7, so MAX_DOMAINS=7.
194 set( MAX_DOMAINS_F 21 )
197 #### DM buffer length for the configuration flags.
199 set( CONFIG_BUF_LEN 65536 )
201 #### Size of bitmasks (in 4byte integers) of stream masks for WRF I/O
203 set( MAX_HISTORY 25 )
210 ########################
212 ################################################################################
214 ## Load options selected and any ancillary logic
216 ################################################################################
219 if ( NOT ${WRF_CORE} IN_LIST WRF_CORE_OPTIONS )
220 message( FATAL_ERROR "WRF Core option not recognized : ${WRF_CORE}" )
223 if ( NOT ${WRF_NESTING} IN_LIST WRF_NESTING_OPTIONS )
224 message( FATAL_ERROR "WRF Nesting option not recognized : ${WRF_NESTING}" )
227 if ( NOT ${WRF_CASE} IN_LIST WRF_CASE_OPTIONS )
228 message( FATAL_ERROR "WRF Case option not recognized : ${WRF_CASE}" )
233 # Far easier to write this one as normal logic rather than generator expression
234 if( ${WRF_CORE} STREQUAL "CONVERT" OR ${WRF_CORE} STREQUAL "COAMPS" )
239 # Far easier to write this one as normal logic rather than generator expression
240 if( ${WRF_NESTING} STREQUAL "MOVES" OR ${WRF_NESTING} STREQUAL "VORTEX" )
244 if ( ${ENABLE_KPP} AND NOT ${ENABLE_CHEM} )
245 message( WARNING "ENABLE_KPP requires ENABLE_CHEM but is not set, ignoring" )
249 # Additional information on the type of case we are compiling
250 string( TOLOWER ${WRF_CASE} WRF_CASE_FOLDER )
251 string( REPLACE "em_" "" WRF_CASE_MODULE ${WRF_CASE_FOLDER} )
253 # Find if it is a specialized ideal case or general
254 list( FIND WRF_CASE_OPTIONS EM_B_WAVE START_GENERAL_IDEAL_CASE_IDX )
255 list( FIND WRF_CASE_OPTIONS ${WRF_CASE} CURRENT_CASE_IDX )
256 set( WRF_GENERAL_IDEAL_CASE TRUE )
257 if ( ${CURRENT_CASE_IDX} LESS ${START_GENERAL_IDEAL_CASE_IDX} )
258 set( WRF_GENERAL_IDEAL_CASE FALSE )
261 if ( NOT ${WRFIO_NCD_NO_LARGE_FILE_SUPPORT} )
262 message( STATUS "netCDF large file support not suppressed, if available it will be used" )
265 # Hydro option requires MPI
266 if ( ${ENABLE_HYDRO} AND NOT ${USE_MPI} )
267 message( STATUS "WRF Hydro requires MPI usage" )
268 set( USE_MPI ON CACHE BOOL "Required by configuration" FORCE )
271 # Handle double promotion - doing this here instead of from config.cmake toolchain
272 # file since the double promotion logic is a nightmare
273 list( FIND WRF_CORE_OPTIONS ${WRF_CORE} CURRENT_WRF_CORE_IDX )
274 list( FIND WRF_CORE_OPTIONS "DA" START_DA_IDX )
275 # DA + WRF PLUS cores require double precision
276 if ( ${CURRENT_WRF_CORE_IDX} GREATER_EQUAL ${START_DA_IDX} AND NOT ${USE_DOUBLE} )
277 # if ( # Apparently set regardless of compiler
278 # ${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU" OR
279 # ${CMAKE_Fortran_COMPILER_ID} STREQUAL "Fujitsu" )
280 message( STATUS "DA and PLUS Core builds require double precision" )
281 set( USE_DOUBLE ON CACHE BOOL "Required by configuration" FORCE )
287 if ( ${BUILD_SBM_FAST} )
288 set( BUILD_SBM_FAST OFF CACHE BOOL "Required by configuration" FORCE )
289 message( STATUS "BUILD_SBM_FAST does not support double, turning off" )
295 math( EXPR RWORDSIZE_B "8 * ${RWORDSIZE}" )
300 if ( NOT ${IPO_SUPPORT} )
301 message( STATUS "IPO/LTO not supported, request ignored" )
302 set( USE_IPO OFF CACHE BOOL "Required by configuration" FORCE )
306 ################################################################################
308 ## Now find packages that cross-compilation is potentially handled
310 ################################################################################
311 # If nesting is enabled, DM_PARALLEL must be set, but if this is a non-MPI compilation
312 # we must stub its usage
313 list( FIND WRF_NESTING_OPTIONS ${WRF_NESTING} CURRENT_NESTING_IDX )
316 set( USE_RSL_LITE OFF )
318 # Through ***MUCH*** debugging, if utilizing MPI_<LANG>_COMPILER
319 # https://cmake.org/cmake/help/latest/module/FindMPI.html#variables-for-locating-mpi
320 # the find logic makes a mess of things by utilizing <mpi> -show[me]
321 # Which may or may not get polluted by the environment
322 # It still technically finds MPI but the output is nonintuitive
323 # saying things like hdf5 or pthread
324 find_package( MPI REQUIRED COMPONENTS Fortran C )
325 add_compile_definitions(
330 if ( DEFINED WRF_MPI_Fortran_FLAGS AND NOT "${WRF_MPI_Fortran_FLAGS}" STREQUAL "" )
332 $<$<COMPILE_LANGUAGE:Fortran>:${WRF_MPI_Fortran_FLAGS}>
336 if ( DEFINED WRF_MPI_C_FLAGS AND NOT "${WRF_MPI_C_FLAGS}" STREQUAL "" )
338 $<$<COMPILE_LANGUAGE:C>:${WRF_MPI_C_FLAGS}>
342 # Check if MPI in all its glory has forced IPO down our throats due to hard-coding the wrapper flags
343 # https://www.open-mpi.org/faq/?category=mpi-apps#why-no-rpath LOL!
344 # Quote "The default installation of Open MPI tries very hard to not include any non-essential flags in the wrapper compilers"
345 # Okay, yea sure. Maybe it's the distro's lib config that does add all the bloatware flags
346 if ( NOT ${USE_IPO} )
348 message( STATUS "Checking if MPI requires IPO" )
349 foreach( IPO_FLAG IN LISTS CMAKE_Fortran_COMPILE_OPTIONS_IPO )
350 string( FIND "${MPI_Fortran_COMPILE_OPTIONS}" ${IPO_FLAG} MPI_FORCE_IPO )
351 # Note we are not using IN_LIST since certain IPO settings might not exactly match (e.g. -flto vs -flto=auto)
352 if ( NOT ${MPI_FORCE_IPO} EQUAL -1 )
353 # An IPO flag was found
354 if ( ${IPO_SUPPORT} )
355 message( STATUS "NOTE: ${MPI_Fortran_COMPILER} requires IPO flags be enabled, forcing USE_IPO=ON" )
356 set( USE_IPO ON CACHE BOOL "Required by MPI" FORCE )
359 message( FATAL_ERROR "${MPI_Fortran_COMPILER} requires IPO support but selected compiler does not support it, would fail to link" )
365 set( USE_RSL_LITE ON )
366 # We know NONE is the zero index so compare against that
367 elseif( ${CURRENT_NESTING_IDX} GREATER 0 )
368 add_compile_definitions(
372 set( USE_RSL_LITE ON )
376 find_package( OpenMP REQUIRED COMPONENTS Fortran C )
377 add_compile_definitions( USE_OPENMP=1 SM_PARALLEL )
386 set( M4_FLAGS ${WRF_M4_FLAGS} -Uinclude -Uindex -Ulen )
391 # HDF5 has some funky weirdness between versions where the casing has changed
399 find_package( Jasper 1.900.1...<1.900.24 )
404 find_package( PIO QUIET )
407 if ( ${ENABLE_TERRAIN} )
411 if ( ${ENABLE_CTSM} )
412 # Will need our own finder
413 # find_package( CTSM REQUIRED )
416 # Will need our own finder
417 # find_package( GPFS REQUIRED )
419 # Included is a lightweight finder, but we really should switch to using UniData's netCDF cmake config
420 # The reason these are two separate and not COMPONENTS of one larger package is because that is the way UniData
421 # has laid out the cmake configs for each respective package
422 find_package( netCDF REQUIRED )
423 find_package( netCDF-Fortran REQUIRED )
425 # Make use of version checking here and not in find_package for previous versions that did not use cmake
426 if ( ( NOT netCDF_VERSION GREATER_EQUAL "4.1.3" ) OR ( NOT netCDF-Fortran_VERSION GREATER_EQUAL "4.1.3" ) )
427 message( FATAL "Please make sure NETCDF versions are 4.1.3 or later. " )
430 find_package( pnetCDF QUIET )
432 # Attempt to find zlib packaged with netcdf first
433 set( ZLIB_ROOT ${netCDF_PREFIX} )
434 find_package( ZLIB REQUIRED )
435 find_package( CURL REQUIRED )
437 ################################################################################
439 ## Print out final set of options to be used
440 ## DO NOT MODIFY OPTIONS BEYOND THIS POINT
442 ################################################################################
444 if ( DEFINED CMAKE_TOOLCHAIN_FILE )
445 print_option( WRF_CONFIG 20 ${BOLD_CYAN} )
448 print_option( CMAKE_BUILD_TYPE 20 ${BOLD_CYAN} )
451 print_option( WRF_CORE 20 ${BOLD_CYAN} )
452 print_option( WRF_NESTING 20 ${BOLD_CYAN} )
453 print_option( WRF_CASE 20 ${BOLD_CYAN} )
456 print_option( USE_DOUBLE 20 )
457 print_option( USE_MPI 20 )
458 print_option( USE_OPENMP 20 )
459 print_option( USE_IPO 20 )
461 print_option( ENABLE_CHEM 20 )
462 print_option( ENABLE_CLM 20 )
463 print_option( ENABLE_CMAQ 20 )
464 print_option( ENABLE_DFI_RADAR 20 )
465 print_option( ENABLE_HYDRO 20 )
466 print_option( ENABLE_KPP 20 )
467 print_option( ENABLE_MARS 20 )
468 print_option( ENABLE_TERRAIN 20 )
469 print_option( ENABLE_TITAN 20 )
470 print_option( ENABLE_VENUS 20 )
472 print_option( USE_ALLOCATABLES 20 )
473 print_option( wrfmodel 20 )
474 print_option( GRIB1 20 )
475 print_option( INTIO 20 )
476 print_option( KEEP_INT_AROUND 20 )
477 print_option( LIMIT_ARGS 20 )
479 print_option( FORCE_NETCDF_CLASSIC 20 )
480 print_option( BUILD_RRTMG_FAST 20 )
481 print_option( BUILD_RRTMK 20 )
482 print_option( BUILD_SBM_FAST 20 )
483 print_option( SHOW_ALL_VARS_USED 20 )
485 print_option( WRFIO_NCD_NO_LARGE_FILE_SUPPORT 36 )
487 ################################################################################
489 ## Set any global cmake options decided by particular configuration
491 ################################################################################
492 set( CMAKE_INTERPROCEDURAL_OPTIMIZATION ${USE_IPO} )
494 ################################################################################
496 ## Configuration checks for features & intrinsices
498 ################################################################################
499 add_subdirectory( confcheck )
501 ################################################################################
503 ## Adjust flags based on compiler and linker used
505 ################################################################################
507 # https://stackoverflow.com/a/47927921
508 # Define compile options to be inherited for directories
511 PROPERTY COMPILE_FLAGS
513 BRIEF_DOCS "brief-doc"
519 PROPERTY COMPILE_FLAGS
521 BRIEF_DOCS "brief-doc"
525 # Get current build type flags and put them in there
526 if ( "${CMAKE_BUILD_TYPE}" STREQUAL "Release" )
527 set_directory_properties(
530 $<$<COMPILE_LANGUAGE:Fortran>:${WRF_FCOPTIM}>
533 # # Assume no optimization
534 # set_directory_properties(
537 # $<$<COMPILE_LANGUAGE:Fortran>:${WRF_FCNOOPT}>
542 # This is really ugly but such is the cost of supporting many ways to say the same thing
543 # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
545 # Use "" and ; specifically to evaluate correctly
546 # "$<$<COMPILE_LANG_AND_ID:Fortran,Absoft>:>" #@ Absoft Fortran
547 # "$<$<COMPILE_LANG_AND_ID:Fortran,ADSP>:>" #@ Analog VisualDSP++
548 # "$<$<COMPILE_LANG_AND_ID:Fortran,AppleClang>:>" #@ Apple Clang
549 # "$<$<COMPILE_LANG_AND_ID:Fortran,ARMCC>:>" #@ ARM Compiler
550 # "$<$<COMPILE_LANG_AND_ID:Fortran,ARMClang>:>" #@ ARM Compiler based on Clang
551 # "$<$<COMPILE_LANG_AND_ID:Fortran,Bruce>:>" #@ Bruce C Compiler
552 # "$<$<COMPILE_LANG_AND_ID:Fortran,CCur>:>" #@ Concurrent Fortran
553 # "$<$<COMPILE_LANG_AND_ID:Fortran,Clang>:>" #@ LLVM Clang
554 "$<$<COMPILE_LANG_AND_ID:Fortran,Cray>:-s;integer32;-s;real${RWORDSIZE_B}>" #@ Cray Compiler
555 # "$<$<COMPILE_LANG_AND_ID:Fortran,Embarcadero>:>" #@ Embarcadero
556 "$<$<AND:$<BOOL:${USE_DOUBLE}>,$<COMPILE_LANG_AND_ID:Fortran,Flang>>:-fdefault-real-${RWORDSIZE}>" #@ Classic Flang Fortran Compiler
557 # "$<$<COMPILE_LANG_AND_ID:Fortran,LLVMFlang>:>" #@ LLVM Flang Fortran Compiler
558 "$<$<COMPILE_LANG_AND_ID:Fortran,Fujitsu>:-CcdRR${RWORDSIZE}>" #@ Fujitsu HPC compiler (Trad mode)
559 # "$<$<COMPILE_LANG_AND_ID:Fortran,FujitsuClang>:>" #@ Fujitsu HPC compiler (Clang mode)
560 "$<$<COMPILE_LANG_AND_ID:Fortran,G95>:-r${RWORDSIZE};-i4>" #@ G95 Fortran
561 "$<$<AND:$<BOOL:${USE_DOUBLE}>,$<COMPILE_LANG_AND_ID:Fortran,GNU>>:-fdefault-real-${RWORDSIZE}>" #@ GNU Compiler Collection
562 # "$<$<COMPILE_LANG_AND_ID:Fortran,GHS>:>" #@ Green Hills Software
563 # "$<$<COMPILE_LANG_AND_ID:Fortran,HP>:>" #@ Hewlett-Packard Compiler
564 # "$<$<COMPILE_LANG_AND_ID:Fortran,IAR>:>" #@ IAR Systems
565 "$<$<COMPILE_LANG_AND_ID:Fortran,Intel>:-real-size;${RWORDSIZE_B};-i4>" #@ Intel Classic Compiler
566 "$<$<COMPILE_LANG_AND_ID:Fortran,IntelLLVM>:-real-size;${RWORDSIZE_B};-i4>" #@ Intel LLVM-Based Compiler
567 # "$<$<COMPILE_LANG_AND_ID:Fortran,LCC>:>" #@ MCST Elbrus C/C++/Fortran Compiler
568 # "$<$<COMPILE_LANG_AND_ID:Fortran,MSVC>:>" #@ Microsoft Visual Studio
569 "$<$<COMPILE_LANG_AND_ID:Fortran,NVHPC>:-r${RWORDSIZE};-i4>" #@ NVIDIA HPC Compiler
570 # "$<$<COMPILE_LANG_AND_ID:Fortran,NVIDIA>:>" #@ NVIDIA CUDA Compiler
571 # "$<$<COMPILE_LANG_AND_ID:Fortran,OpenWatcom>:>" #@ Open Watcom
572 "$<$<COMPILE_LANG_AND_ID:Fortran,PGI>:-r${RWORDSIZE};-i4>" #@ The Portland Group
573 "$<$<COMPILE_LANG_AND_ID:Fortran,PathScale>:-r${RWORDSIZE};-i4>" #@ PathScale
574 # "$<$<COMPILE_LANG_AND_ID:Fortran,SDCC>:>" #@ Small Device C Compiler
575 # "$<$<COMPILE_LANG_AND_ID:Fortran,SunPro>:>" #@ Oracle Solaris Studio
576 # "$<$<COMPILE_LANG_AND_ID:Fortran,Tasking>:>" #@ Tasking Compiler Toolsets
577 # "$<$<COMPILE_LANG_AND_ID:Fortran,TI>:>" #@ Texas Instruments
578 # "$<$<COMPILE_LANG_AND_ID:Fortran,TinyCC>:>" #@ Tiny C Compiler
579 "$<$<COMPILE_LANG_AND_ID:Fortran,XL>:-qrealsize=${RWORDSIZE};-qintsize=4>" #@ IBM XL
580 # "$<$<COMPILE_LANG_AND_ID:Fortran,XLClang>:>" #@ IBM Clang-based XL
581 # "$<$<COMPILE_LANG_AND_ID:Fortran,IBMClang>:>" #@ IBM LLVM-based Compiler
582 # Todo find how to handle default selection or add new compiler IDs
583 # unknown how to add support for sxf90
586 "$<$<COMPILE_LANG_AND_ID:Fortran,GNU>:-ffree-line-length-none>" #@ GNU Compiler Collection
590 # https://stackoverflow.com/a/53155812
591 # set( Fortran_COMPILER_ID ${CMAKE_Fortran_COMPILER_ID} )
592 # message( STATUS "Set Fortran_COMPILER_ID to : ${Fortran_COMPILER_ID}" )
595 # Whole project flags
597 # $<$<COMPILE_LANGUAGE:Fortran>:-cpp>
598 # Use "" and ; specifically to evaluate correctly
599 "$<$<COMPILE_LANG_AND_ID:Fortran,Intel>:-diag-disable;6843>"
600 $<$<AND:$<COMPILE_LANG_AND_ID:Fortran,GNU>,$<VERSION_GREATER_EQUAL:${CMAKE_Fortran_COMPILER_VERSION},10>>:-fallow-argument-mismatch>
601 $<$<AND:$<COMPILE_LANG_AND_ID:Fortran,GNU>,$<VERSION_GREATER_EQUAL:${CMAKE_Fortran_COMPILER_VERSION},10>>:-fallow-invalid-boz>
602 $<$<AND:$<COMPILE_LANG_AND_ID:Fortran,GNU>,$<VERSION_GREATER_EQUAL:${CMAKE_Fortran_COMPILER_VERSION},10>>:-ffree-line-length-none>
604 # $<AND:$<COMPILE_LANGUAGE:Fortran>,$<STREQUAL:${Fortran_COMPILER_ID},Intel>:-diag-disable;6843>
607 if ( ${PROFILE_COMPILATION} )
608 message( STATUS "Attemping to add compilation profiling..." )
610 $<$<COMPILE_LANG_AND_ID:Fortran,GNU>:-ftime-report>
614 add_compile_definitions(
615 MAX_DOMAINS_F=${MAX_DOMAINS_F}
616 CONFIG_BUF_LEN=${CONFIG_BUF_LEN}
617 MAX_HISTORY=${MAX_HISTORY}
618 IWORDSIZE=${IWORDSIZE}
619 DWORDSIZE=${DWORDSIZE}
620 LWORDSIZE=${LWORDSIZE}
621 RWORDSIZE=${RWORDSIZE}
622 # Only define if set, this is to use #ifdef/#ifndef preprocessors
623 # in code since cmake cannot handle basically any others :(
624 # https://gitlab.kitware.com/cmake/cmake/-/issues/17398
625 $<$<BOOL:${ENABLE_CHEM}>:WRF_CHEM=$<BOOL:${ENABLE_CHEM}>>
626 $<$<BOOL:${ENABLE_CHEM}>:BUILD_CHEM=$<BOOL:${ENABLE_CHEM}>>
627 $<$<BOOL:${ENABLE_CMAQ}>:WRF_CMAQ=$<BOOL:${ENABLE_CMAQ}>>
628 $<$<AND:$<BOOL:${ENABLE_CHEM}>,$<BOOL:${ENABLE_KPP}>>:WRF_KPP=$<BOOL:${ENABLE_KPP}>>
629 $<$<BOOL:${ENABLE_DFI_RADAR}>:WRF_DFI_RADAR=$<BOOL:${ENABLE_DFI_RADAR}>>
630 $<$<BOOL:${ENABLE_TITAN}>:WRF_TITAN=$<BOOL:${ENABLE_TITAN}>>
631 $<$<BOOL:${ENABLE_MARS}>:WRF_MARS=$<BOOL:${ENABLE_MARS}>>
632 $<$<BOOL:${ENABLE_VENUS}>:WRF_VENUS=$<BOOL:${ENABLE_VENUS}>>
633 $<$<BOOL:${ENABLE_HYDRO}>:WRF_HYDRO=$<BOOL:${ENABLE_HYDRO}>>
635 # Because once again we need two defines to control one thing
636 $<$<BOOL:${ENABLE_CTSM}>:WRF_USE_CTSM=$<BOOL:${ENABLE_CTSM}>>
637 $<$<NOT:$<BOOL:${ENABLE_CTSM}>>:WRF_USE_CLM>
639 # If force classic or no nc-4 support enable classic
640 $<$<OR:$<BOOL:${FORCE_NETCDF_CLASSIC}>,$<NOT:$<BOOL:${netCDF_NC4}>>>:NETCDF_classic=1>
641 $<$<OR:$<BOOL:${WRFIO_NCD_NO_LARGE_FILE_SUPPORT}>,$<NOT:$<BOOL:${netCDF_LARGE_FILE_SUPPORT}>>>:WRFIO_NCD_NO_LARGE_FILE_SUPPORT=1>
642 # May need a check for WRFIO_ncdpar_LARGE_FILE_SUPPORT
644 # Now set the opposite in different defines, because why not :)
645 $<$<AND:$<NOT:$<BOOL:${FORCE_NETCDF_CLASSIC}>>,$<BOOL:${netCDF_NC4}>>:USE_NETCDF4_FEATURES=1>
646 $<$<AND:$<NOT:$<BOOL:${WRFIO_NCD_NO_LARGE_FILE_SUPPORT}>>,$<BOOL:${netCDF_LARGE_FILE_SUPPORT}>>:WRFIO_NCD_LARGE_FILE_SUPPORT=1>
648 # Could simplify logic to just check if RPC is available but to be explicit
649 # Does this actually need to check for EM_CORE (Config.pl:443)
650 # not enable terran or not rpc_found do
651 # not ( enable terrain and rpc_found )
652 $<$<NOT:$<AND:$<BOOL:${ENABLE_TERRAIN}>,$<BOOL:${RPC_FOUND}>>>:LANDREAD_STUB>
653 $<$<BOOL:${ENABLE_TERRAIN}>:TERRAIN_AND_LANDUSE>
656 $<$<BOOL:${USE_ALLOCATABLES}>:USE_ALLOCATABLES>
657 $<$<BOOL:${wrfmodel}>:wrfmodel>
658 $<$<BOOL:${GRIB1}>:GRIB1>
659 $<$<BOOL:${INTIO}>:INTIO>
660 $<$<BOOL:${KEEP_INT_AROUND}>:KEEP_INT_AROUND>
661 $<$<BOOL:${LIMIT_ARGS}>:LIMIT_ARGS>
663 #!TODO Always defined - fix the ambiguous english in these BUILD_*_FAST defines
664 BUILD_RRTMG_FAST=$<BOOL:${BUILD_RRTMG_FAST}>
665 BUILD_RRTMK=$<BOOL:${BUILD_RRTMK}>
666 BUILD_SBM_FAST=$<BOOL:${BUILD_SBM_FAST}>
667 SHOW_ALL_VARS_USED=$<BOOL:${SHOW_ALL_VARS_USED}>
670 NMM_CORE=$<BOOL:${NMM_CORE}>
674 #!TODO Change this to a confcheck
675 NONSTANDARD_SYSTEM_SUBR
678 WRFPLUS=$<BOOL:$<STREQUAL:${WRF_CORE},"PLUS">>
679 DA_CORE=$<BOOL:$<OR:$<STREQUAL:${WRF_CORE},"DA_CORE">,$<STREQUAL:${WRF_CORE},"DA_4D_VAR">>>
680 # DFI_RADAR=$<BOOL:${NMM_CORE}>
683 $<$<BOOL:${MOVE_NESTS}>:MOVE_NESTS>
684 $<$<BOOL:$<STREQUAL:${WRF_NESTING},"VORTEX">>:VORTEX_CENTER>
686 # Configuration checks
687 $<$<NOT:$<BOOL:${Fortran_2003_IEEE}>>:NO_IEEE_MODULE>
688 $<$<NOT:$<BOOL:${Fortran_2003_ISO_C}>>:NO_ISO_C_SUPPORT>
689 # If flush fails, check if we can fall back to fflush, and if not no support
690 $<$<NOT:$<BOOL:${Fortran_2003_FLUSH}>>:$<IF:$<BOOL:${Fortran_2003_FFLUSH}>,USE_FFLUSH,NO_FLUSH_SUPPORT>>
691 $<$<NOT:$<BOOL:${Fortran_2003_GAMMA}>>:NO_GAMMA_SUPPORT>
693 #!TODO Leaving as is in WRF for now but investigate why we don't do this
694 # https://stackoverflow.com/a/1035713
695 # If fseeko64 succeeds, use that, else check if we can fall back to fseeko, and if not just use fseek
696 $<IF:$<BOOL:${FSEEKO64}>,FSEEKO64_OK,$<IF:$<BOOL:${FSEEKO}>,FSEEKO_OK,FSEEK_OK>>
698 # I don't believe these are used anymore...
699 # $<$<BOOL:${MPI2_SUPPORT}>:MPI2_SUPPORT=$<BOOL:${MPI2_SUPPORT}>>
700 # $<$<BOOL:${MPI2_THREAD_SUPPORT}>:MPI2_THREAD_SUPPORT=$<BOOL:${MPI2_THREAD_SUPPORT}>>
711 # Supplemental to core, or rather should be, some stuff in external is legitimately part of WRF and others
712 # are source code from truly external repositories - albeit old versions
713 add_subdirectory( external )
714 add_subdirectory( tools )
716 # add_dependencies() does not support generator expressions so whatever we can defer to linking please do so
719 # So many things depend on this that I'm adding a dep here
722 target_include_directories(
725 # List module directories first so the compiler does not get confused
726 # about things "not being compiled yet" - yes, yes it is compiled
727 # These are already set up to be @ install location
728 $<TARGET_PROPERTY:esmf_time_f90,Fortran_MODULE_DIRECTORY>
729 $<TARGET_PROPERTY:io_grib_share,Fortran_MODULE_DIRECTORY>
730 $<TARGET_PROPERTY:io_grib1,Fortran_MODULE_DIRECTORY>
731 $<TARGET_PROPERTY:fftpack5,Fortran_MODULE_DIRECTORY>
732 $<TARGET_PROPERTY:io_netcdf,Fortran_MODULE_DIRECTORY>
733 $<TARGET_PROPERTY:io_int,Fortran_MODULE_DIRECTORY>
735 $<TARGET_PROPERTY:${PROJECT_NAME}_Core,Fortran_MODULE_DIRECTORY>
738 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
739 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/inc>
740 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/frame>
741 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/external/ioapi_share>
743 $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/inc>
744 $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/frame>
746 # For install interface includes, i.e. when used by external tools
748 # $<INSTALL_INTERFACE::${PROJECT_SOURCE_DIR}>
749 $<INSTALL_INTERFACE:include/inc>
750 $<INSTALL_INTERFACE:include/frame>
751 $<INSTALL_INTERFACE:include/external/ioapi_share>
753 # May or may not exist
754 $<$<TARGET_EXISTS:atm_ocn>:$<TARGET_PROPERTY:atm_ocn,Fortran_MODULE_DIRECTORY>>
755 $<$<TARGET_EXISTS:io_adios2>:$<TARGET_PROPERTY:io_adios2,Fortran_MODULE_DIRECTORY>>
756 $<$<TARGET_EXISTS:io_esmf>:$<TARGET_PROPERTY:io_esmf,Fortran_MODULE_DIRECTORY>>
757 $<$<TARGET_EXISTS:io_pio>:$<TARGET_PROPERTY:io_pio,Fortran_MODULE_DIRECTORY>>
758 $<$<TARGET_EXISTS:io_netcdfpar>:$<TARGET_PROPERTY:io_netcdfpar,Fortran_MODULE_DIRECTORY>>
759 $<$<TARGET_EXISTS:io_pnetcdf>:$<TARGET_PROPERTY:io_pnetcdf,Fortran_MODULE_DIRECTORY>>
760 $<$<TARGET_EXISTS:io_phdf5>:$<TARGET_PROPERTY:io_phdf5,Fortran_MODULE_DIRECTORY>>
761 $<$<TARGET_EXISTS:g2lib>:$<TARGET_PROPERTY:g2lib,Fortran_MODULE_DIRECTORY>>
762 $<$<TARGET_EXISTS:bacio-1.3>:$<TARGET_PROPERTY:bacio-1.3,Fortran_MODULE_DIRECTORY>>
766 ${PROJECT_SOURCE_DIR}/dyn_em
769 ${PROJECT_SOURCE_DIR}/external/esmf_time_f90
770 ${PROJECT_SOURCE_DIR}/external/io_grib_share
771 ${PROJECT_SOURCE_DIR}/external/io_netcdf
772 ${PROJECT_SOURCE_DIR}/external/io_int
774 # Found Packages not handled through :: imported target
775 ${netCDF_INCLUDE_DIRS}
776 ${netCDF-Fortran_INCLUDE_DIRS}
777 ${pnetCDF_INCLUDE_DIRS}
780 # Add directly to core
781 add_subdirectory( phys )
782 add_subdirectory( share )
783 add_subdirectory( frame )
784 add_subdirectory( inc )
787 add_subdirectory( chem )
790 if ( ${ENABLE_HYDRO} )
791 add_subdirectory( hydro )
794 add_subdirectory( dyn_em )
797 add_subdirectory( main )
799 ################################################################################
800 # Add subdirectory with case info
801 ################################################################################
802 if ( ${CURRENT_WRF_CORE_IDX} GREATER_EQUAL ${START_DA_IDX} )
803 message( STATUS "DA or PLUS build, WRF_CASE selection ignored" )
805 add_subdirectory( test/${WRF_CASE_FOLDER} )
809 set_target_properties(
812 # Just dump everything in here
813 Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/modules/
815 EXPORT_PROPERTIES Fortran_MODULE_DIRECTORY
818 # Because of the way netCDF provides its info and the way cmake auto-gens RPATH, we need to help it along
819 target_link_directories(
822 ${netCDF_LIBRARY_DIR}
823 ${netCDF-Fortran_LIBRARY_DIR}
827 target_link_libraries( ${PROJECT_NAME}_Core
830 ${netCDF-Fortran_LIBRARIES}
832 $<$<BOOL:${USE_MPI}>:$<TARGET_NAME_IF_EXISTS:MPI::MPI_Fortran>>
833 $<$<BOOL:${USE_OPENMP}>:$<TARGET_NAME_IF_EXISTS:OpenMP::OpenMP_Fortran>>
834 # This will add in target dependencies if they exist
835 $<TARGET_NAME_IF_EXISTS:Jasper::Jasper>
836 $<TARGET_NAME_IF_EXISTS:HDF5::HDF5>
837 $<TARGET_NAME_IF_EXISTS:ZLIB::ZLIB>
838 $<TARGET_NAME_IF_EXISTS:CURL::libcurl>
839 $<TARGET_NAME_IF_EXISTS:RPC::RPC>
854 $<TARGET_NAME_IF_EXISTS:wrfhydro>
855 $<TARGET_NAME_IF_EXISTS:atm_ocn>
856 $<TARGET_NAME_IF_EXISTS:io_adios2>
857 $<TARGET_NAME_IF_EXISTS:io_esmf>
858 $<TARGET_NAME_IF_EXISTS:io_pio>
861 $<TARGET_NAME_IF_EXISTS:io_netcdfpar>
862 $<TARGET_NAME_IF_EXISTS:io_pnetcdf>
863 $<TARGET_NAME_IF_EXISTS:io_phdf5>
865 $<TARGET_NAME_IF_EXISTS:g2lib>
866 $<TARGET_NAME_IF_EXISTS:bacio-1.3>
868 $<TARGET_NAME_IF_EXISTS:RSL_LITE>
871 ################################################################################
873 ## Install and export
875 ################################################################################
876 set( CONFIG_INSTALL_DIRECTORY lib/cmake/${PROJECT_NAME} )
878 TARGETS ${PROJECT_NAME}_Core
879 EXPORT ${EXPORT_NAME}Targets
880 RUNTIME DESTINATION bin/
881 ARCHIVE DESTINATION lib/
882 LIBRARY DESTINATION lib/
885 # Install to namespace
887 EXPORT ${EXPORT_NAME}Targets
888 DESTINATION ${CONFIG_INSTALL_DIRECTORY}
889 FILE ${EXPORT_NAME}Targets.cmake
890 NAMESPACE ${EXPORT_NAME}::
893 configure_package_config_file(
894 ${PROJECT_SOURCE_DIR}/cmake/template/${EXPORT_NAME}Config.cmake.in
895 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}Config.cmake
896 INSTALL_DESTINATION ${CONFIG_INSTALL_DIRECTORY}
899 write_basic_package_version_file(
900 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}ConfigVersion.cmake
901 VERSION ${PROJECT_VERSION}
902 #!TODO Check if this is the type of versioning support we want to use
903 COMPATIBILITY SameMinorVersion
908 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}Config.cmake
909 ${CMAKE_BINARY_DIR}/${EXPORT_NAME}ConfigVersion.cmake
910 DESTINATION ${CONFIG_INSTALL_DIRECTORY}
913 # Install some helper files for anyone using this build as part of their code
916 # Trailing / is important
917 ${PROJECT_SOURCE_DIR}/cmake/modules/
925 ${PROJECT_SOURCE_DIR}/cmake/confcheck.cmake
926 ${PROJECT_SOURCE_DIR}/cmake/gitinfo.cmake
927 ${PROJECT_SOURCE_DIR}/cmake/printOption.cmake
928 ${PROJECT_SOURCE_DIR}/cmake/wrf_get_version.cmake