diff --git a/configuration/scripts/cmake/CMakeLists.txt b/configuration/scripts/cmake/CMakeLists.txt new file mode 100644 index 000000000..0f4930678 --- /dev/null +++ b/configuration/scripts/cmake/CMakeLists.txt @@ -0,0 +1,373 @@ +# Copyright ACCESS-NRI and contributors. See the top-level LICENSE file for details. + +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 # +#]==============================================================================] + +message(STATUS "Build options") + +option(CICE_IO "CICE IO Method" OFF) +if (NOT CICE_IO) + set(CICE_IO "Binary") #set a default +endif() +if(NOT CICE_IO MATCHES "^(NetCDF|PIO|Binary)$") + message(FATAL_ERROR " CICE_IO ${CICE_IO} not valid, choose NetCDF|PIO|Binary") +else() + message(STATUS " - CICE_IO ${CICE_IO}") +endif() + +option(CICE_ACCESS3 "Use ACCESS3 dependencies and install ACCESS3 libraries" OFF) +option(CICE_OPENMP "Enable OpenMP threading" OFF) +message(STATUS " - CICE_ACCESS3 ${CICE_ACCESS3}") +message(STATUS " - CICE_OPENMP ${CICE_OPENMP}") + +#placeholder CICE_DRIVER option to allow for a nuopc/access driver in the future +option(CICE_DRIVER "CICE driver code to use" OFF) +if(NOT CICE_DRIVER) + if(CICE_ACCESS3) + set(CICE_DRIVER "nuopc/cmeps") + else() + set(CICE_DRIVER "standalone/cice") + endif() +endif() +message(STATUS " - CICE_DRIVER ${CICE_DRIVER}") + +#[==============================================================================[ +# 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 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(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 (CICE_ACCESS3) + 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(CICE_ACCESS3) + find_package(Access3Share REQUIRED cdeps timing share nuopc_cap_share) + if(NOT TARGET ESMF::ESMF) #Access3Share probably already has ESMF with PUBLIC interface + message(FATAL_ERROR "ESMF interface missing from Access3Share package") + endif() +else() + find_package(MPI REQUIRED) +endif() + +if(CICE_OPENMP) + find_package(OpenMP REQUIRED COMPONENTS Fortran) +endif() + +if(CICE_IO MATCHES "^(NetCDF|PIO)$" AND NOT TARGET NetCDF::NetCDF_Fortran) + # Code has not been tested with versions older than 4.7.3, but probably still works fine + find_package(NetCDF 4.7.3 REQUIRED Fortran) +endif() +if(CICE_IO MATCHES "PIO" AND NOT TARGET PIO::PIO_Fortran) + find_package(PIO 2.5.3 REQUIRED COMPONENTS Fortran) + # Code has not been tested with versions older than 2.5.3, but probably still works fine +endif() + +#[==============================================================================[ +# Main definitions # +#]==============================================================================] + +### Targets + +## CICE library + +set(CICE_CORE "${CMAKE_SOURCE_DIR}/../../../cicecore") +set(ICEPACK "${CMAKE_SOURCE_DIR}/../../../icepack") + +add_fortran_library(cicelib mod STATIC) + +if(CICE_IO MATCHES "^(NetCDF|PIO)$") + target_compile_definitions(cicelib PRIVATE FORTRANUNDERSCORE ncdf) + target_compile_definitions(cicelib PRIVATE USE_NETCDF) +endif() +if(CICE_ACCESS3) + target_link_libraries(cicelib + PUBLIC ESMF::ESMF + PRIVATE Access3::nuopc_cap_share Access3::share Access3::timing Access3::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(CICE_OPENMP) + target_link_libraries(cicelib PUBLIC OpenMP::OpenMP_Fortran) +endif() + + + +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(CICE_DRIVER MATCHES "nuopc/cmeps") + target_sources(cicelib PRIVATE + # NUOPC CMEPS driver + ${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_FinalMod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_InitMod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_RunMod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/cice_wrapper_mod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/ice_comp_nuopc.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/ice_import_export.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/ice_mesh_mod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/ice_prescribed_mod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/ice_scam.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/ice_shr_methods.F90 + ) +elseif(CICE_DRIVER MATCHES "standalone/cice") + target_sources(cicelib PRIVATE + # CICE standalone + ${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_FinalMod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_InitMod.F90 + ${CICE_CORE}/drivers/${CICE_DRIVER}/CICE_RunMod.F90 + ) +else() + message(FATAL_ERROR "CICE_DRIVER: ${CICE_DRIVER} is currently not supported by the CMake build system") +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(CICE_ACCESS3) + ## Library + set_target_properties(cicelib PROPERTIES + OUTPUT_NAME access-cicelib + EXPORT_NAME cicelib + ) + install(TARGETS cicelib + EXPORT CicelibTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT AccessCICE_runtime NAMELINK_COMPONENT AccessCICE_Development + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT AccessCICE_Development + ) + # Fortran module files are a special case, as currently there is no standard + # way of handling them in CMake + target_include_directories(cicelib PUBLIC "$") + get_target_property(cice_moddir cicelib Fortran_MODULE_DIRECTORY) + install(FILES ${cice_moddir}/ice_comp_nuopc.mod + DESTINATION ${CMAKE_INSTALL_MODULEDIR}/cicelib + COMPONENT AccessCICECmeps_Development + ) + install(EXPORT CicelibTargets + FILE CicelibTargets.cmake + NAMESPACE Access3:: + 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 AccessCICE_Development + ) + + 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 MPI::MPI_Fortran) + + set_target_properties(CICE PROPERTIES + LINKER_LANGUAGE Fortran + OUTPUT_NAME cice + ) + install(TARGETS CICE + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT IO_${CICE_IO} + ) +endif() diff --git a/configuration/scripts/cmake/CicelibConfig.cmake.in b/configuration/scripts/cmake/CicelibConfig.cmake.in new file mode 100644 index 000000000..13b9e5fa7 --- /dev/null +++ b/configuration/scripts/cmake/CicelibConfig.cmake.in @@ -0,0 +1,31 @@ +# Copyright ACCESS-NRI and contributors. See the top-level LICENSE file for details. + +@PACKAGE_INIT@ + +# Request components +set(_required_components ${Cicelib_FIND_COMPONENTS}) + + +# Check indirect dependencies +set(CICE_IO @CICE_IO@) + +if(CICE_IO MATCHES "NetCDF") + find_dependency(NetCDF 4.7.3 REQUIRED Fortran) +elseif(CICE_IO MATCHES "PIO") + if (NOT TARGET PIO::PIO_Fortran) + find_dependency(PIO 2.5.3 REQUIRED COMPONENTS C Fortran) + endif() + find_dependency(NetCDF REQUIRED Fortran) +endif() + +if(@OPENMP@) + find_package(OpenMP REQUIRED) +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) \ No newline at end of file diff --git a/configuration/scripts/cmake/FindNetCDF.cmake b/configuration/scripts/cmake/FindNetCDF.cmake new file mode 100644 index 000000000..1439ae848 --- /dev/null +++ b/configuration/scripts/cmake/FindNetCDF.cmake @@ -0,0 +1,337 @@ +# (C) Copyright 2011- ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation nor +# does it submit to any jurisdiction. + +# Try to find NetCDF includes and library. +# Supports static and shared libaries and allows each component to be found in sepearte prefixes. +# +# This module defines +# +# - NetCDF_FOUND - System has NetCDF +# - NetCDF_INCLUDE_DIRS - the NetCDF include directories +# - NetCDF_VERSION - the version of NetCDF +# - NetCDF_CONFIG_EXECUTABLE - the netcdf-config executable if found +# - NetCDF_PARALLEL - Boolean True if NetCDF4 has parallel IO support via hdf5 and/or pnetcdf +# - NetCDF_HAS_PNETCDF - Boolean True if NetCDF4 has pnetcdf support +# +# Deprecated Defines +# - NetCDF_LIBRARIES - [Deprecated] Use NetCDF::NetCDF_ targets instead. +# +# +# Following components are available: +# +# - C - C interface to NetCDF (netcdf) +# - CXX - CXX4 interface to NetCDF (netcdf_c++4) +# - Fortran - Fortran interface to NetCDF (netcdff) +# +# For each component the following are defined: +# +# - NetCDF__FOUND - whether the component is found +# - NetCDF__LIBRARIES - the libraries for the component +# - NetCDF__LIBRARY_SHARED - Boolean is true if libraries for component are shared +# - NetCDF__INCLUDE_DIRS - the include directories for specified component +# - NetCDF::NetCDF_ - target of component to be used with target_link_libraries() +# +# The following paths will be searched in order if set in CMake (first priority) or environment (second priority) +# +# - NetCDF_ROOT - root of NetCDF installation +# - NetCDF_PATH - root of NetCDF installation +# +# The search process begins with locating NetCDF Include headers. If these are in a non-standard location, +# set one of the following CMake or environment variables to point to the location: +# +# - NetCDF_INCLUDE_DIR or NetCDF_${comp}_INCLUDE_DIR +# - NetCDF_INCLUDE_DIRS or NetCDF_${comp}_INCLUDE_DIR +# +# Notes: +# +# - Use "NetCDF::NetCDF_" targets only. NetCDF_LIBRARIES exists for backwards compatibility and should not be used. +# - These targets have all the knowledge of include directories and library search directories, and a single +# call to target_link_libraries will provide all these transitive properties to your target. Normally all that is +# needed to build and link against NetCDF is, e.g.: +# target_link_libraries(my_c_tgt PUBLIC NetCDF::NetCDF_C) +# - "NetCDF" is always the preferred naming for this package, its targets, variables, and environment variables +# - For compatibility, some variables are also set/checked using alternate names NetCDF4, NETCDF, or NETCDF4 +# - Environments relying on these older environment variable names should move to using a "NetCDF_ROOT" environment variable +# - Preferred component capitalization follows the CMake LANGUAGES variables: i.e., C, Fortran, CXX +# - For compatibility, alternate capitalizations are supported but should not be used. +# - If no components are defined, all components will be searched +# + +list( APPEND _possible_components C CXX Fortran ) + +## Include names for each component +set( NetCDF_C_INCLUDE_NAME netcdf.h ) +set( NetCDF_CXX_INCLUDE_NAME netcdf ) +set( NetCDF_Fortran_INCLUDE_NAME netcdf.mod ) + +## Library names for each component +set( NetCDF_C_LIBRARY_NAME netcdf ) +set( NetCDF_CXX_LIBRARY_NAME netcdf_c++4 ) +set( NetCDF_Fortran_LIBRARY_NAME netcdff ) + +## Enumerate search components +foreach( _comp ${_possible_components} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_${_COMP} ${_comp} ) + set( _name_${_COMP} ${_comp} ) +endforeach() + +set( _search_components C) +foreach( _comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_${_COMP} ${_comp} ) + list( APPEND _search_components ${_name_${_COMP}} ) + if( NOT _name_${_COMP} ) + message(SEND_ERROR "Find${CMAKE_FIND_PACKAGE_NAME}: COMPONENT ${_comp} is not a valid component. Valid components: ${_possible_components}" ) + endif() +endforeach() +list( REMOVE_DUPLICATES _search_components ) + +## Search hints for finding include directories and libraries +foreach( _comp IN ITEMS "_" "_C_" "_Fortran_" "_CXX_" ) + foreach( _name IN ITEMS NetCDF4 NetCDF NETCDF4 NETCDF ) + foreach( _var IN ITEMS ROOT PATH ) + list(APPEND _search_hints ${${_name}${_comp}${_var}} $ENV{${_name}${_comp}${_var}} ) + list(APPEND _include_search_hints + ${${_name}${_comp}INCLUDE_DIR} $ENV{${_name}${_comp}INCLUDE_DIR} + ${${_name}${_comp}INCLUDE_DIRS} $ENV{${_name}${_comp}INCLUDE_DIRS} ) + endforeach() + endforeach() +endforeach() +#Old-school HPC module env variable names +foreach( _name IN ITEMS NetCDF4 NetCDF NETCDF4 NETCDF ) + foreach( _comp IN ITEMS "_C" "_Fortran" "_CXX" ) + list(APPEND _search_hints ${${_name}} $ENV{${_name}}) + list(APPEND _search_hints ${${_name}${_comp}} $ENV{${_name}${_comp}}) + endforeach() +endforeach() + +## Find headers for each component +set(NetCDF_INCLUDE_DIRS) +set(_new_search_components) +foreach( _comp IN LISTS _search_components ) + if(NOT ${PROJECT_NAME}_NetCDF_${_comp}_FOUND) + list(APPEND _new_search_components ${_comp}) + endif() + find_file(NetCDF_${_comp}_INCLUDE_FILE + NAMES ${NetCDF_${_comp}_INCLUDE_NAME} + DOC "NetCDF ${_comp} include directory" + HINTS ${_include_search_hints} ${_search_hints} + PATH_SUFFIXES include include/netcdf + ) + mark_as_advanced(NetCDF_${_comp}_INCLUDE_FILE) + message(DEBUG "NetCDF_${_comp}_INCLUDE_FILE: ${NetCDF_${_comp}_INCLUDE_FILE}") + if( NetCDF_${_comp}_INCLUDE_FILE ) + get_filename_component(NetCDF_${_comp}_INCLUDE_FILE ${NetCDF_${_comp}_INCLUDE_FILE} ABSOLUTE) + get_filename_component(NetCDF_${_comp}_INCLUDE_DIR ${NetCDF_${_comp}_INCLUDE_FILE} DIRECTORY) + list(APPEND NetCDF_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIR}) + endif() +endforeach() +if(NetCDF_INCLUDE_DIRS) + list(REMOVE_DUPLICATES NetCDF_INCLUDE_DIRS) +endif() +set(NetCDF_INCLUDE_DIRS "${NetCDF_INCLUDE_DIRS}" CACHE STRING "NetCDF Include directory paths" FORCE) + +## Find n*-config executables for search components +foreach( _comp IN LISTS _search_components ) + if( _comp MATCHES "^(C)$" ) + set(_conf "c") + elseif( _comp MATCHES "^(Fortran)$" ) + set(_conf "f") + elseif( _comp MATCHES "^(CXX)$" ) + set(_conf "cxx4") + endif() + find_program( NetCDF_${_comp}_CONFIG_EXECUTABLE + NAMES n${_conf}-config + HINTS ${NetCDF_INCLUDE_DIRS} ${_include_search_hints} ${_search_hints} + PATH_SUFFIXES bin Bin ../bin ../../bin + DOC "NetCDF n${_conf}-config helper" ) + message(DEBUG "NetCDF_${_comp}_CONFIG_EXECUTABLE: ${NetCDF_${_comp}_CONFIG_EXECUTABLE}") +endforeach() + +set(_C_libs_flag --libs) +set(_Fortran_libs_flag --flibs) +set(_CXX_libs_flag --libs) +set(_C_includes_flag --includedir) +set(_Fortran_includes_flag --includedir) +set(_CXX_includes_flag --includedir) +function(netcdf_config exec flag output_var) + set(${output_var} False PARENT_SCOPE) + if( exec ) + execute_process( COMMAND ${exec} ${flag} RESULT_VARIABLE _ret OUTPUT_VARIABLE _val) + if( _ret EQUAL 0 ) + string( STRIP ${_val} _val ) + set( ${output_var} ${_val} PARENT_SCOPE ) + endif() + endif() +endfunction() + +## Find libraries for each component +set( NetCDF_LIBRARIES ) +foreach( _comp IN LISTS _search_components ) + string( TOUPPER "${_comp}" _COMP ) + + find_library( NetCDF_${_comp}_LIBRARY + NAMES ${NetCDF_${_comp}_LIBRARY_NAME} + DOC "NetCDF ${_comp} library" + HINTS ${NetCDF_${_comp}_INCLUDE_DIRS} ${_search_hints} + PATH_SUFFIXES lib64 lib ../lib64 ../lib ../../lib64 ../../lib ) + mark_as_advanced( NetCDF_${_comp}_LIBRARY ) + get_filename_component(NetCDF_${_comp}_LIBRARY ${NetCDF_${_comp}_LIBRARY} ABSOLUTE) + set(NetCDF_${_comp}_LIBRARY ${NetCDF_${_comp}_LIBRARY} CACHE STRING "NetCDF ${_comp} library" FORCE) + message(DEBUG "NetCDF_${_comp}_LIBRARY: ${NetCDF_${_comp}_LIBRARY}") + + if( NetCDF_${_comp}_LIBRARY ) + if( NetCDF_${_comp}_LIBRARY MATCHES ".a$" ) + set( NetCDF_${_comp}_LIBRARY_SHARED FALSE ) + set( _library_type STATIC) + else() + list( APPEND NetCDF_LIBRARIES ${NetCDF_${_comp}_LIBRARY} ) + set( NetCDF_${_comp}_LIBRARY_SHARED TRUE ) + set( _library_type SHARED) + endif() + endif() + + #Use nc-config to set per-component LIBRARIES variable if possible + netcdf_config( ${NetCDF_${_comp}_CONFIG_EXECUTABLE} ${_${_comp}_libs_flag} _val ) + if( _val ) + set( NetCDF_${_comp}_LIBRARIES ${_val} ) + if(NOT NetCDF_${_comp}_LIBRARY_SHARED AND NOT NetCDF_${_comp}_FOUND) #Static targets should use nc_config to get a proper link line with all necessary static targets. + list( APPEND NetCDF_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + endif() + else() + set( NetCDF_${_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARY} ) + if(NOT NetCDF_${_comp}_LIBRARY_SHARED) + message(SEND_ERROR "Unable to properly find NetCDF. Found static libraries at: ${NetCDF_${_comp}_LIBRARY} but could not run nc-config: ${NetCDF_CONFIG_EXECUTABLE}") + endif() + endif() + + #Use nc-config to set per-component INCLUDE_DIRS variable if possible + netcdf_config( ${NetCDF_${_comp}_CONFIG_EXECUTABLE} ${_${_comp}_includes_flag} _val ) + if( _val ) + string( REPLACE " " ";" _val ${_val} ) + set( NetCDF_${_comp}_INCLUDE_DIRS ${_val} ) + else() + set( NetCDF_${_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIR} ) + endif() + + if( NetCDF_${_comp}_LIBRARIES AND NetCDF_${_comp}_INCLUDE_DIRS ) + set( ${CMAKE_FIND_PACKAGE_NAME}_${_arg_${_COMP}}_FOUND TRUE ) + if (NOT TARGET NetCDF::NetCDF_${_comp}) + add_library(NetCDF::NetCDF_${_comp} ${_library_type} IMPORTED) + set_target_properties(NetCDF::NetCDF_${_comp} PROPERTIES + IMPORTED_LOCATION ${NetCDF_${_comp}_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES "${NetCDF_${_comp}_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + endif() + endif() +endforeach() +if(NetCDF_LIBRARIES AND NetCDF_${_comp}_LIBRARY_SHARED) + list(REMOVE_DUPLICATES NetCDF_LIBRARIES) +endif() +set(NetCDF_LIBRARIES "${NetCDF_LIBRARIES}" CACHE STRING "NetCDF library targets" FORCE) + +## Find version via netcdf-config if possible +if (NetCDF_INCLUDE_DIRS) + if( NetCDF_C_CONFIG_EXECUTABLE ) + netcdf_config( ${NetCDF_C_CONFIG_EXECUTABLE} --version _vers ) + if( _vers ) + string(REGEX REPLACE ".* ((([0-9]+)\\.)+([0-9]+)).*" "\\1" NetCDF_VERSION "${_vers}" ) + endif() + else() + foreach( _dir IN LISTS NetCDF_INCLUDE_DIRS) + if( EXISTS "${_dir}/netcdf_meta.h" ) + file(STRINGS "${_dir}/netcdf_meta.h" _netcdf_version_lines + REGEX "#define[ \t]+NC_VERSION_(MAJOR|MINOR|PATCH|NOTE)") + string(REGEX REPLACE ".*NC_VERSION_MAJOR *\([0-9]*\).*" "\\1" _netcdf_version_major "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_MINOR *\([0-9]*\).*" "\\1" _netcdf_version_minor "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_PATCH *\([0-9]*\).*" "\\1" _netcdf_version_patch "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_NOTE *\"\([^\"]*\)\".*" "\\1" _netcdf_version_note "${_netcdf_version_lines}") + set(NetCDF_VERSION "${_netcdf_version_major}.${_netcdf_version_minor}.${_netcdf_version_patch}${_netcdf_version_note}") + unset(_netcdf_version_major) + unset(_netcdf_version_minor) + unset(_netcdf_version_patch) + unset(_netcdf_version_note) + unset(_netcdf_version_lines) + endif() + endforeach() + endif() +endif () + +## Detect additional package properties +netcdf_config(${NetCDF_C_CONFIG_EXECUTABLE} --has-parallel4 _val) +if( NOT _val MATCHES "^(yes|no)$" ) + netcdf_config(${NetCDF_C_CONFIG_EXECUTABLE} --has-parallel _val) +endif() +if( _val MATCHES "^(yes)$" ) + set(NetCDF_PARALLEL TRUE CACHE STRING "NetCDF has parallel IO capability via pnetcdf or hdf5." FORCE) +else() + set(NetCDF_PARALLEL FALSE CACHE STRING "NetCDF has no parallel IO capability." FORCE) +endif() + +## Finalize find_package +include(FindPackageHandleStandardArgs) + +if(NOT NetCDF_FOUND OR _new_search_components) + find_package_handle_standard_args( ${CMAKE_FIND_PACKAGE_NAME} + REQUIRED_VARS NetCDF_INCLUDE_DIRS NetCDF_LIBRARIES + VERSION_VAR NetCDF_VERSION + HANDLE_COMPONENTS ) +endif() + +foreach( _comp IN LISTS _search_components ) + if( NetCDF_${_comp}_FOUND ) + #Record found components to avoid duplication in NetCDF_LIBRARIES for static libraries + set(NetCDF_${_comp}_FOUND ${NetCDF_${_comp}_FOUND} CACHE BOOL "NetCDF ${_comp} Found" FORCE) + #Set a per-package, per-component found variable to communicate between multiple calls to find_package() + set(${PROJECT_NAME}_NetCDF_${_comp}_FOUND True) + endif() +endforeach() + +if( ${CMAKE_FIND_PACKAGE_NAME}_FOUND AND NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY AND _new_search_components) + message( STATUS "Find${CMAKE_FIND_PACKAGE_NAME} defines targets:" ) + message( STATUS " - NetCDF_VERSION [${NetCDF_VERSION}]") + message( STATUS " - NetCDF_PARALLEL [${NetCDF_PARALLEL}]") + foreach( _comp IN LISTS _new_search_components ) + string( TOUPPER "${_comp}" _COMP ) + message( STATUS " - NetCDF_${_comp}_CONFIG_EXECUTABLE [${NetCDF_${_comp}_CONFIG_EXECUTABLE}]") + if( ${CMAKE_FIND_PACKAGE_NAME}_${_arg_${_COMP}}_FOUND ) + get_filename_component(_root ${NetCDF_${_comp}_INCLUDE_DIR}/.. ABSOLUTE) + if( NetCDF_${_comp}_LIBRARY_SHARED ) + message( STATUS " - NetCDF::NetCDF_${_comp} [SHARED] [Root: ${_root}] Lib: ${NetCDF_${_comp}_LIBRARY} ") + else() + message( STATUS " - NetCDF::NetCDF_${_comp} [STATIC] [Root: ${_root}] Lib: ${NetCDF_${_comp}_LIBRARY} ") + endif() + endif() + endforeach() +endif() + +foreach( _prefix NetCDF NetCDF4 NETCDF NETCDF4 ${CMAKE_FIND_PACKAGE_NAME} ) + set( ${_prefix}_INCLUDE_DIRS ${NetCDF_INCLUDE_DIRS} ) + set( ${_prefix}_LIBRARIES ${NetCDF_LIBRARIES}) + set( ${_prefix}_VERSION ${NetCDF_VERSION} ) + set( ${_prefix}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_FOUND} ) + set( ${_prefix}_CONFIG_EXECUTABLE ${NetCDF_CONFIG_EXECUTABLE} ) + set( ${_prefix}_PARALLEL ${NetCDF_PARALLEL} ) + + foreach( _comp ${_search_components} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_comp ${_arg_${_COMP}} ) + set( ${_prefix}_${_comp}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + set( ${_prefix}_${_COMP}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + set( ${_prefix}_${_arg_comp}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + + set( ${_prefix}_${_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + set( ${_prefix}_${_COMP}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + set( ${_prefix}_${_arg_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + + set( ${_prefix}_${_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + set( ${_prefix}_${_COMP}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + set( ${_prefix}_${_arg_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + endforeach() +endforeach() diff --git a/configuration/scripts/cmake/FindPIO.cmake b/configuration/scripts/cmake/FindPIO.cmake new file mode 100644 index 000000000..37d6d31f4 --- /dev/null +++ b/configuration/scripts/cmake/FindPIO.cmake @@ -0,0 +1,209 @@ +# FindPIO.cmake +# +# Copyright UCAR 2020 +# Copyright NOAA/NWS/NCEP/EMC 2020 +# +# Find PIO: A high-level Parallel I/O Library for structured grid applications +# https://github.com/NCAR/ParallelIO +# +# Components available for query: +# C - Has C support +# Fortran - Has Fortran support +# SHARED - Has shared targets +# STATIC - Has static targets +# +# Variables provided: +# PIO_FOUND - True if PIO was found +# PIO_C_FOUND - True if PIO C support was found +# PIO_Fortran_FOUND - True if PIO Fortran support was found +# PIO_VERSION - Version of installed PIO +# +# Targets provided: +# PIO::PIO_C - C interface target aliased to SHARED|STATIC as requested or to shared libraries if available else static libraries +# PIO::PIO_Fortran - Fortran interface target aliases to SHARED|STATIC as requested or to shared libraries if available else static libraries +# +# To control finding of this package, set PIO_ROOT environment variable to the full path to the prefix +# under which PIO was installed (e.g., /usr/local) + +set( _search_components ) +set( _search_library_type ) +foreach( _comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS} ) + if( _comp MATCHES "^(STATIC|SHARED)$" ) + list( APPEND _search_library_type ${_comp} ) + else() + list( APPEND _search_components ${_comp} ) + endif() +endforeach() +set( ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS ${_search_components} ) + +# If no COMPONENTS are requested, seach both C and Fortran +if( NOT _search_components ) + list( APPEND _search_components C Fortran ) +endif() + +# Ensure there is only one type of library being requested +if( _search_library_type ) + list( LENGTH _search_library_type _len) + if( _len GREATER 1 ) + message(FATAL_ERROR "User requesting both STATIC and SHARED is not permissible") + endif() + unset(_len) +endif() + +## Find libraries and paths, and determine found components +find_path(PIO_INCLUDE_DIR NAMES pio.h HINTS "${PIO_PREFIX}" PATH_SUFFIXES include include/pio) +if(PIO_INCLUDE_DIR) + string(REGEX REPLACE "/include(/.+)?" "" PIO_PREFIX ${PIO_INCLUDE_DIR}) + set(PIO_PREFIX ${PIO_PREFIX} CACHE STRING "") + find_path(PIO_MODULE_DIR NAMES pio.mod PATHS "${PIO_PREFIX}" + PATH_SUFFIXES include include/pio lib/pio/module module module/pio NO_DEFAULT_PATH) + if(APPLE) + set(_SHARED_LIB_EXT dylib) + else() + set(_SHARED_LIB_EXT so) + endif() + find_library(PIO_C_STATIC_LIB libpioc.a PATHS "${PIO_PREFIX}" PATH_SUFFIXES lib lib64 NO_DEFAULT_PATH) + find_library(PIO_C_SHARED_LIB libpioc.${_SHARED_LIB_EXT} PATHS "${PIO_PREFIX}" PATH_SUFFIXES lib lib64 NO_DEFAULT_PATH) + find_library(PIO_Fortran_STATIC_LIB libpiof.a PATHS "${PIO_PREFIX}" PATH_SUFFIXES lib lib64 NO_DEFAULT_PATH) + find_library(PIO_Fortran_SHARED_LIB libpiof.${_SHARED_LIB_EXT} PATHS "${PIO_PREFIX}" PATH_SUFFIXES lib lib64 NO_DEFAULT_PATH) + unset(_SHARED_LIB_EXT) + #Check for Fortran components + if(PIO_MODULE_DIR) + if(PIO_Fortran_STATIC_LIB) + set(PIO_Fortran_STATIC_FOUND 1) + endif() + if(PIO_Fortran_SHARED_LIB) + set(PIO_Fortran_SHARED_FOUND 1) + endif() + endif() + #Check for C components + if(PIO_C_STATIC_LIB) + set(PIO_C_STATIC_FOUND 1) + endif() + if(PIO_C_SHARED_LIB) + set(PIO_C_SHARED_FOUND 1) + endif() +endif() +## Debugging output +message(DEBUG "[FindPIO] PIO_INCLUDE_DIR: ${PIO_INCLUDE_DIR}") +message(DEBUG "[FindPIO] PIO_PREFIX: ${PIO_PREFIX}") +message(DEBUG "[FindPIO] PIO_MODULE_DIR: ${PIO_MODULE_DIR}") +message(DEBUG "[FindPIO] PIO_C_STATIC_LIB: ${PIO_C_STATIC_LIB}") +message(DEBUG "[FindPIO] PIO_C_SHARED_LIB: ${PIO_C_SHARED_LIB}") +message(DEBUG "[FindPIO] PIO_C_SHARED_FOUND: ${PIO_C_SHARED_FOUND}") +message(DEBUG "[FindPIO] PIO_C_STATIC_FOUND: ${PIO_C_STATIC_FOUND}") +message(DEBUG "[FindPIO] PIO_Fortran_STATIC_LIB: ${PIO_Fortran_STATIC_LIB}") +message(DEBUG "[FindPIO] PIO_Fortran_SHARED_LIB: ${PIO_Fortran_SHARED_LIB}") +message(DEBUG "[FindPIO] PIO_Fortran_SHARED_FOUND: ${PIO_Fortran_SHARED_FOUND}") +message(DEBUG "[FindPIO] PIO_Fortran_STATIC_FOUND: ${PIO_Fortran_STATIC_FOUND}") + +## Create targets +set(_new_components) +# PIO_C_STATIC imported interface target +if(PIO_C_STATIC_FOUND AND NOT TARGET PIO_C_STATIC) + add_library(PIO_C_STATIC INTERFACE IMPORTED) + set_target_properties(PIO_C_STATIC PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${PIO_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES ${PIO_C_STATIC_LIB} + IMPORTED_GLOBAL True ) + set(_new_components 1) +endif() +# PIO_C_SHARED imported interface target +if(PIO_C_SHARED_FOUND AND NOT TARGET PIO_C_SHARED) + add_library(PIO_C_SHARED INTERFACE IMPORTED) + set_target_properties(PIO_C_SHARED PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${PIO_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES ${PIO_C_SHARED_LIB} + IMPORTED_GLOBAL True ) + set(_new_components 1) +endif() +# PIO_Fortran_STATIC imported interface target +if(PIO_Fortran_STATIC_FOUND AND NOT TARGET PIO_Fortran_STATIC) + add_library(PIO_Fortran_STATIC INTERFACE IMPORTED) + set_target_properties(PIO_Fortran_STATIC PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${PIO_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES ${PIO_Fortran_STATIC_LIB} + IMPORTED_GLOBAL True ) + if(PIO_MODULE_DIR AND NOT PIO_MODULE_DIR STREQUAL PIO_INCLUDE_DIR ) + set_property(TARGET PIO_Fortran_STATIC APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PIO_MODULE_DIR}) + endif() + set(_new_components 1) + target_link_libraries(PIO_Fortran_STATIC INTERFACE PIO_C_STATIC) +endif() +# PIO_Fortran_SHARED imported interface target +if(PIO_Fortran_SHARED_FOUND AND NOT TARGET PIO_Fortran_SHARED) + add_library(PIO_Fortran_SHARED INTERFACE IMPORTED) + set_target_properties(PIO_Fortran_SHARED PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${PIO_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES ${PIO_Fortran_SHARED_LIB} + IMPORTED_GLOBAL True ) + if(PIO_MODULE_DIR AND NOT PIO_MODULE_DIR STREQUAL PIO_INCLUDE_DIR ) + set_property(TARGET PIO_Fortran_SHARED APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PIO_MODULE_DIR}) + endif() + target_link_libraries(PIO_Fortran_SHARED INTERFACE PIO_C_SHARED) + set(_new_components 1) +endif() + +if( _search_library_type MATCHES "^(SHARED)$" ) + if( TARGET PIO_C_SHARED ) + add_library(PIO::PIO_C ALIAS PIO_C_SHARED) + set(PIO_C_FOUND 1) + endif() + if( TARGET PIO_Fortran_SHARED ) + add_library(PIO::PIO_Fortran ALIAS PIO_Fortran_SHARED) + set(PIO_Fortran_FOUND 1) + endif() +elseif( _search_library_type MATCHES "^(STATIC)$" ) + if( TARGET PIO_C_STATIC ) + add_library(PIO::PIO_C ALIAS PIO_C_STATIC) + set(PIO_C_FOUND 1) + endif() + if( TARGET PIO_Fortran_STATIC ) + add_library(PIO::PIO_Fortran ALIAS PIO_Fortran_STATIC) + set(PIO_Fortran_FOUND 1) + endif() +else() + if( TARGET PIO_C_SHARED ) + add_library(PIO::PIO_C ALIAS PIO_C_SHARED) + set(PIO_C_FOUND 1) + elseif( TARGET PIO_C_STATIC ) + add_library(PIO::PIO_C ALIAS PIO_C_STATIC) + set(PIO_C_FOUND 1) + endif() + if( TARGET PIO_Fortran_SHARED ) + add_library(PIO::PIO_Fortran ALIAS PIO_Fortran_SHARED) + set(PIO_Fortran_FOUND 1) + elseif( TARGET PIO_Fortran_STATIC ) + add_library(PIO::PIO_Fortran ALIAS PIO_Fortran_STATIC) + set(PIO_Fortran_FOUND 1) + endif() +endif() + +## Check package has been found correctly +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + PIO + REQUIRED_VARS + PIO_PREFIX + PIO_INCLUDE_DIR + HANDLE_COMPONENTS +) +message(DEBUG "[FindPIO] PIO_FOUND: ${PIO_FOUND}") + +## Print status +if(${CMAKE_FIND_PACKAGE_NAME}_FOUND AND NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY AND _new_components) + message( STATUS "Find${CMAKE_FIND_PACKAGE_NAME}:" ) + message( STATUS " - ${CMAKE_FIND_PACKAGE_NAME}_PREFIX [${${CMAKE_FIND_PACKAGE_NAME}_PREFIX}]") + set(_found_comps) + foreach( _comp ${_search_components} ) + if( ${CMAKE_FIND_PACKAGE_NAME}_${_comp}_FOUND ) + list(APPEND _found_comps ${_comp}) + endif() + endforeach() + message( STATUS " - ${CMAKE_FIND_PACKAGE_NAME} Components Found: ${_found_comps}") + unset(_found_comps) +endif() +unset(_new_components) +unset(_search_components) +unset(_search_library_type) +unset(_library_type) diff --git a/configuration/scripts/cmake/FortranLib.cmake b/configuration/scripts/cmake/FortranLib.cmake new file mode 100644 index 000000000..6eaec978b --- /dev/null +++ b/configuration/scripts/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)