Skip to content

Commit f5e377a

Browse files
committed
Merge branch 'cmakeBuild' into develop (PR #230)
This merge introduces a CMake build capability to complement the CMake build in WRF. Building the WPS with CMake requires that WRF was also compiled with CMake (provided the geogrid and metgrid programs are to be built). The WPS CMake build follows the same procedure as the WRF build procedure, using the following: ./configure_new ./compile_new The prompts will look similar and present the user with available options specific to their system. * cmakeBuild: (44 commits) Give detailed error info when WRF not found, and fail if it was requested Be more explicit with external source code to be compiled Use abs paths Update WRF find logic Switch default to no Allow for building just ungrib Set fortran fixed for these targets Reorder library linking so symbols are properly resolved Add snippet about cmake compilation Install main bins with .exe links similar to WRF cmake Better usage of build externals with updates to find jasper and note zlib Move compiled fortran modules to a subdir in install Sync with WRF developments Sync with WRF updates for better option outputs Set cpp flags to defaults Better control over finding WRF Use WRF better Jasper module for control of versioning Sync netCDF modules with WRF Sync with WRF Splitting defs in case we ever need to handle them differently ...
2 parents 085d6f8 + d1979bc commit f5e377a

29 files changed

+2464
-68
lines changed

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ ungrib.exe
33
metgrid.exe
44
configure.wps
55
configure.wps.backup
6-
6+
wps_config.cmake
7+
run/
8+
*.log
9+
_build/
710
# Compiled GRIB2 libraries if --build-grib2-libs option is given to configure script
811
grib2
12+
*.nc
13+
GRIBFILE.*
14+
*.o
15+
FILE:*

CMakeLists.txt

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
cmake_minimum_required( VERSION 3.20 )
2+
cmake_policy( SET CMP0118 NEW )
3+
4+
enable_language( C )
5+
enable_language( CXX )
6+
enable_language( Fortran )
7+
8+
project( WPS )
9+
set( EXPORT_NAME ${PROJECT_NAME} )
10+
set( INTERNAL_GRIB2_PATH ${CMAKE_INSTALL_PREFIX}/grib2 )
11+
12+
if ( DEFINED CMAKE_TOOLCHAIN_FILE )
13+
set( WPS_CONFIG ${CMAKE_TOOLCHAIN_FILE} )
14+
endif()
15+
16+
17+
18+
list( APPEND CMAKE_MODULE_PATH
19+
${PROJECT_SOURCE_DIR}/cmake/
20+
${PROJECT_SOURCE_DIR}/cmake/modules
21+
)
22+
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()
31+
32+
# Use link paths as rpaths
33+
set( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE )
34+
set( CMAKE_Fortran_PREPROCESS ON )
35+
36+
include( CMakePackageConfigHelpers )
37+
# include( confcheck )
38+
# include( gitinfo )
39+
include( wrf_get_version )
40+
include( wrf_case_setup )
41+
42+
43+
# Grab version info
44+
wrf_get_version( ${PROJECT_SOURCE_DIR}/README )
45+
46+
# Disable WRF-specifics entirely
47+
set( USE_WRF ON CACHE BOOL "USE_WRF" )
48+
49+
################################################################################
50+
##
51+
## MPI & OpenMP
52+
##
53+
################################################################################
54+
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()
63+
64+
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()
95+
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+
)
108+
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()
114+
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()
121+
122+
if ( ${USE_OPENMP} )
123+
find_package( OpenMP REQUIRED COMPONENTS Fortran C )
124+
add_compile_definitions( USE_OPENMP=1 SM_PARALLEL )
125+
endif()
126+
127+
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 )
134+
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()
142+
143+
# Add config definitions
144+
message( STATUS "Adding configuration specific definitions : ${WPS_DEFINITIONS}" )
145+
146+
string( REPLACE " " ";" WPS_DEFINITIONS_LIST ${WPS_DEFINITIONS} )
147+
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(.*)" )
151+
152+
# Add this to the cpp processing
153+
list( APPEND CMAKE_C_PREPROCESSOR_FLAGS ${WPS_UNDEFINITIONS_LIST} -P -nostdinc -traditional )
154+
155+
# Filter for anything that is -D
156+
list( FILTER WPS_DEFINITIONS_LIST INCLUDE REGEX "^-D(.*)" )
157+
158+
# In CMake 2.26 this will not be necessary
159+
list( TRANSFORM WPS_DEFINITIONS_LIST REPLACE "^-D(.*)" "\\1" )
160+
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+
)
171+
172+
173+
# Always build whatever we can
174+
add_subdirectory( ungrib )
175+
176+
if ( DEFINED WRF_DIR )
177+
# WRF Specific things
178+
add_subdirectory( metgrid )
179+
add_subdirectory( geogrid )
180+
endif()
181+
182+
add_subdirectory( util )
183+
184+
185+
################################################################################
186+
##
187+
## Install and export
188+
##
189+
################################################################################
190+
191+
if ( "${WRF_FOUND}" )
192+
193+
wrf_setup_targets(
194+
TARGETS
195+
geogrid
196+
metgrid
197+
DEST_PATH ${CMAKE_INSTALL_PREFIX}/bin
198+
)
199+
endif()
200+
201+
wrf_setup_targets(
202+
TARGETS
203+
ungrib
204+
DEST_PATH ${CMAKE_INSTALL_PREFIX}/bin
205+
)
206+
207+
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+
)
215+
216+
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+
)
224+
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+
)
230+
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+
)
237+
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+
)
244+
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+
)

README

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ in configure.wps and then compiled using
9595
./compile plotfmt
9696
./compile plotgrids
9797

98+
Building WPS with CMake
99+
100+
The WPS cmake build follows the same procedure as the WRF
101+
build procedure, using the following:
102+
./configure_new
103+
./compile_new
104+
105+
The prompts will look similar and present the user with
106+
available options specific to their system.
98107

99108
Running WPS (for serially compiled code)
100109

0 commit comments

Comments
 (0)