Skip to content

Commit

Permalink
building access cice library
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-seaice committed Jan 13, 2025
1 parent 3203a96 commit 21e859a
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 74 deletions.
9 changes: 9 additions & 0 deletions cmake/AccessCiceCmeps.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@PACKAGE_INIT@


find_package(NetCDF 4.7.3 REQUIRED Fortran)
find_package(PIO 2.5.3 REQUIRED COMPONENTS C Fortran)

include("${CMAKE_CURRENT_LIST_DIR}/AccessCiceCmepsTargets.cmake")

check_required_components(AccessCiceCmeps)
107 changes: 89 additions & 18 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,35 @@ cmake_minimum_required(VERSION 3.18)
# Basic project definition #
#]==============================================================================]

project(CICE6 DESCRIPTION "CICE6" LANGUAGES C Fortran)
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")
Expand Down Expand Up @@ -51,22 +73,36 @@ set(CMAKE_INSTALL_MODULEDIR ${CMAKE_INSTALL_INCLUDEDIR}
"Fortran module installation path (Not a cmake native variable)"
)

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

if(ACCESS3_LIB_INSTALL)
find_package(Access3Share)
find_package(FoX 4.1.2 REQUIRED)
find_package(Access3Share) #should this have a REQUIRED?
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)
target_compile_definitions(cicelib PRIVATE FORTRANUNDERSCORE ncdf)

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)
Expand All @@ -81,6 +117,7 @@ if(CICE_IO MATCHES "^(NetCDF|PIO)$")
target_link_libraries(cicelib PRIVATE PIO::PIO_Fortran)
endif()
endif()

if(OpenMP_Fortran_FOUND)
target_link_libraries(cicelib PRIVATE OpenMP::OpenMP_Fortran)
endif()
Expand Down Expand Up @@ -205,6 +242,13 @@ if(ACCESS3_LIB_INSTALL)
${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
Expand All @@ -226,31 +270,58 @@ elseif(CICE_IO MATCHES "Binary")
)
endif()

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

## Library
if(ACCESS3_LIB_INSTALL)
## Library
set_target_properties(cicelib PROPERTIES
OUTPUT_NAME access-cice
EXPORT_NAME cice
OUTPUT_NAME access-cice-cmeps
EXPORT_NAME cice-cmeps
)
install(TARGETS cicelib
EXPORT Access3cice_Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Access3_RunTime NAMELINK_COMPONENT Access3_Development
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Access3_Development
EXPORT AccessCiceCmepsTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
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}/access-cice>")
get_target_property(cice_moddir cicelib Fortran_MODULE_DIRECTORY)
install(FILES ${cice_moddir}/ice_comp_nuopc.mod
DESTINATION ${CMAKE_INSTALL_MODULEDIR}/CICE
COMPONENT Access3_Development
DESTINATION ${CMAKE_INSTALL_MODULEDIR}/access-cice
)
install(EXPORT Access3cice_Targets
FILE Access3ciceTargets.cmake
NAMESPACE Access3::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CICE

# Make sure the dependencies get exported too
configure_package_config_file(
AccessCiceCmeps.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/AccessCiceCmepsConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/AccessCiceCmeps
)
install(FILES ${CMAKE_SOURCE_DIR}/FindNetCDF.cmake ${CMAKE_SOURCE_DIR}/FindPIO.cmake ${CMAKE_CURRENT_BINARY_DIR}/AccessCiceCmepsConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/AccessCiceCmeps
COMPONENT AccessCiceCmeps
)
# install(EXPORT AccessCiceCmepsTargets
# FILE AccessCiceCmepsTargets.cmake
# NAMESPACE AccessCiceCmeps::
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/AccessCiceCmeps
# )
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}
)
endif()
135 changes: 135 additions & 0 deletions cmake/FindESMF.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# - Try to find ESMF
#
# Requires setting ESMFMKFILE to the filepath of esmf.mk. If this is NOT set,
# then ESMF_FOUND will always be FALSE. If ESMFMKFILE exists, then ESMF_FOUND=TRUE
# and all ESMF makefile variables will be set in the global scope. Optionally,
# set ESMF_MKGLOBALS to a string list to filter makefile variables. For example,
# to globally scope only ESMF_LIBSDIR and ESMF_APPSDIR variables, use this CMake
# command in CMakeLists.txt:
#
# set(ESMF_MKGLOBALS "LIBSDIR" "APPSDIR")


# Add the ESMFMKFILE path to the cache if defined as system env variable
if(DEFINED ENV{ESMFMKFILE} AND NOT DEFINED ESMFMKFILE)
set(ESMFMKFILE $ENV{ESMFMKFILE} CACHE FILEPATH "Path to ESMF mk file")
endif()

# If it's not explicitly set try to find esmf.mk file in default locations (ESMF_ROOT, CMAKE_PREFIX_PATH, etc)
if(NOT DEFINED ESMFMKFILE)
find_path(ESMFMKFILE_PATH esmf.mk PATH_SUFFIXES lib lib64)
if(ESMFMKFILE_PATH)
set(ESMFMKFILE ${ESMFMKFILE_PATH}/esmf.mk)
message(STATUS "Found esmf.mk file ${ESMFMKFILE}")
else()
message(STATUS "ESMFMKFILE not defined. This is the path to esmf.mk file. \
Without this filepath, ESMF_FOUND will always be FALSE.")
endif()
endif()

