Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
40b2e11
Add cmake build copied from COSIMA/access-om3
aidanheerdegen Nov 13, 2024
296f623
Change source paths to remove leading CICE directory
aidanheerdegen Nov 13, 2024
677113b
Add Fortran library cmake function
aidanheerdegen Nov 13, 2024
432d562
Remove source code patching
aidanheerdegen Nov 13, 2024
d48a342
hacks to fix paths & add_fortran_library
anton-seaice Nov 13, 2024
07b4ea2
messing around with building libraries
anton-seaice Nov 18, 2024
b1b3f82
rm OM3 names
anton-seaice Dec 6, 2024
f258a4c
only find PIO when needed
anton-seaice Dec 6, 2024
f6d3e81
only find deps when needed
anton-seaice Dec 6, 2024
6448d75
rm more deps from standalone build
anton-seaice Dec 6, 2024
1b75181
building access cice library
anton-seaice Jan 13, 2025
6a78480
some tweaks
anton-seaice Jan 13, 2025
3bb7b84
tweaks
anton-seaice Jan 14, 2025
93bafd5
Fix dependencies
anton-seaice Jan 14, 2025
e99c87d
tweak names
anton-seaice Jan 17, 2025
06b34dd
move cmake to configuration/scripts
anton-seaice Jan 22, 2025
26ce3b0
seperate runtime and Development components
anton-seaice Jan 23, 2025
73f1720
fix names and IO dependency finding
anton-seaice Jan 23, 2025
459e3c8
Merge branch 'main' into 5-port_cmake_build
anton-seaice Jan 29, 2025
1329116
possible better deps handling and allow CICE_DRIVER to be specified
anton-seaice Feb 5, 2025
ea03147
Merge remote-tracking branch 'origin/5-port_cmake_build' into 5-port_…
anton-seaice Feb 5, 2025
3453973
fp-model precise and rm duplicate line
anton-seaice Mar 13, 2025
63ce71b
openmp
anton-seaice Mar 14, 2025
1ab3709
explicitly link MPI in exe
anton-seaice Mar 18, 2025
49d3978
license
anton-seaice Mar 18, 2025
73128cb
license
anton-seaice Mar 18, 2025
87a1ec0
updated FindESMF.cmake
anton-seaice Mar 19, 2025
c43a89f
use deps from access3-share where possible
anton-seaice Mar 20, 2025
421a90c
review comments
anton-seaice Mar 26, 2025
3964965
Update configuration/scripts/cmake/CMakeLists.txt
anton-seaice Mar 27, 2025
774c9c7
note about code versions
anton-seaice Mar 27, 2025
b6b4a17
Update configuration/scripts/cmake/CMakeLists.txt
anton-seaice Mar 27, 2025
4c89929
remove CICE_CESMCOUPLED option
anton-seaice Mar 27, 2025
5eaa7c2
rm comments and set versions consistently
anton-seaice Mar 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
342 changes: 342 additions & 0 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
cmake_minimum_required(VERSION 3.18)

#[==============================================================================[
# Basic project definition #
#]==============================================================================]

project(CICE
DESCRIPTION "CICE Sea Ice Model"
HOMEPAGE_URL https://github.com/ciCE-Consortium/cice
LANGUAGES C Fortran)

#[==============================================================================[
# Options #
#]==============================================================================]

# Build options
option(ACCESS3_LIB_INSTALL "Instal ACCESS3 libraries" OFF)
option(CICE_IO "CICE IO Method" "Binary")
option(CESMCOUPLED "CESMCOUPLED Build CPP" OFF)
# openmp ?

message(STATUS "Build options")
message(STATUS " - ACCESS3_LIB_INSTALL ${ACCESS3_LIB_INSTALL}")
message(STATUS " - CICE_IO ${CICE_IO}")
message(STATUS " - CESMCOUPLED ${CESMCOUPLED}")

#[==============================================================================[
# Project configuration #
#]==============================================================================]

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
include(FortranLib)

# Common compiler flags and definitions
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fbacktrace -fconvert=big-endian -ffree-line-length-none -ffixed-line-length-none")
if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL 10)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch")
endif()
set(CMAKE_Fortran_FLAGS_RELEASE "-O")
set(CMAKE_Fortran_FLAGS_DEBUG "-g -Wall -Og -ffpe-trap=zero,overflow -fcheck=bounds")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source")
set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -debug minimal")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created")
else()
message(WARNING "Fortran compiler with ID ${CMAKE_Fortran_COMPILER_ID} will be used with CMake default options")
endif()

