Merge branch 'release-v4.6.0'
[WPS.git] / CMakeLists.txt
blob6f47367955283d263fb3d956e44ebcc2edc71ce6
1 cmake_minimum_required( VERSION 3.20 )
2 cmake_policy( SET CMP0118 NEW )
4 enable_language( C )
5 enable_language( CXX )
6 enable_language( Fortran )
8 project( WPS )
9 set( EXPORT_NAME          ${PROJECT_NAME} )
10 set( INTERNAL_GRIB2_PATH  ${CMAKE_INSTALL_PREFIX}/grib2 )
12 if ( DEFINED CMAKE_TOOLCHAIN_FILE )
13   set( WPS_CONFIG ${CMAKE_TOOLCHAIN_FILE} )
14 endif()
18 list( APPEND CMAKE_MODULE_PATH 
19       ${PROJECT_SOURCE_DIR}/cmake/
20       ${PROJECT_SOURCE_DIR}/cmake/modules
21       )
23 # I'd love to be able to do something like this, but this would place a depedency
24 # on WRF which would be bad since who would expect the *WRF Preprocessing System*
25 # to have a strict dependency on WRF. Silly me
26 # if ( DEFINED WRF_DIR )
27 #   list( APPEND CMAKE_MODULE_PATH 
28 #       ${WRF_DIR}/share
29 #       )
30 # endif()
32 # Use link paths as rpaths 
33 set( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE )
34 set( CMAKE_Fortran_PREPROCESS          ON )
36 include( CMakePackageConfigHelpers )
37 # include( confcheck   )
38 # include( gitinfo     )
39 include( wrf_get_version )
40 include( wrf_case_setup )
43 # Grab version info
44 wrf_get_version( ${PROJECT_SOURCE_DIR}/README )
46 # Disable WRF-specifics entirely
47 set( USE_WRF      ON CACHE BOOL "USE_WRF"     )
49 ################################################################################
51 ## MPI & OpenMP
53 ################################################################################
55 # First do externals
56 if ( ${BUILD_EXTERNALS} )
57   add_subdirectory( external )
58   # If we got here everything built, we are safe to add find paths for libs
59   set( ZLIB_ROOT   ${INTERNAL_GRIB2_PATH} ) # This may get overridden by HDF5 if zlib is packaged with that
60   set( PNG_ROOT    ${INTERNAL_GRIB2_PATH} )
61   set( Jasper_ROOT ${INTERNAL_GRIB2_PATH} )
62 endif()
65 # Now find required libraries, which may have been affected by externals
66 if ( ${USE_WRF} )
67   # PATHS will be checked last
68   find_package( 
69                 WRF 
70                 COMPONENTS 
71                   WRF_Core io_netcdf io_grib1 io_int 
72                 # REQUIRED # this is technically required but we'll print our own msg
73                 PATHS
74                   ${PROJECT_SOURCE_DIR}/../WRF/install
75                   ${PROJECT_SOURCE_DIR}/../wrf/install
76                 QUIET
77                 NO_CMAKE_ENVIRONMENT_PATH # Do not use _DIR option
78                 )
79   if ( ${WRF_FOUND} )
80     message( STATUS "Found WRF : ${WRF_CONFIG} (found version \"${WRF_VERSION}\")" )
81   else()
82     message(
83             FATAL_ERROR
84             "Compiled WRF model not found. Please ensure a compiled WRF exists "
85             "and can be found by trying one of the following : \n"
86             "(1) provide -DWRF_ROOT=<path to install location> to CMake, if done "
87             "via the configure_new script use -- before option or see ./configure_new -h for more info\n"
88             "(2) set the environment variable WRF_ROOT to the path to the install location\n"
89             "(3) compile the WRF model code in ../WRF using the default install location\n"
90             "\nMore detail on search modes of CMake can be found at\n"
91             "https://cmake.org/cmake/help/latest/command/find_package.html#search-modes"
92             )
93   endif()
94 endif()
96 if ( ${USE_MPI} )
97   # Through ***MUCH*** debugging, if utilizing MPI_<LANG>_COMPILER
98   # https://cmake.org/cmake/help/latest/module/FindMPI.html#variables-for-locating-mpi
99   # the find logic makes a mess of things by utilizing <mpi> -show[me]
100   # Which may or may not get polluted by the environment
101   # It still technically finds MPI but the output is nonintuitive 
102   # saying things like hdf5 or pthread
103   find_package( MPI REQUIRED COMPONENTS Fortran C )
104   add_compile_definitions(
105                           USE_MPI=1
106                           DM_PARALLEL
107                           )
109   if ( DEFINED WRF_MPI_Fortran_FLAGS AND NOT "${WRF_MPI_Fortran_FLAGS}" STREQUAL "" )
110     add_compile_options(
111                         $<$<COMPILE_LANGUAGE:Fortran>,${WRF_MPI_Fortran_FLAGS}>
112                         )
113   endif()
115   if ( DEFINED WRF_MPI_C_FLAGS AND NOT "${WRF_MPI_C_FLAGS}" STREQUAL "" )
116     add_compile_options(
117                         $<$<COMPILE_LANGUAGE:C>,${WRF_MPI_C_FLAGS}>
118                         )
119   endif()
120 endif()
122 if ( ${USE_OPENMP} )
123   find_package( OpenMP REQUIRED COMPONENTS Fortran C )
124   add_compile_definitions( USE_OPENMP=1 SM_PARALLEL )
125 endif()
128 # Find externals now -- this is a little different than normal since we want WRF to 
129 # take precedence if it is present on which libraries to use to avoid library splicing
130 # rather than finding our external thirdparty libraries first
131 find_package( ZLIB   REQUIRED )
132 find_package( PNG    REQUIRED )
133 find_package( Jasper 1.900.1...1.900.29 REQUIRED )
135 # Because WRF might use a different version of zlib, check to see if we are using a different one
136 # when externals (really internals) are used
137 if ( ${BUILD_EXTERNALS} AND "${WRF_FOUND}" )
138   if ( NOT ( ${ZLIB_INCLUDE_DIRS} STREQUAL ${INTERNAL_GRIB2_PATH}/include ) )
139     message( STATUS "Note: Using WRF-specified zlib instead of ${INTERNAL_GRIB2_PATH}" )
140   endif()
141 endif()
143 # Add config definitions
144 message( STATUS "Adding configuration specific definitions : ${WPS_DEFINITIONS}" )
146 string( REPLACE " " ";" WPS_DEFINITIONS_LIST ${WPS_DEFINITIONS} )
148 # Make a copy, filter for anything not -D
149 set( WPS_UNDEFINITIONS_LIST ${WPS_DEFINITIONS_LIST} )
150 list( FILTER WPS_UNDEFINITIONS_LIST EXCLUDE REGEX "^-D(.*)" )
152 # Add this to the cpp processing
153 list( APPEND CMAKE_C_PREPROCESSOR_FLAGS ${WPS_UNDEFINITIONS_LIST} -P -nostdinc -traditional )
155 # Filter for anything that is -D
156 list( FILTER WPS_DEFINITIONS_LIST INCLUDE REGEX "^-D(.*)" )
158 # In CMake 2.26 this will not be necessary
159 list( TRANSFORM WPS_DEFINITIONS_LIST REPLACE "^-D(.*)" "\\1" )
161 add_compile_definitions( 
162                         ${WPS_DEFINITIONS_LIST}
163                         ${WPS_UNDEFINITIONS_LIST}
164                         $<$<COMPILE_LANGUAGE:Fortran>:USE_JPEG2000>
165                         $<$<COMPILE_LANGUAGE:Fortran>:USE_PNG>
166                         )
167 # Whole project flags
168 add_compile_options(
169                     $<$<COMPILE_LANG_AND_ID:Fortran,GNU>:-fallow-argument-mismatch>
170                     )
173 # Always build whatever we can
174 add_subdirectory( ungrib )
176 if ( DEFINED WRF_DIR )
177   # WRF Specific things
178   add_subdirectory( metgrid )
179   add_subdirectory( geogrid )
180 endif()
182 add_subdirectory( util )
185 ################################################################################
187 ## Install and export
189 ################################################################################
191 if ( "${WRF_FOUND}" )
193   wrf_setup_targets(
194                     TARGETS
195                       geogrid
196                       metgrid
197                     DEST_PATH       ${CMAKE_INSTALL_PREFIX}/bin
198                     )
199 endif()
201 wrf_setup_targets(
202                   TARGETS
203                     ungrib
204                   DEST_PATH       ${CMAKE_INSTALL_PREFIX}/bin
205                   )
208 wrf_setup_files( 
209                 FILES
210                   ${PROJECT_SOURCE_DIR}/link_grib.csh
211                 DEST_PATH
212                   ${CMAKE_INSTALL_PREFIX}/bin
213                 USE_SYMLINKS
214                 )
217 # Install to namespace
218 install(
219         EXPORT      ${EXPORT_NAME}Targets
220         DESTINATION lib/cmake/
221         FILE        ${EXPORT_NAME}Targets.cmake
222         NAMESPACE   ${EXPORT_NAME}::
223         )
225 configure_package_config_file(
226                               ${PROJECT_SOURCE_DIR}/cmake/template/${EXPORT_NAME}Config.cmake.in
227                               ${CMAKE_BINARY_DIR}/${EXPORT_NAME}Config.cmake
228                               INSTALL_DESTINATION lib/cmake
229                               )
231 write_basic_package_version_file(
232                                   ${CMAKE_BINARY_DIR}/${EXPORT_NAME}ConfigVersion.cmake
233                                   VERSION ${PROJECT_VERSION}
234                                   #!TODO Check if this is the type of versioning support we want to use
235                                   COMPATIBILITY SameMinorVersion
236                                   )
238 install(
239         FILES
240           ${CMAKE_BINARY_DIR}/${EXPORT_NAME}Config.cmake
241           ${CMAKE_BINARY_DIR}/${EXPORT_NAME}ConfigVersion.cmake
242         DESTINATION lib/cmake
243         )
245 # Install some helper files for anyone using this build as part of their code
246 install(
247         DIRECTORY
248           # Trailing / is important
249           ${PROJECT_SOURCE_DIR}/cmake/modules/
250         COMPONENT       helpers
251         DESTINATION     share
252         FILES_MATCHING  
253           PATTERN       "*.cmake"
254         )