# Only parse the mk file if it is found
if(EXISTS ${ESMFMKFILE})
# Read the mk file
file(STRINGS "${ESMFMKFILE}" esmfmkfile_contents)
# Parse each line in the mk file
foreach(str ${esmfmkfile_contents})
# Only consider uncommented lines
string(REGEX MATCH "^[^#]" def ${str})
# Line is not commented
if(def)
# Extract the variable name
string(REGEX MATCH "^[^=]+" esmf_varname ${str})
# Extract the variable's value
string(REGEX MATCH "=.+$" esmf_vardef ${str})
# Only for variables with a defined value
if(esmf_vardef)
# Get rid of the assignment string
string(SUBSTRING ${esmf_vardef} 1 -1 esmf_vardef)
# Remove whitespace
string(STRIP ${esmf_vardef} esmf_vardef)
# A string or single-valued list
if(NOT DEFINED ESMF_MKGLOBALS)
# Set in global scope
set(${esmf_varname} ${esmf_vardef})
# Don't display by default in GUI
mark_as_advanced(esmf_varname)
else() # Need to filter global promotion
foreach(m ${ESMF_MKGLOBALS})
string(FIND ${esmf_varname} ${m} match)
# Found the string
if(NOT ${match} EQUAL -1)
# Promote to global scope
set(${esmf_varname} ${esmf_vardef})
# Don't display by default in the GUI
mark_as_advanced(esmf_varname)
# No need to search for the current string filter
break()
endif()
endforeach()
endif()
endif()
endif()
endforeach()

# Construct ESMF_VERSION from ESMF_VERSION_STRING_GIT
# ESMF_VERSION_MAJOR and ESMF_VERSION_MINOR are defined in ESMFMKFILE
set(ESMF_VERSION 0)
set(ESMF_VERSION_PATCH ${ESMF_VERSION_REVISION})
set(ESMF_BETA_RELEASE FALSE)
if(ESMF_VERSION_BETASNAPSHOT MATCHES "^('T')$")
set(ESMF_BETA_RELEASE TRUE)
string(REGEX REPLACE ".*beta_snapshot_*\([0-9]*\).*" "\\1" ESMF_BETA_SNAPSHOT "${ESMF_VERSION_STRING_GIT}")
message(STATUS "Detected ESMF Beta snapshot ${ESMF_BETA_SNAPSHOT}")
endif()
set(ESMF_VERSION "${ESMF_VERSION_MAJOR}.${ESMF_VERSION_MINOR}.${ESMF_VERSION_PATCH}")

separate_arguments(ESMF_F90COMPILEPATHS NATIVE_COMMAND ${ESMF_F90COMPILEPATHS})
foreach(ITEM ${ESMF_F90COMPILEPATHS})
string(REGEX REPLACE "^-I" "" ITEM "${ITEM}")
list(APPEND tmp ${ITEM})
endforeach()
set(ESMF_F90COMPILEPATHS ${tmp})

# Look for static library, if not found try dynamic library
find_library(esmf_lib NAMES libesmf.a PATHS ${ESMF_LIBSDIR})
if(esmf_lib MATCHES "esmf_lib-NOTFOUND")
unset(esmf_lib)
message(STATUS "Static ESMF library not found, searching for dynamic library instead")
find_library(esmf_lib NAMES esmf_fullylinked libesmf.so PATHS ${ESMF_LIBSDIR})
if(esmf_lib MATCHES "esmf_lib-NOTFOUND")
unset(esmf_lib)
message(STATUS "Neither the dynamic nor the static ESMF library was found")
else()
set(_library_type SHARED)
endif()
else()
set(_library_type STATIC)
endif()

string(STRIP "${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES)
set(ESMF_LIBRARY_LOCATION ${esmf_lib})

else()

message(WARNING "ESMFMKFILE ${ESMFMKFILE} does not exist")

endif()

## Finalize find_package
include(FindPackageHandleStandardArgs)

find_package_handle_standard_args(
${CMAKE_FIND_PACKAGE_NAME}
REQUIRED_VARS ESMF_LIBRARY_LOCATION
ESMF_INTERFACE_LINK_LIBRARIES
ESMF_F90COMPILEPATHS
VERSION_VAR ESMF_VERSION)

## If ESMF is found create imported library target
if(ESMF_FOUND)
add_library(esmf ${_library_type} IMPORTED)
set_target_properties(esmf PROPERTIES
IMPORTED_LOCATION "${ESMF_LIBRARY_LOCATION}"
INTERFACE_INCLUDE_DIRECTORIES "${ESMF_F90COMPILEPATHS}"
INTERFACE_LINK_LIBRARIES "${ESMF_INTERFACE_LINK_LIBRARIES}")
endif()
56 changes: 0 additions & 56 deletions cmake/FindFoX.cmake

This file was deleted.

0 comments on commit 21e859a

Please sign in to comment.