if(CMAKE_C_COMPILER_ID MATCHES "GNU")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
set(CMAKE_C_FLAGS_RELEASE "-O")
set(CMAKE_C_FLAGS_DEBUG "-g -Wall -Og -fbacktrace -ffpe-trap=invalid,zero,overflow -fcheck=bounds")
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -traceback -qno-opt-dynamic-align -fp-model precise -std=gnu99")
set(CMAKE_C_FLAGS_RELEASE "-O2 -debug minimal")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g")
else()
message(WARNING "C compiler with ID ${CMAKE_C_COMPILER_ID} will be used with CMake default options")
endif()

if (CESMCOUPLED)
add_compile_definitions(
CESMCOUPLED
)
endif()

## Fortran modules path; currently this is simply set to be the include dir
set(CMAKE_INSTALL_MODULEDIR ${CMAKE_INSTALL_INCLUDEDIR}
CACHE STRING
"Fortran module installation path (Not a cmake native variable)"
)

#[==============================================================================[
# External packages #
#]==============================================================================]

if(ACCESS3_LIB_INSTALL)
find_package(Access3Share REQUIRED cdeps timing share nuopc_cap_share)
find_package(ESMF 8.3.0 MODULE REQUIRED)
else()
find_package(MPI REQUIRED)
endif()

if(CICE_IO MATCHES "^(NetCDF|PIO)$")
find_package(NetCDF 4.7.3 REQUIRED Fortran)
endif()
if(CICE_IO MATCHES "PIO")
find_package(PIO 2.5.3 REQUIRED COMPONENTS C Fortran)
endif()

#[==============================================================================[
# Main definitions #
#]==============================================================================]

### Targets

## CICE library
add_fortran_library(cicelib mod STATIC)

if(CICE_IO MATCHES "^(NetCDF|PIO)$")
# which is this not just an "add_compile_definitions?"
target_compile_definitions(cicelib PRIVATE FORTRANUNDERSCORE ncdf)
target_compile_definitions(cicelib PRIVATE USE_NETCDF)
endif()
if(ACCESS3_LIB_INSTALL)
target_link_libraries(cicelib
PUBLIC esmf
PRIVATE Access3Share::nuopc_cap_share Access3Share::share Access3Share::timing Access3Share::cdeps-common
)
endif()
if(CICE_IO MATCHES "^(NetCDF|PIO)$")
target_link_libraries(cicelib PRIVATE NetCDF::NetCDF_Fortran)
if(CICE_IO MATCHES "PIO")
target_link_libraries(cicelib PRIVATE PIO::PIO_Fortran)
endif()
endif()

if(OpenMP_Fortran_FOUND)
target_link_libraries(cicelib PUBLIC OpenMP::OpenMP_Fortran)
endif()

set(CICE_CORE "${CMAKE_SOURCE_DIR}/../cicecore")
set(ICEPACK "${CMAKE_SOURCE_DIR}/../icepack")

