diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dff6c12fc..4753b299e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,68 +1,227 @@ -# CMake build written by Kyle Gerheiser +# Copyright ACCESS-NRI and contributors. See the top-level LICENSE file for details. -# Requires CMake 3.19 for JSON strings cmake_minimum_required(VERSION 3.19) -# Get VERSION from VERSION file -file(STRINGS "VERSION" pVersion) - -project( - WW3 - VERSION ${pVersion} - LANGUAGES C Fortran) - -get_directory_property(hasParent PARENT_DIRECTORY) -if(hasParent) - # Unset flags that come from Parent (ie UFS or other coupled build) - # for potential (-r8/-r4) conflict - set(CMAKE_Fortran_FLAGS "") - set(CMAKE_C_FLAGS "") - remove_definitions(-DDEBUG) +#[==============================================================================[ +# Basic project definition # +#]==============================================================================] + +project(WW3 + DESCRIPTION "WAVEWATCH III numerical wave model" + HOMEPAGE_URL https://github.com/ACCESS-NRI/WW3/ + LANGUAGES C Fortran) + +#[==============================================================================[ +# Options # +#]==============================================================================] + +## List of switches +# to-do: make configurable +list(APPEND switches "CESMCOUPLED" "DIST" "MPI" "PR1" "FLX4" "ST6" "STAB0" "LN1" "NL1" "BT1" "DB1" "MLIM" "TR0" "BS0" "RWND" "WNX1" "WNT0" "CRX1" "CRT0" "O0" "O1" "O2" "O3" "O4" "O5" "O6" "O7" "O14" "O15" "IS2" "REF0" "NOGRB" "IC3") + +option(WW3_ACCESS3 "Use ACCESS3 dependencies and install ACCESS3 libraries" OFF) +option(WW3_OPENMP "Enable OpenMP threading" OFF) +message(STATUS " - WW3_ACCESS3 ${WW3_ACCESS3}") +message(STATUS " - WW3_OPENMP ${WW3_OPENMP}") + +if(NOT WW3_ACCESS3) + message(STATUS " - NOT WW3_ACCESS3: Building standalone ww3_shel for testing") endif() -set(valid_caps "MULTI_ESMF" "NUOPC_MESH") +if(WW3_OPENMP) + list(APPEND switches "OMPG") +endif() -set(UFS_CAP "" CACHE STRING "Valid options are ${valid_caps}") -set(NETCDF ON CACHE BOOL "Build NetCDF programs (requires NetCDF)") -set(ENDIAN "BIG" CACHE STRING "Endianness of unformatted output files. Valid values are 'BIG', 'LITTLE', 'NATIVE'.") -set(EXCLUDE_FIND "" CACHE STRING "Don't try and search for these libraries (assumd to be handled by the compiler/wrapper)") -# make sure all "exclude_find" entries are lower case -list(TRANSFORM EXCLUDE_FIND TOLOWER) -# Make Find modules visible to CMake +#[==============================================================================[ +# Project configuration # +#]==============================================================================] + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -# Set switch file on command line when running CMake -set(SWITCH "" CACHE STRING "Switch file, either full path, relative path from location of top-level WW3/ dir, or a switch in model/bin") +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) +include(FortranLib) -# Search for switch file as a full path or in model/bin -if(EXISTS ${SWITCH}) - set(switch_file ${SWITCH}) -else() - set(switch_file ${CMAKE_CURRENT_SOURCE_DIR}/model/bin/switch_${SWITCH}) - if(NOT EXISTS ${switch_file}) - message(FATAL_ERROR "Switch file '${switch_file}' does not exist, set switch with -DSWITCH=") +# 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 precise") + 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(UFS_CAP) - if(NOT UFS_CAP IN_LIST valid_caps) - message(FATAL_ERROR "Invalid UFS_CAP selection. Valids options are ${valid_caps}") - 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() -message(STATUS "Build with switch: ${switch_file}") -# Copy switch file to build dir -configure_file(${switch_file} ${CMAKE_BINARY_DIR}/switch COPYONLY) +## Global compile definitions +foreach(switch ${switches}) + add_compile_definitions(W3_${switch}) +endforeach() -# Re-configure CMake when switch changes -set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_BINARY_DIR}/switch) +if ("CESMCOUPLED" IN_LIST switches) + 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 # +#]==============================================================================] + +find_package(MPI REQUIRED) + +if(WW3_ACCESS3) + find_package(Access3Share REQUIRED cdeps timing share nuopc_cap_share) + if(NOT TARGET ESMF::ESMF) #Access3Share probably already has ESMF with PUBLIC interface + find_package(ESMF 8.3.0 MODULE REQUIRED) + endif() +endif() -if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)$") - message(STATUS "Setting build type to 'Release' as none was specified.") - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +if(NOT TARGET NetCDF::NetCDF_Fortran) #Access3Share probably already has NetCDF with PUBLIC interface + find_package(NetCDF 4.7.3 MODULE REQUIRED Fortran) + # Code has not been tested with versions older than 4.7.3, but probably still works fine endif() -add_subdirectory(model) +if(WW3_OPENMP) + find_package(OpenMP REQUIRED COMPONENTS Fortran) +endif() + +#[==============================================================================[ +# Main definitions # +#]==============================================================================] + +## WW3 library + +set(SRC "${CMAKE_SOURCE_DIR}/model/src") + +add_fortran_library(ww3lib mod STATIC) +target_include_directories(ww3lib PRIVATE $) +target_compile_definitions(ww3lib PRIVATE ENDIANNESS="big_endian") +set_property(SOURCE ${SRC}/w3initmd.F90 + APPEND + PROPERTY COMPILE_DEFINITIONS + "__WW3_SWITCHES__=\'\'" +) +target_link_libraries(ww3lib PUBLIC NetCDF::NetCDF_Fortran) + +if(WW3_ACCESS3) + target_link_libraries(ww3lib PUBLIC ESMF::ESMF PIO::PIO_C) +endif() + +if(OpenMP_Fortran_FOUND) + target_link_libraries(ww3lib PUBLIC OpenMP::OpenMP_Fortran) +endif() + +# Process switches and get list of extra source files +include(${CMAKE_CURRENT_SOURCE_DIR}/model/src/cmake/check_switches.cmake) +check_switches("${switches}" switch_files) +message(VERBOSE "WW3 switch files: ${switch_files}") + +include(${CMAKE_CURRENT_SOURCE_DIR}/model/src/cmake/src_list.cmake) + +if(WW3_ACCESS3) + list(APPEND ftn_src ${nuopc_mesh_cap_src}) +endif() + +list(APPEND ftn_src ${switch_files}) + +foreach(file ${ftn_src}) + list(APPEND srcfiles "${CMAKE_CURRENT_SOURCE_DIR}/model/src/${file}") +endforeach() + +target_sources(ww3lib PRIVATE ${srcfiles}) + +## Utilities +# Always build utilities: +set(utility_apps ww3_grid ww3_strt ww3_outf ww3_ounf ww3_ounp) +if(NOT WW3_ACCESS3) + # A generic WW3 "shell" for testing + list(APPEND utility_apps ww3_shel) +endif() + #to-do: confim when other utilities are needed: + # ww3_bound ww3_outp ww3_trck ww3_grib + # ww3_gint gx_outf gx_outp ww3_uprstr ww3_prep ww3_gspl ww3_multi ww3_systrk + # ww3_ounf ww3_ounp ww3_bounc ww3_trnc ww3_prnc + +foreach(program ${utility_apps}) + add_executable(${program} ${SRC}/${program}.F90) + set_target_properties(${program} PROPERTIES + LINKER_LANGUAGE Fortran + OUTPUT_NAME ${program} + ) + target_link_libraries(${program} PRIVATE ww3lib) +endforeach() + +# ww3_ounf has en extra file +target_sources(ww3_ounf PRIVATE + ${SRC}/w3ounfmetamd.F90 +) + +#[==============================================================================[ +# Install and Export # +#]==============================================================================] + +## Library +if(WW3_ACCESS3) + set_target_properties(ww3lib PROPERTIES + OUTPUT_NAME access-ww3lib + EXPORT_NAME ww3lib + ) + install(TARGETS ww3lib + EXPORT Ww3libTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT AccessWW3_RunTime NAMELINK_COMPONENT AccessWW3_Development + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT AccessWW3_Development + ) + # Fortran module files are a special case, as currently there is no standard + # way of handling them in CMake + target_include_directories(ww3lib PUBLIC "$") + get_target_property(ww3_moddir ww3lib Fortran_MODULE_DIRECTORY) + install(FILES ${ww3_moddir}/wav_comp_nuopc.mod + DESTINATION ${CMAKE_INSTALL_MODULEDIR}/access-ww3 + COMPONENT AccessWW3_Development + ) + install(EXPORT Ww3libTargets + FILE Ww3libTargets.cmake + NAMESPACE Access3:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Ww3lib + ) + + # Make sure the dependencies get exported too + configure_package_config_file( + cmake/Access3Ww3libConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/Ww3libConfig.cmake" + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Ww3lib + ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Ww3libConfig.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Ww3lib + COMPONENT AccessWW3_Development + ) +endif() + +## Utilities +install(TARGETS ${utility_apps} +RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + diff --git a/cmake/Access3Ww3libConfig.cmake.in b/cmake/Access3Ww3libConfig.cmake.in new file mode 100644 index 0000000000..ce8f22ec95 --- /dev/null +++ b/cmake/Access3Ww3libConfig.cmake.in @@ -0,0 +1,18 @@ +# Copyright ACCESS-NRI and contributors. See the top-level LICENSE file for details. + +@PACKAGE_INIT@ + +if(@OPENMP@) + find_package(OpenMP REQUIRED) +endif() + +# Request components +set(_required_components ${Ww3lib_FIND_COMPONENTS}) + +# Run the normal Targets.cmake +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) +include("${CMAKE_CURRENT_LIST_DIR}/Ww3libTargets.cmake") +list(REMOVE_ITEM CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) + +# Check the requested components are valid +check_required_components(_required_components) \ No newline at end of file diff --git a/cmake/FindESMF.cmake b/cmake/FindESMF.cmake index 5ba7003bdb..8dfb926ce1 100644 --- a/cmake/FindESMF.cmake +++ b/cmake/FindESMF.cmake @@ -1,34 +1,81 @@ +# Earth System Modeling Framework + +# Copyright (c) 2002-2025 University Corporation for Atmospheric Research, +# Massachusetts Institute of Technology, Geophysical Fluid Dynamics Laboratory, +# University of Michigan, National Centers for Environmental Prediction, +# Los Alamos National Laboratory, Argonne National Laboratory, +# NASA Goddard Space Flight Center. +# All rights reserved. + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal with the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimers. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimers in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the names of the organizations developing this software, nor +# the names of its contributors may be used to endorse or promote products +# derived from this Software without specific prior written permission. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# WITH THE SOFTWARE. + # - 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: +# Uses ESMFMKFILE to find the filepath of esmf.mk. If this is NOT set, then this +# module will attempt to find esmf.mk. 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") +# Set ESMFMKFILE as defined by system env variable. If it's not explicitly set +# try to find esmf.mk file in default locations (ESMF_ROOT, CMAKE_PREFIX_PATH, +# etc) -# 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() +# - Common Usage +# +# Where to look for this FindESMF.cmake file +# list(APPEND CMAKE_MODULE_PATH "") +# is to be replaced with the directory for this file +# +# How to locate ESMF libraries and create target +# find_package(ESMF MODULE REQUIRED) +# is to be replaced with the minimum version required +# +# How to link targets +# target_link_libraries( PUBLIC ESMF::ESMF) +# is to be replaced with your CMake target -# 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}") + if(NOT DEFINED ENV{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}") + endif() else() - message(STATUS "ESMFMKFILE not defined. This is the path to esmf.mk file. \ -Without this filepath, ESMF_FOUND will always be FALSE.") + set(ESMFMKFILE $ENV{ESMFMKFILE}) endif() endif() # Only parse the mk file if it is found if(EXISTS ${ESMFMKFILE}) + set(ESMFMKFILE ${ESMFMKFILE} CACHE FILEPATH "Path to esmf.mk file") + set(ESMF_FOUND TRUE CACHE BOOL "esmf.mk file found" FORCE) + # Read the mk file file(STRINGS "${ESMFMKFILE}" esmfmkfile_contents) # Parse each line in the mk file @@ -78,58 +125,70 @@ if(EXISTS ${ESMFMKFILE}) 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}") + if(ESMF_VERSION_STRING_GIT MATCHES "^ESMF.*beta_snapshot") + set(ESMF_BETA_SNAPSHOT ${ESMF_VERSION_STRING_GIT}) + elseif(ESMF_VERSION_STRING_GIT MATCHES "^v.\..\..b") + set(ESMF_BETA_SNAPSHOT ${ESMF_VERSION_STRING_GIT}) + else() + set(ESMF_BETA_SNAPSHOT 0) + endif() + 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) + # Find the ESMF library + if(USE_ESMF_STATIC_LIBS) + find_library(ESMF_LIBRARY_LOCATION NAMES libesmf.a PATHS ${ESMF_LIBSDIR} NO_DEFAULT_PATH) + if(ESMF_LIBRARY_LOCATION MATCHES "ESMF_LIBRARY_LOCATION-NOTFOUND") + message(WARNING "Static ESMF library (libesmf.a) not found in \ + ${ESMF_LIBSDIR}. Try setting USE_ESMF_STATIC_LIBS=OFF") + endif() + if(NOT TARGET ESMF::ESMF) + add_library(ESMF::ESMF STATIC IMPORTED) endif() else() - set(_library_type STATIC) + find_library(ESMF_LIBRARY_LOCATION NAMES esmf PATHS ${ESMF_LIBSDIR} NO_DEFAULT_PATH) + if(ESMF_LIBRARY_LOCATION MATCHES "ESMF_LIBRARY_LOCATION-NOTFOUND") + message(WARNING "ESMF library not found in ${ESMF_LIBSDIR}.") + endif() + if(NOT TARGET ESMF::ESMF) + add_library(ESMF::ESMF UNKNOWN IMPORTED) + endif() endif() - string(STRIP "${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES) - set(ESMF_LIBRARY_LOCATION ${esmf_lib}) + # Add ESMF as an alias to ESMF::ESMF for backward compatibility + if(NOT TARGET ESMF) + add_library(ESMF ALIAS ESMF::ESMF) + endif() -else() + # Add ESMF include directories + set(ESMF_INCLUDE_DIRECTORIES "") + separate_arguments(_ESMF_F90COMPILEPATHS UNIX_COMMAND ${ESMF_F90COMPILEPATHS}) + foreach(_ITEM ${_ESMF_F90COMPILEPATHS}) + string(REGEX REPLACE "^-I" "" _ITEM "${_ITEM}") + list(APPEND ESMF_INCLUDE_DIRECTORIES ${_ITEM}) + endforeach() - message(WARNING "ESMFMKFILE ${ESMFMKFILE} does not exist") + # Add ESMF link libraries + string(STRIP "${ESMF_F90LINKRPATHS} ${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES) -endif() + # Finalize find_package + include(FindPackageHandleStandardArgs) -## 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() + find_package_handle_standard_args( + ${CMAKE_FIND_PACKAGE_NAME} + REQUIRED_VARS ESMF_LIBRARY_LOCATION + ESMF_INTERFACE_LINK_LIBRARIES + ESMF_F90COMPILEPATHS + VERSION_VAR ESMF_VERSION) + + set_target_properties(ESMF::ESMF PROPERTIES + IMPORTED_LOCATION "${ESMF_LIBRARY_LOCATION}" + INTERFACE_INCLUDE_DIRECTORIES "${ESMF_INCLUDE_DIRECTORIES}" + INTERFACE_LINK_LIBRARIES "${ESMF_INTERFACE_LINK_LIBRARIES}") + +else() + set(ESMF_FOUND FALSE CACHE BOOL "esmf.mk file NOT found" FORCE) + message(WARNING "ESMFMKFILE ${ESMFMKFILE} not found. Try setting ESMFMKFILE \ + to esmf.mk location.") +endif() \ No newline at end of file diff --git a/cmake/FortranLib.cmake b/cmake/FortranLib.cmake new file mode 100644 index 0000000000..6eaec978be --- /dev/null +++ b/cmake/FortranLib.cmake @@ -0,0 +1,10 @@ +# Copyright ACCESS-NRI and contributors. See the top-level LICENSE file for details. + +function(add_fortran_library LIB MOD_DIR) + add_library(${LIB} ${ARGN}) + + get_target_property(LIB_DIR ${LIB} BINARY_DIR) + set_target_properties(${LIB} PROPERTIES Fortran_MODULE_DIRECTORY ${LIB_DIR}/${MOD_DIR}) + + target_include_directories(${LIB} INTERFACE "$") + endfunction(add_fortran_library) diff --git a/model/src/cmake/check_switches.cmake b/model/src/cmake/check_switches.cmake index 563d529e21..12c5edbebf 100644 --- a/model/src/cmake/check_switches.cmake +++ b/model/src/cmake/check_switches.cmake @@ -1,6 +1,6 @@ function(check_switches switches switch_files) # Read JSON file - file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/switches.json json_str) + file(READ ${CMAKE_CURRENT_SOURCE_DIR}/model/src/cmake/switches.json json_str) # Get length of top-level array of all switch categories string(JSON len LENGTH ${json_str}) # CMake's foreach RANGE is inclusive, so subtract 1 when looping diff --git a/model/src/w3srcemd.F90 b/model/src/w3srcemd.F90 index 9bd97c6fbd..c51a86094d 100644 --- a/model/src/w3srcemd.F90 +++ b/model/src/w3srcemd.F90 @@ -2088,7 +2088,7 @@ SUBROUTINE W3SRCE ( srce_call, IT, ISEA, JSEA, IX, IY, IMOD, & #ifdef W3_IC3 CALL W3SIC3 ( SPEC,DEPTH, CG1, WN1, IX, IY, VSIC, VDIC ) #endif -#ifndef W3_IC4_NUMERICS +#if defined(W3_IC4) && !defined(W3_IC4_NUMERICS) CALL W3SIC4 ( SPEC,DEPTH, CG1, IX, IY, VSIC, VDIC ) #endif #ifdef W3_IC5 @@ -2119,7 +2119,7 @@ SUBROUTINE W3SRCE ( srce_call, IT, ISEA, JSEA, IX, IY, IMOD, & #ifdef W3_IC3 ATT=EXP(ICE*VDIC(IS)*DTG) #endif -#ifndef W3_IC4_NUMERICS +#if defined(W3_IC4) && !defined(W3_IC4_NUMERICS) ATT=EXP(ICE*VDIC(IS)*DTG) #endif #ifdef W3_IC5