diff --git a/ESMF_HelloWorld_CMake/CMakeLists.txt b/ESMF_HelloWorld_CMake/CMakeLists.txt index 381877b..0a831e2 100644 --- a/ESMF_HelloWorld_CMake/CMakeLists.txt +++ b/ESMF_HelloWorld_CMake/CMakeLists.txt @@ -1,27 +1,36 @@ -cmake_minimum_required(VERSION 3.12) -enable_language(Fortran) +################################################################################ +# Configuration step: cmake -S . -B ./build +# Build step: cmake --build ./build -v +# Execution step: mpirun -np 8 ./build/ESMF_HelloWorld +# Clean-up step: rm -rf ./build PET* +################################################################################ -# Project -project(ESMF_HelloWorld_CMake) -add_executable(ESMF_HelloWorld ESMF_HelloWorld.F90) +cmake_minimum_required(VERSION 3.22) -# Where to look for Find.cmake files +# Where to look for the local Find.cmake files list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # Find ESMF -find_package(ESMF REQUIRED) +find_package(ESMF 8.3.0 MODULE REQUIRED) -# Project depends on ESMF -target_link_libraries(ESMF_HelloWorld ESMF) +# Set compilers consistent with ESMF +set(CMAKE_Fortran_COMPILER "${ESMF_F90COMPILER}") +set(CMAKE_CXX_COMPILER "${ESMF_CXXCOMPILER}") +set(CMAKE_C_COMPILER "${ESMF_CCOMPILER}") -# Set compilers per ESMFMKFILE -set(CMAKE_CXX_COMPILER ${ESMF_CXXCOMPILER}) -set(CMAKE_Fortran_COMPILER ${ESMF_F90LINKER}) +# Optionally set compiler options consistent with ESMF +set(CMAKE_Fortran_FLAGS "${ESMF_F90COMPILEOPTS}") +set(CMAKE_CXX_FLAGS "${ESMF_CXXCOMPILEOPTS}") +set(CMAKE_C_FLAGS "${ESMF_CCOMPILEOPTS}") -# Diagnostic output -get_filename_component (Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME) -message("------------------------------------") -message("Fortran compiler: ${CMAKE_Fortran_COMPILER_ID} ${CMAKE_Fortran_COMPILER_VERSION} (${Fortran_COMPILER_NAME})") -message("------------------------------------") +# Project +project(ESMF_HelloWorld_CMake + VERSION 1.0 + LANGUAGES Fortran CXX C + ) +# Executable +add_executable(ESMF_HelloWorld ESMF_HelloWorld.F90) +# Executable depends on ESMF +target_link_libraries(ESMF_HelloWorld ESMF) diff --git a/ESMF_HelloWorld_CMake/ESMF_HelloWorld.F90 b/ESMF_HelloWorld_CMake/ESMF_HelloWorld.F90 index 3e46235..c19aa99 100644 --- a/ESMF_HelloWorld_CMake/ESMF_HelloWorld.F90 +++ b/ESMF_HelloWorld_CMake/ESMF_HelloWorld.F90 @@ -1,26 +1,27 @@ ! Earth System Modeling Framework -! Copyright 2002-2021, University Corporation for Atmospheric Research, +! Copyright (c) 2002-2023, 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. ! Licensed under the University of Illinois-NCSA License. -program esmf_application +program ESMF_HelloWorld ! modules use ESMF - + implicit none - + ! local variables - integer:: rc - + integer :: rc + call ESMF_Initialize(rc=rc) if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) - - print *, "Hello ESMF World" - call ESMF_Finalize() - + call ESMF_LogWrite(">>> Hello ESMF World <<<", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_Finalize(rc=rc) + end program diff --git a/ESMF_HelloWorld_CMake/README b/ESMF_HelloWorld_CMake/README deleted file mode 100644 index 08631f6..0000000 --- a/ESMF_HelloWorld_CMake/README +++ /dev/null @@ -1,21 +0,0 @@ -ESMF_HelloWorld README ---------------- ------ - -This directory contains code that is based on the ESMF Fortran API. - -The application prints "Hello ESMF World" to stdout. The code is accompanied -by CMakeLists.txt and cmake/FindESMF.cmake files. It builds using the typical -CMake procedure: - -mkdir build; cd build -cmake .. -make - -The FindESMF.cmake file depends on environment variable ESMFMKFILE being set -according to the instructions given in the ESMF User's Guide. - -NOTE: -The executable should be run according to the system-specific procedures that -apply to the execution of binaries. The correct procedure may depend on whether -the executable was built against an mpiuni- or mpi-based ESMF library -installation. diff --git a/ESMF_HelloWorld_CMake/README.md b/ESMF_HelloWorld_CMake/README.md new file mode 100644 index 0000000..54aa78b --- /dev/null +++ b/ESMF_HelloWorld_CMake/README.md @@ -0,0 +1,33 @@ +ESMF_HelloWorld_CMake +===================== + +This directory contains code that is based on the ESMF Fortran API. + +The application writes ">>> Hello ESMF World <<<" to the ESMF default log (see PET*.ESMF_LogFile's). + +The main purpose of this example is to demonstrate the use of CMake for ESMF applications. The code is accompanied by `CMakeLists.txt` and `cmake/FindESMF.cmake` files. + +Notice the dependency of the example on a relatively recent release of CMake: version 3.22. This is specified in file `CMakeLists.txt`. The primary reason for this restictive dependency is that not until version 3.22 was it supported to use the `find_package()` and `set()` functions before `project()`. Hence it was more difficult in the older versions to specified the compilers consistent with those used by ESMF. + +Notice that it is possible to get the desired end result with previous versions of CMake, requiring some re-arranging of the order of functions in `CMakeLists.txt`. However, the more recently supported order of functions leads to a simpler and more intuitive version of `CMakeLists.txt` file shown here. + +The code can be built using any of the usual CMake build procedures: + + mkdir build; cd build + cmake .. + make + +or alternatively using the `-S`, `-B`, and `--build` CMake options: + + cmake -S . -B ./build + cmake --build ./build + +And execute on 8 PETs, e.g. via mpirun: + + mpirun -np 8 ./build/ESMF_HelloWorld + +================================================================================ + +Please contact esmf_support@ucar.edu with any questions or problems. + +================================================================================ diff --git a/ESMF_HelloWorld_CMake/cmake/FindESMF.cmake b/ESMF_HelloWorld_CMake/cmake/FindESMF.cmake index e86b7e9..1616544 100644 --- a/ESMF_HelloWorld_CMake/cmake/FindESMF.cmake +++ b/ESMF_HelloWorld_CMake/cmake/FindESMF.cmake @@ -78,14 +78,14 @@ if(EXISTS ${ESMFMKFILE}) set(ESMF_BETA_RELEASE FALSE) if(ESMF_VERSION_BETASNAPSHOT MATCHES "^('T')$") set(ESMF_BETA_RELEASE TRUE) - if(ESMF_VERSION_STRING_GIT MATCHES "^ESMF.*beta_snapshot_[0-9]") - string(REGEX REPLACE "^ESMF.*beta_snapshot_\([0-9]*\).*" "\\1" ESMF_BETA_SNAPSHOT "${ESMF_VERSION_STRING_GIT}") - elseif(ESMF_VERSION_STRING_GIT MATCHES "^v.*b[0-9]") - string(REGEX REPLACE "^v.*b\([0-9]*\).*" "\\1" ESMF_BETA_SNAPSHOT "${ESMF_VERSION_STRING_GIT}") + 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}") + message(STATUS "Detected ESMF Beta snapshot: ${ESMF_BETA_SNAPSHOT}") endif() set(ESMF_VERSION "${ESMF_VERSION_MAJOR}.${ESMF_VERSION_MINOR}.${ESMF_VERSION_PATCH}") @@ -107,14 +107,14 @@ if(EXISTS ${ESMFMKFILE}) # Add ESMF include directories set(ESMF_INCLUDE_DIRECTORIES "") - separate_arguments(_ESMF_F90COMPILEPATHS NATIVE_COMMAND ${ESMF_F90COMPILEPATHS}) + 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() # Add ESMF link libraries - string(STRIP "${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES) + string(STRIP "${ESMF_F90LINKRPATHS} ${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES) # Finalize find_package include(FindPackageHandleStandardArgs)