target_sources(cicelib PRIVATE
# Shared List:
${CICE_CORE}/shared/ice_arrays_column.F90
${CICE_CORE}/shared/ice_calendar.F90
${CICE_CORE}/shared/ice_constants.F90
${CICE_CORE}/shared/ice_domain_size.F90
${CICE_CORE}/shared/ice_fileunits.F90
${CICE_CORE}/shared/ice_init_column.F90
${CICE_CORE}/shared/ice_kinds_mod.F90
${CICE_CORE}/shared/ice_restart_column.F90
${CICE_CORE}/shared/ice_restart_shared.F90
${CICE_CORE}/shared/ice_spacecurve.F90
${CICE_CORE}/shared/ice_distribution.F90

# Analysis
${CICE_CORE}/cicedyn/analysis/ice_diagnostics.F90
${CICE_CORE}/cicedyn/analysis/ice_diagnostics_bgc.F90
${CICE_CORE}/cicedyn/analysis/ice_history.F90
${CICE_CORE}/cicedyn/analysis/ice_history_bgc.F90
${CICE_CORE}/cicedyn/analysis/ice_history_drag.F90
${CICE_CORE}/cicedyn/analysis/ice_history_fsd.F90
${CICE_CORE}/cicedyn/analysis/ice_history_mechred.F90
${CICE_CORE}/cicedyn/analysis/ice_history_pond.F90
${CICE_CORE}/cicedyn/analysis/ice_history_shared.F90
${CICE_CORE}/cicedyn/analysis/ice_history_snow.F90

# Dynamics
${CICE_CORE}/cicedyn/dynamics/ice_dyn_core1d.F90
${CICE_CORE}/cicedyn/dynamics/ice_dyn_eap.F90
${CICE_CORE}/cicedyn/dynamics/ice_dyn_evp.F90
${CICE_CORE}/cicedyn/dynamics/ice_dyn_evp1d.F90
${CICE_CORE}/cicedyn/dynamics/ice_dyn_shared.F90
${CICE_CORE}/cicedyn/dynamics/ice_dyn_vp.F90
${CICE_CORE}/cicedyn/dynamics/ice_transport_driver.F90
${CICE_CORE}/cicedyn/dynamics/ice_transport_remap.F90

# General
${CICE_CORE}/cicedyn/general/ice_init.F90
${CICE_CORE}/cicedyn/general/ice_flux.F90
${CICE_CORE}/cicedyn/general/ice_flux_bgc.F90
${CICE_CORE}/cicedyn/general/ice_forcing.F90
${CICE_CORE}/cicedyn/general/ice_forcing_bgc.F90
${CICE_CORE}/cicedyn/general/ice_state.F90
${CICE_CORE}/cicedyn/general/ice_step_mod.F90

# Infrastructure
${CICE_CORE}/cicedyn/infrastructure/ice_blocks.F90
${CICE_CORE}/cicedyn/infrastructure/ice_grid.F90
${CICE_CORE}/cicedyn/infrastructure/ice_memusage.F90
${CICE_CORE}/cicedyn/infrastructure/ice_memusage_gptl.c
${CICE_CORE}/cicedyn/infrastructure/ice_read_write.F90
${CICE_CORE}/cicedyn/infrastructure/ice_restart_driver.F90
${CICE_CORE}/cicedyn/infrastructure/ice_restoring.F90
${CICE_CORE}/cicedyn/infrastructure/ice_domain.F90

# Icepack
${ICEPACK}/columnphysics/icepack_aerosol.F90
${ICEPACK}/columnphysics/icepack_age.F90
${ICEPACK}/columnphysics/icepack_algae.F90
${ICEPACK}/columnphysics/icepack_atmo.F90
${ICEPACK}/columnphysics/icepack_brine.F90
${ICEPACK}/columnphysics/icepack_firstyear.F90
${ICEPACK}/columnphysics/icepack_flux.F90
${ICEPACK}/columnphysics/icepack_fsd.F90
${ICEPACK}/columnphysics/icepack_intfc.F90
${ICEPACK}/columnphysics/icepack_isotope.F90
${ICEPACK}/columnphysics/icepack_itd.F90
${ICEPACK}/columnphysics/icepack_kinds.F90
${ICEPACK}/columnphysics/icepack_mechred.F90
${ICEPACK}/columnphysics/icepack_meltpond_lvl.F90
${ICEPACK}/columnphysics/icepack_meltpond_topo.F90
${ICEPACK}/columnphysics/icepack_mushy_physics.F90
${ICEPACK}/columnphysics/icepack_ocean.F90
${ICEPACK}/columnphysics/icepack_orbital.F90
${ICEPACK}/columnphysics/icepack_parameters.F90
${ICEPACK}/columnphysics/icepack_shortwave_data.F90
${ICEPACK}/columnphysics/icepack_shortwave.F90
${ICEPACK}/columnphysics/icepack_snow.F90
${ICEPACK}/columnphysics/icepack_therm_bl99.F90
${ICEPACK}/columnphysics/icepack_therm_itd.F90
${ICEPACK}/columnphysics/icepack_therm_mushy.F90
${ICEPACK}/columnphysics/icepack_therm_shared.F90
${ICEPACK}/columnphysics/icepack_therm_vertical.F90
${ICEPACK}/columnphysics/icepack_tracers.F90
${ICEPACK}/columnphysics/icepack_warnings.F90
${ICEPACK}/columnphysics/icepack_wavefracspec.F90
${ICEPACK}/columnphysics/icepack_zbgc.F90
${ICEPACK}/columnphysics/icepack_zbgc_shared.F90

# Shared C
${CICE_CORE}/cicedyn/infrastructure/ice_shr_reprosum86.c

# MPI
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_boundary.F90
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_broadcast.F90
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_communicate.F90
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_exit.F90
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_gather_scatter.F90
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_global_reductions.F90
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_reprosum.F90
${CICE_CORE}/cicedyn/infrastructure/comm/mpi/ice_timers.F90
)

