Skip to content

Commit 964a445

Browse files
aidanheerdegenanton-seaicemicaeljtoliveira
authored
Add cmake build for access3 models (#6)
* Add cmake build based on https://github.com/cOSIMA/access-om3 There are two variations, the default is to build the cice standalone executable, the alternative is to build a library for access3 models (with https://github.com/ACCESS-NRI/access3-share as a dependency). There is also a cice_driver option available for future extension using other driver/coupling methods. Co-authored-by: Anton Steketee <[email protected]> Co-authored-by: Micael Oliveira <[email protected]>
1 parent 4fbbae0 commit 964a445

5 files changed

Lines changed: 960 additions & 0 deletions

File tree

Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
# Copyright ACCESS-NRI and contributors. See the top-level LICENSE file for details.
2+
3+
cmake_minimum_required(VERSION 3.18)
4+
5+
#[==============================================================================[
6+
# Basic project definition #
7+
#]==============================================================================]
8+
9+
project(CICE
10+
DESCRIPTION "CICE Sea Ice Model"
11+
HOMEPAGE_URL https://github.com/ciCE-Consortium/cice
12+
LANGUAGES C Fortran)
13+
14+
#[==============================================================================[
15+
# Options #
16+
#]==============================================================================]
17+
18+
message(STATUS "Build options")
19+
20+
option(CICE_IO "CICE IO Method" OFF)
21+
if (NOT CICE_IO)
22+
set(CICE_IO "Binary") #set a default
23+
endif()
24+
if(NOT CICE_IO MATCHES "^(NetCDF|PIO|Binary)$")
25+
message(FATAL_ERROR " CICE_IO ${CICE_IO} not valid, choose NetCDF|PIO|Binary")
26+
else()
27+
message(STATUS " - CICE_IO ${CICE_IO}")
28+
endif()
29+
30+
option(CICE_ACCESS3 "Use ACCESS3 dependencies and install ACCESS3 libraries" OFF)
31+
option(CICE_OPENMP "Enable OpenMP threading" OFF)
32+
message(STATUS " - CICE_ACCESS3 ${CICE_ACCESS3}")
33+
message(STATUS " - CICE_OPENMP ${CICE_OPENMP}")
34+
35+
#placeholder CICE_DRIVER option to allow for a nuopc/access driver in the future
36+
option(CICE_DRIVER "CICE driver code to use" OFF)
37+
if(NOT CICE_DRIVER)
38+
if(CICE_ACCESS3)
39+
set(CICE_DRIVER "nuopc/cmeps")
40+
else()
41+
set(CICE_DRIVER "standalone/cice")
42+
endif()
43+
endif()
44+
message(STATUS " - CICE_DRIVER ${CICE_DRIVER}")
45+
46+
#[==============================================================================[
47+
# Project configuration #
48+
#]==============================================================================]
49+
50+
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
51+
include(CMakePackageConfigHelpers)
52+
include(GNUInstallDirs)
53+
include(FortranLib)
54+
55+
# Common compiler flags and definitions
56+
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
57+
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fbacktrace -fconvert=big-endian -ffree-line-length-none -ffixed-line-length-none")
58+
if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL 10)
59+
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch")
60+
endif()
61+
set(CMAKE_Fortran_FLAGS_RELEASE "-O")
62+
set(CMAKE_Fortran_FLAGS_DEBUG "-g -Wall -Og -ffpe-trap=zero,overflow -fcheck=bounds")
63+
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
64+
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model precise")
65+
set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -debug minimal")
66+
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created")
67+
else()
68+
message(WARNING "Fortran compiler with ID ${CMAKE_Fortran_COMPILER_ID} will be used with CMake default options")
69+
endif()
70+
71+
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
72+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
73+
set(CMAKE_C_FLAGS_RELEASE "-O")
74+
set(CMAKE_C_FLAGS_DEBUG "-g -Wall -Og -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds")
75+
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
76+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -traceback -qno-opt-dynamic-align -fp-model precise -std=gnu99")
77+
set(CMAKE_C_FLAGS_RELEASE "-O2 -debug minimal")
78+
set(CMAKE_C_FLAGS_DEBUG "-O0 -g")
79+
else()
80+
message(WARNING "C compiler with ID ${CMAKE_C_COMPILER_ID} will be used with CMake default options")
81+
endif()
82+
83+
if (CICE_ACCESS3)
84+
add_compile_definitions(
85+
CESMCOUPLED
86+
)
87+
endif()
88+
89+
## Fortran modules path; currently this is simply set to be the include dir
90+
set(CMAKE_INSTALL_MODULEDIR ${CMAKE_INSTALL_INCLUDEDIR}
91+
CACHE STRING
92+
"Fortran module installation path (Not a cmake native variable)"
93+
)
94+
95+
#[==============================================================================[
96+
# External packages #
97+
#]==============================================================================]
98+
99+
if(CICE_ACCESS3)
100+
find_package(Access3Share REQUIRED cdeps timing share nuopc_cap_share)
101+
if(NOT TARGET ESMF::ESMF) #Access3Share probably already has ESMF with PUBLIC interface
102+
message(FATAL_ERROR "ESMF interface missing from Access3Share package")
103+
endif()
104+
else()
105+
find_package(MPI REQUIRED)
106+
endif()
107+
108+
if(CICE_OPENMP)
109+
find_package(OpenMP REQUIRED COMPONENTS Fortran)
110+
endif()
111+
112+
if(CICE_IO MATCHES "^(NetCDF|PIO)$" AND NOT TARGET NetCDF::NetCDF_Fortran)
113+
# Code has not been tested with versions older than 4.7.3, but probably still works fine
114+
find_package(NetCDF 4.7.3 REQUIRED Fortran)
115+
endif()
116+
if(CICE_IO MATCHES "PIO" AND NOT TARGET PIO::PIO_Fortran)
117+
find_package(PIO 2.5.3 REQUIRED COMPONENTS Fortran)
118+
# Code has not been tested with versions older than 2.5.3, but probably still works fine
119+
endif()
120+
121+
#[==============================================================================[
122+
# Main definitions #
123+
#]==============================================================================]
124+
125+
### Targets
126+
127+
## CICE library
128+
129+
set(CICE_CORE "${CMAKE_SOURCE_DIR}/../../../cicecore")
130+
set(ICEPACK "${CMAKE_SOURCE_DIR}/../../../icepack")
131+
132+
add_fortran_library(cicelib mod STATIC)
133+
134+
if(CICE_IO MATCHES "^(NetCDF|PIO)$")
135+
target_compile_definitions(cicelib PRIVATE FORTRANUNDERSCORE ncdf)
136+
target_compile_definitions(cicelib PRIVATE USE_NETCDF)
137+
endif()
138+
if(CICE_ACCESS3)
139+
target_link_libraries(cicelib
140+
PUBLIC ESMF::ESMF
141+
PRIVATE Access3::nuopc_cap_share Access3::share Access3::timing Access3::cdeps-common
142+
)
143+
endif()
144+
if(CICE_IO MATCHES "^(NetCDF|PIO)$")
145+
target_link_libraries(cicelib PRIVATE NetCDF::NetCDF_Fortran)
146+
if(CICE_IO MATCHES "PIO")
147+
target_link_libraries(cicelib PRIVATE PIO::PIO_Fortran)
148+
endif()
149+
endif()
150+
151+
if(CICE_OPENMP)
152+
target_link_libraries(cicelib PUBLIC OpenMP::OpenMP_Fortran)
153+
endif()
154+
155+
156+
157+
target_sources(cicelib PRIVATE
158+
# Shared List:
159+
${CICE_CORE}/shared/ice_arrays_column.F90
160+
${CICE_CORE}/shared/ice_calendar.F90
161+
${CICE_CORE}/shared/ice_constants.F90
162+
${CICE_CORE}/shared/ice_domain_size.F90
163+
${CICE_CORE}/shared/ice_fileunits.F90
164+
${CICE_CORE}/shared/ice_init_column.F90
165+
${CICE_CORE}/shared/ice_kinds_mod.F90
166+
${CICE_CORE}/shared/ice_restart_column.F90
167+
${CICE_CORE}/shared/ice_restart_shared.F90
168+
${CICE_CORE}/shared/ice_spacecurve.F90
169+
${CICE_CORE}/shared/ice_distribution.F90
170+
171+
# Analysis
172+
${CICE_CORE}/cicedyn/analysis/ice_diagnostics.F90
173+
${CICE_CORE}/cicedyn/analysis/ice_diagnostics_bgc.F90
174+
${CICE_CORE}/cicedyn/analysis/ice_history.F90
175+
${CICE_CORE}/cicedyn/analysis/ice_history_bgc.F90
176+
${CICE_CORE}/cicedyn/analysis/ice_history_drag.F90
177+
${CICE_CORE}/cicedyn/analysis/ice_history_fsd.F90
178+
${CICE_CORE}/cicedyn/analysis/ice_history_mechred.F90
179+
${CICE_CORE}/cicedyn/analysis/ice_history_pond.F90
180+
${CICE_CORE}/cicedyn/analysis/ice_history_shared.F90
181+
${CICE_CORE}/cicedyn/analysis/ice_history_snow.F90
182+
183+
# Dynamics
184+
${CICE_CORE}/cicedyn/dynamics/ice_dyn_core1d.F90
185+
${CICE_CORE}/cicedyn/dynamics/ice_dyn_eap.F90
186+
${CICE_CORE}/cicedyn/dynamics/ice_dyn_evp.F90
187+
${CICE_CORE}/cicedyn/dynamics/ice_dyn_evp1d.F90
188+
${CICE_CORE}/cicedyn/dynamics/ice_dyn_shared.F90
189+
${CICE_CORE}/cicedyn/dynamics/ice_dyn_vp.F90
190+
${CICE_CORE}/cicedyn/dynamics/ice_transport_driver.F90
191+
${CICE_CORE}/cicedyn/dynamics/ice_transport_remap.F90
192+
193+
# General
194+
${CICE_CORE}/cicedyn/general/ice_init.F90
195+
${CICE_CORE}/cicedyn/general/ice_flux.F90
196+
${CICE_CORE}/cicedyn/general/ice_flux_bgc.F90
197+
${CICE_CORE}/cicedyn/general/ice_forcing.F90
198+
${CICE_CORE}/cicedyn/general/ice_forcing_bgc.F90
199+
${CICE_CORE}/cicedyn/general/ice_state.F90
200+
${CICE_CORE}/cicedyn/general/ice_step_mod.F90
201+
202+
# Infrastructure
203+
${CICE_CORE}/cicedyn/infrastructure/ice_blocks.F90
204+
${CICE_CORE}/cicedyn/infrastructure/ice_grid.F90
205+
${CICE_CORE}/cicedyn/infrastructure/ice_memusage.F90
206+
${CICE_CORE}/cicedyn/infrastructure/ice_memusage_gptl.c
207+
${CICE_CORE}/cicedyn/infrastructure/ice_read_write.F90
208+
${CICE_CORE}/cicedyn/infrastructure/ice_restart_driver.F90
209+
${CICE_CORE}/cicedyn/infrastructure/ice_restoring.F90
210+
${CICE_CORE}/cicedyn/infrastructure/ice_domain.F90
211+
212+
# Icepack
213+
${ICEPACK}/columnphysics/icepack_aerosol.F90
214+
${ICEPACK}/columnphysics/icepack_age.F90
215+
${ICEPACK}/columnphysics/icepack_algae.F90
216+
${ICEPACK}/columnphysics/icepack_atmo.F90
217+
${ICEPACK}/columnphysics/icepack_brine.F90
218+
${ICEPACK}/columnphysics/icepack_firstyear.F90
219+
${ICEPACK}/columnphysics/icepack_flux.F90
220+
${ICEPACK}/columnphysics/icepack_fsd.F90
221+
${ICEPACK}/columnphysics/icepack_intfc.F90
222+
${ICEPACK}/columnphysics/icepack_isotope.F90
223+
${ICEPACK}/columnphysics/icepack_itd.F90
224+
${ICEPACK}/columnphysics/icepack_kinds.F90
225+
${ICEPACK}/columnphysics/icepack_mechred.F90
226+
${ICEPACK}/columnphysics/icepack_meltpond_lvl.F90
227+
${ICEPACK}/columnphysics/icepack_meltpond_topo.F90
228+
${ICEPACK}/columnphysics/icepack_mushy_physics.F90
229+
${ICEPACK}/columnphysics/icepack_ocean.F90
230+
${ICEPACK}/columnphysics/icepack_orbital.F90
231+
${ICEPACK}/columnphysics/icepack_parameters.F90
232+
${ICEPACK}/columnphysics/icepack_shortwave_data.F90
233+
${ICEPACK}/columnphysics/icepack_shortwave.F90
234+
${ICEPACK}/columnphysics/icepack_snow.F90
235+
${ICEPACK}/columnphysics/icepack_therm_bl99.F90
236+
${ICEPACK}/columnphysics/icepack_therm_itd.F90
237+
${ICEPACK}/columnphysics/icepack_therm_mushy.F90
238+
${ICEPACK}/columnphysics/icepack_therm_shared.F90
239+
${ICEPACK}/columnphysics/icepack_therm_vertical.F90
240+
${ICEPACK}/columnphysics/icepack_tracers.F90
241+
${ICEPACK}/columnphysics/icepack_warnings.F90
242+
${ICEPACK}/columnphysics/icepack_wavefracspec.F90
243+
${ICEPACK}/columnphysics/icepack_zbgc.F90
244+
${ICEPACK}/columnphysics/icepack_zbgc_shared.F90
245+
246+
# Shared C
247+
${CICE_CORE}/cicedyn/infrastructure/ice_shr_reprosum86.c
248+
249+
# MPI
250+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_boundary.F90
251+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_broadcast.F90
252+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_communicate.F90
253+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_exit.F90
254+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_gather_scatter.F90
255+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_global_reductions.F90
256+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_reprosum.F90
257+
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_timers.F90
258+
)
259+
260+
if(CICE_DRIVER MATCHES "nuopc/cmeps")
261+
target_sources(cicelib PRIVATE
262+
# NUOPC CMEPS driver
263+
${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_FinalMod.F90
264+
${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_InitMod.F90
265+
${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_RunMod.F90
266+
${CICE_CORE}/drivers/${CICE_DRIVER}/cice_wrapper_mod.F90
267+
${CICE_CORE}/drivers/${CICE_DRIVER}/ice_comp_nuopc.F90
268+
${CICE_CORE}/drivers/${CICE_DRIVER}/ice_import_export.F90
269+
${CICE_CORE}/drivers/${CICE_DRIVER}/ice_mesh_mod.F90
270+
${CICE_CORE}/drivers/${CICE_DRIVER}/ice_prescribed_mod.F90
271+
${CICE_CORE}/drivers/${CICE_DRIVER}/ice_scam.F90
272+
${CICE_CORE}/drivers/${CICE_DRIVER}/ice_shr_methods.F90
273+
)
274+
elseif(CICE_DRIVER MATCHES "standalone/cice")
275+
target_sources(cicelib PRIVATE
276+
# CICE standalone
277+
${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_FinalMod.F90
278+
${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_InitMod.F90
279+
${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_RunMod.F90
280+
)
281+
else()
282+
message(FATAL_ERROR "CICE_DRIVER: ${CICE_DRIVER} is currently not supported by the CMake build system")
283+
endif()
284+
285+
# Select IO source files based on CICE_IO
286+
if(CICE_IO MATCHES "NetCDF")
287+
target_sources(cicelib PRIVATE
288+
${CICE_CORE}/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90
289+
${CICE_CORE}/cicedyn/infrastructure/io/io_netcdf/ice_restart.F90
290+
)
291+
elseif(CICE_IO MATCHES "PIO")
292+
target_sources(cicelib PRIVATE
293+
${CICE_CORE}/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90
294+
${CICE_CORE}/cicedyn/infrastructure/io/io_pio2/ice_pio.F90
295+
${CICE_CORE}/cicedyn/infrastructure/io/io_pio2/ice_restart.F90
296+
)
297+
elseif(CICE_IO MATCHES "Binary")
298+
target_sources(cicelib PRIVATE
299+
${CICE_CORE}/cicedyn/infrastructure/io/io_binary/ice_history_write.F90
300+
${CICE_CORE}/cicedyn/infrastructure/io/io_binary/ice_restart.F90
301+
)
302+
endif()
303+
304+
#[==============================================================================[
305+
# Install or Export #
306+
#]==============================================================================]
307+
308+
if(CICE_ACCESS3)
309+
## Library
310+
set_target_properties(cicelib PROPERTIES
311+
OUTPUT_NAME access-cicelib
312+
EXPORT_NAME cicelib
313+
)
314+
install(TARGETS cicelib
315+
EXPORT CicelibTargets
316+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT AccessCICE_runtime NAMELINK_COMPONENT AccessCICE_Development
317+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT AccessCICE_Development
318+
)
319+
# Fortran module files are a special case, as currently there is no standard
320+
# way of handling them in CMake
321+
target_include_directories(cicelib PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_MODULEDIR}/cicelib>")
322+
get_target_property(cice_moddir cicelib Fortran_MODULE_DIRECTORY)
323+
install(FILES ${cice_moddir}/ice_comp_nuopc.mod
324+
DESTINATION ${CMAKE_INSTALL_MODULEDIR}/cicelib
325+
COMPONENT AccessCICECmeps_Development
326+
)
327+
install(EXPORT CicelibTargets
328+
FILE CicelibTargets.cmake
329+
NAMESPACE Access3::
330+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
331+
)
332+
333+
# Make sure the dependencies get exported too
334+
configure_package_config_file(
335+
CicelibConfig.cmake.in
336+
"${CMAKE_CURRENT_BINARY_DIR}/CicelibConfig.cmake"
337+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
338+
)
339+
340+
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CicelibConfig.cmake
341+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
342+
COMPONENT AccessCICE_Development
343+
)
344+
345+
if(CICE_IO MATCHES "NetCDF")
346+
install(FILES ${CMAKE_SOURCE_DIR}/FindNetCDF.cmake
347+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
348+
COMPONENT IO_NetCDF
349+
)
350+
elseif(CICE_IO MATCHES "PIO")
351+
install(FILES ${CMAKE_SOURCE_DIR}/FindNetCDF.cmake ${CMAKE_SOURCE_DIR}/FindPIO.cmake
352+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
353+
COMPONENT IO_PIO
354+
)
355+
endif()
356+
357+
else()
358+
set_target_properties(cicelib PROPERTIES
359+
OUTPUT_NAME cicelib-standalone
360+
EXPORT_NAME cicelib
361+
)
362+
add_executable(CICE ${CICE_CORE}/drivers/standalone/cice/CICE.F90)
363+
target_link_libraries(CICE PRIVATE cicelib MPI::MPI_Fortran)
364+
365+
set_target_properties(CICE PROPERTIES
366+
LINKER_LANGUAGE Fortran
367+
OUTPUT_NAME cice
368+
)
369+
install(TARGETS CICE
370+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
371+
COMPONENT IO_${CICE_IO}
372+
)
373+
endif()

0 commit comments

Comments
 (0)