if(ACCESS3_LIB_INSTALL)
target_sources(cicelib PRIVATE
# NUOPC CMEPS driver
${CICE_CORE}/drivers/nuopc/cmeps/CICE_FinalMod.F90
${CICE_CORE}/drivers/nuopc/cmeps/CICE_InitMod.F90
${CICE_CORE}/drivers/nuopc/cmeps/CICE_RunMod.F90
${CICE_CORE}/drivers/nuopc/cmeps/cice_wrapper_mod.F90
${CICE_CORE}/drivers/nuopc/cmeps/ice_comp_nuopc.F90
${CICE_CORE}/drivers/nuopc/cmeps/ice_import_export.F90
${CICE_CORE}/drivers/nuopc/cmeps/ice_mesh_mod.F90
${CICE_CORE}/drivers/nuopc/cmeps/ice_prescribed_mod.F90
${CICE_CORE}/drivers/nuopc/cmeps/ice_scam.F90
${CICE_CORE}/drivers/nuopc/cmeps/ice_shr_methods.F90
)
else()
target_sources(cicelib PRIVATE
# CICE standalone
${CICE_CORE}/drivers/standalone/cice/CICE_FinalMod.F90
${CICE_CORE}/drivers/standalone/cice/CICE_InitMod.F90
${CICE_CORE}/drivers/standalone/cice/CICE_RunMod.F90
)
endif()

# Select IO source files based on CICE_IO
if(CICE_IO MATCHES "NetCDF")
target_sources(cicelib PRIVATE
${CICE_CORE}/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90
${CICE_CORE}/cicedyn/infrastructure/io/io_netcdf/ice_restart.F90
)
elseif(CICE_IO MATCHES "PIO")
target_sources(cicelib PRIVATE
${CICE_CORE}/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90
${CICE_CORE}/cicedyn/infrastructure/io/io_pio2/ice_pio.F90
${CICE_CORE}/cicedyn/infrastructure/io/io_pio2/ice_restart.F90
)
elseif(CICE_IO MATCHES "Binary")
target_sources(cicelib PRIVATE
${CICE_CORE}/cicedyn/infrastructure/io/io_binary/ice_history_write.F90
${CICE_CORE}/cicedyn/infrastructure/io/io_binary/ice_restart.F90
)
endif()

#[==============================================================================[
# Install or Export #
#]==============================================================================]

if(ACCESS3_LIB_INSTALL)
## Library
set_target_properties(cicelib PROPERTIES
OUTPUT_NAME access-cicelib
EXPORT_NAME cicelib
)
install(TARGETS cicelib
EXPORT CicelibTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT AccessCiceCmeps
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
# Fortran module files are a special case, as currently there is no standard
# way of handling them in CMake
target_include_directories(cicelib PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_MODULEDIR}/cicelib>")
get_target_property(cice_moddir cicelib Fortran_MODULE_DIRECTORY)
install(FILES ${cice_moddir}/ice_comp_nuopc.mod
DESTINATION ${CMAKE_INSTALL_MODULEDIR}/cicelib
COMPONENT AccessCiceCmeps
)
install(EXPORT CicelibTargets
FILE CicelibTargets.cmake
NAMESPACE Cicelib::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
)

# Make sure the dependencies get exported too
configure_package_config_file(
CicelibConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/CicelibConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CicelibConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
COMPONENT AccessCiceCmeps
)

if(CICE_IO MATCHES "NetCDF")
install(FILES ${CMAKE_SOURCE_DIR}/FindNetCDF.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
COMPONENT IO_NetCDF
)
elseif(CICE_IO MATCHES "PIO")
install(FILES ${CMAKE_SOURCE_DIR}/FindNetCDF.cmake ${CMAKE_SOURCE_DIR}/FindPIO.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Cicelib
COMPONENT IO_PIO
)
endif()

else()
set_target_properties(cicelib PROPERTIES
OUTPUT_NAME cicelib-standalone
EXPORT_NAME cicelib
)
add_executable(CICE ${CICE_CORE}/drivers/standalone/cice/CICE.F90)
target_link_libraries(CICE PRIVATE cicelib)

set_target_properties(CICE PROPERTIES
LINKER_LANGUAGE Fortran
OUTPUT_NAME cice
)
install(TARGETS CICE
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT IO_${CICE_IO}
)
endif()
27 changes: 27 additions & 0 deletions cmake/CicelibConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)

# Available components
# set(_supported_components AccessCiceCmeps IO_PIO IO_NetCDF)

# Request components
set(_required_components ${Cicelib_FIND_COMPONENTS})

# Check indirect dependencies
if (IO_PIO IN_LIST _required_components)
find_dependency(PIO REQUIRED COMPONENTS C Fortran)
find_dependency(NetCDF REQUIRED Fortran)
endif()

if (IO_NetCDF IN_LIST _required_components)
find_dependency(NetCDF REQUIRED Fortran)
endif()

# Run the normal Targets.cmake
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
include("${CMAKE_CURRENT_LIST_DIR}/CicelibTargets.cmake")
list(REMOVE_ITEM CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})

# Check the requested components are valid
check_required_components(_required_components)
Loading