From 517b366045bf4d73b18f3ee21ca060de850b50a3 Mon Sep 17 00:00:00 2001 From: Liam Bindle Date: Wed, 7 Aug 2019 10:36:07 -0300 Subject: [PATCH 1/2] Changes s.t. esma.cmake can be loaded in generic build environments. Changed FindBaselibs.cmake to use find_package() calls rather than hardcoded paths relative to BASEDIR. Added find-modules for ESMF, GFTL, and FLAP. Added mechanism for disabling the requiredness of ESMA dependencies. --- FindBaselibs.cmake | 155 ++++++++++++++++++++------------------------- FindESMF.cmake | 105 ++++++++++++++++++++++++++++++ FindFLAP.cmake | 29 +++++++++ FindGFTL.cmake | 23 +++++++ esma.cmake | 6 +- 5 files changed, 229 insertions(+), 89 deletions(-) mode change 100644 => 100755 FindBaselibs.cmake create mode 100755 FindESMF.cmake create mode 100755 FindFLAP.cmake create mode 100755 FindGFTL.cmake mode change 100644 => 100755 esma.cmake diff --git a/FindBaselibs.cmake b/FindBaselibs.cmake old mode 100644 new mode 100755 index 1442074e..9696a2ee --- a/FindBaselibs.cmake +++ b/FindBaselibs.cmake @@ -1,106 +1,87 @@ + +# Set BASEDIR to non-existant path if it is not already set set (BASEDIR /does-not-exist CACHE PATH "Path to installed baselibs _including_ OS subdirectory (Linux or Darwin).") -if (NOT EXISTS ${BASEDIR}) +# If BASEDIR evaluates to TRUE but it isn't a valid path throw an error +# This lets BASEDIR be skipped if BASEDIR is set to a false value (e.g. setting BASEDIR to IGNORE) +if (BASEDIR AND NOT EXISTS ${BASEDIR}) message (FATAL_ERROR "ERROR: Must specify a value for BASEDIR with cmake ... -DBASEDIR=.") +elseif(EXISTS ${BASEDIR}) + # Add path to GFE packages + list (APPEND CMAKE_PREFIX_PATH ${BASEDIR} + + # Add BASEDIR's include directories + ${BASEDIR}/include/netcdf + ${BASEDIR}/include/hdf5 + ${BASEDIR}/include/hdf + ${BASEDIR}/include/esmf + ${BASEDIR}/include/FLAP + ) endif () if (ESMA_SDF) message (FATAL_ERROR "ERROR: -hdf option was thought to be obsolete when CMake was crafted.") endif () -link_directories (${BASEDIR}/lib) - -# Add path to GFE packages -list (APPEND CMAKE_PREFIX_PATH ${BASEDIR}) - -#------------------------------------------------------------------ -# netcdf -# The following command provides the list of libraries that netcdf -# uses. Unfortunately it also includes the library path and "-l" -# prefixes, which CMake handles in a different manner. So we need so -# strip off that item from the list -execute_process ( - COMMAND ${BASEDIR}/bin/nf-config --flibs - OUTPUT_VARIABLE LIB_NETCDF - ) - -string(REGEX MATCHALL " -l[^ ]*" _full_libs "${LIB_NETCDF}") -set (NETCDF_LIBRARIES_OLD) -foreach (lib ${_full_libs}) - string (REPLACE "-l" "" _tmp ${lib}) - string (STRIP ${_tmp} _tmp) - list (APPEND NETCDF_LIBRARIES_OLD ${_tmp}) -endforeach() - -list (REVERSE NETCDF_LIBRARIES_OLD) -list (REMOVE_DUPLICATES NETCDF_LIBRARIES_OLD) -list (REVERSE NETCDF_LIBRARIES_OLD) - +# Find NetCDF +find_package(NetCDF REQUIRED COMPONENTS C Fortran) +# Set expected definitions add_definitions(-DHAS_NETCDF4) add_definitions(-DHAS_NETCDF3) add_definitions(-DH5_HAVE_PARALLEL) add_definitions(-DNETCDF_NEED_NF_MPIIO) add_definitions(-DHAS_NETCDF3) -#------------------------------------------------------------------ - -set (INC_HDF5 ${BASEDIR}/include/hdf5) -set (INC_NETCDF ${BASEDIR}/include/netcdf) -set (INC_HDF ${BASEDIR}/include/hdf) -set (INC_ESMF ${BASEDIR}/include/esmf) - +# Set non-standard expected variables +set(INC_NETCDF ${NETCDF_INCLUDE_DIRS}) +set(LIB_NETCDF ${NETCDF_LIBRARIES}) + +# If BASEDIR exists, set the expected HDF and HDF5 variables +if(EXISTS ${BASEDIR}/include/hdf5) + set (INC_HDF5 ${BASEDIR}/include/hdf5) +endif() +if(EXISTS ${BASEDIR}/include/hdf) + set (INC_HDF ${BASEDIR}/include/hdf) +endif() + +# Find GFTL find_package(GFTL REQUIRED) -find_package(GFTL_SHARED) -find_package(FARGPARSE) - -set (INC_FLAP ${BASEDIR}/include/FLAP) -set (LIB_FLAP ${BASEDIR}/lib/libflap.a) -if (NOT EXISTS ${INC_FLAP}) - message (FATAL_ERROR "FLAP directory, ${INC_FLAP} does not exist.") -endif () - -if (APPLE) - if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - execute_process (COMMAND ${CMAKE_C_COMPILER} --print-file-name=libgcc.a OUTPUT_VARIABLE libgcc OUTPUT_STRIP_TRAILING_WHITESPACE) - endif () - execute_process (COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=libstdc++.dylib OUTPUT_VARIABLE stdcxx OUTPUT_STRIP_TRAILING_WHITESPACE) -else () - execute_process (COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=libstdc++.so OUTPUT_VARIABLE stdcxx OUTPUT_STRIP_TRAILING_WHITESPACE) -endif () - -# For OS X - use the gcc stdc++ library - not clang -#find_library (STDCxx -# stdc++ -# HINTS "/opt/local/lib/gcc5" -# ) - -# We must statically link ESMF on Apple due mainly to an issue with how Baselibs is built. -# Namely, the esmf dylib libraries end up with the full *build* path on Darwin (which is in -# src/esmf/lib/libO...) But we copy the dylib to $BASEDIR/lib. Thus, DYLD_LIBRARY_PATH gets -# hosed. yay. - -if (APPLE) - set (ESMF_LIBRARY ${BASEDIR}/lib/libesmf.a) -else () - set (ESMF_LIBRARY esmf_fullylinked) -endif () - -#find_package (NetCDF REQUIRED COMPONENTS Fortran) -#set (INC_NETCDF ${NETCDF_INCLUDE_DIRS}) - -set (NETCDF_LIBRARIES ${NETCDF_LIBRARIES_OLD}) -set (ESMF_LIBRARIES ${ESMF_LIBRARY} ${NETCDF_LIBRARIES} ${MPI_Fortran_LIBRARIES} ${MPI_CXX_LIBRARIES} ${stdcxx} ${libgcc}) - +# Find GFTL_SHARED +set(GFTL_SHARED_IS_REQUIRED_ARG "" CACHE STRING "Argument in GFTL_SHARED's find_package call") +mark_as_advanced(GFTL_SHARED_IS_REQUIRED_ARG) +find_package(GFTL_SHARED ${GFTL_SHARED_IS_REQUIRED_ARG} CONFIG) + +# Find FARGPARSE +set(FARGPARSE_IS_REQUIRED_ARG "" CACHE STRING "Argument in FARGPARSE's find_package call") +mark_as_advanced(FARGPARSE_IS_REQUIRED_ARG) +find_package(FARGPARSE CONFIG) + +# Find FLAP +set(FLAP_IS_REQUIRED_ARG "REQUIRED" CACHE STRING "Argument in FLAP's find_package call") +mark_as_advanced(FLAP_IS_REQUIRED_ARG) +find_package(FLAP ${FLAP_IS_REQUIRED_ARG}) +# Set non-standard expected variables +set (INC_FLAP ${FLAP_INCLUDE_DIRS}) +set (LIB_FLAP ${FLAP_LIBRARIES}) + +# Find ESMF +find_package(ESMF REQUIRED) +# Set non-standard expected variables +set(INC_ESMF ${ESMF_INCLUDE_DIRS}) + +# Find MPI +find_package(MPI REQUIRED COMPONENTS C CXX Fortran) + +# Conditionally find PFUNIT if (PFUNIT) - set (PFUNIT_PATH ${BASEDIR}/pFUnit/pFUnit-mpi) - set (PFUNIT_LIBRARY_DIRS ${PFUNIT_PATH}/lib) - set (PFUNIT_LIBRARIES ${PFUNIT_PATH}/lib/libpfunit.a) - set (PFUNIT_INCLUDE_DIRS ${PFUNIT_PATH}/mod ${PFUNIT_PATH}/include) -endif () - -# BASEDIR.rc file does not have the arch -string(REPLACE "/${CMAKE_SYSTEM_NAME}" "" BASEDIR_WITHOUT_ARCH ${BASEDIR}) -set(BASEDIR_WITHOUT_ARCH ${BASEDIR_WITHOUT_ARCH} CACHE STRING "BASEDIR without arch") -mark_as_advanced(BASEDIR_WITHOUT_ARCH) + find_package(PFUNIT REQUIRED CONFIG) +endif() + +if(BASEDIR) + # BASEDIR.rc file does not have the arch + string(REPLACE "/${CMAKE_SYSTEM_NAME}" "" BASEDIR_WITHOUT_ARCH ${BASEDIR}) + set(BASEDIR_WITHOUT_ARCH ${BASEDIR_WITHOUT_ARCH} CACHE STRING "BASEDIR without arch") + mark_as_advanced(BASEDIR_WITHOUT_ARCH) +endif() # Set the site variable include(DetermineSite) diff --git a/FindESMF.cmake b/FindESMF.cmake new file mode 100755 index 00000000..df059069 --- /dev/null +++ b/FindESMF.cmake @@ -0,0 +1,105 @@ +function(append_globbed_directories VAR) + cmake_parse_arguments(ARGS + "" + "" + "PATTERNS;PATHS" + ${ARGN} + ) + set(MATCHED_LIST "") + foreach(PREFIX ${ARGS_PATHS}) + foreach(PATTERN ${ARGS_PATTERNS}) + if(IS_ABSOLUTE ${PREFIX}) + file(GLOB MATCHED ${PREFIX}/${PATTERN}) + else() + file(GLOB MATCHED ${CMAKE_BINARY_DIR}/${PREFIX}/${PATTERN}) + endif() + foreach(MATCHED_FILE ${MATCHED}) + get_filename_component(MATCHED_DIR ${MATCHED_FILE} DIRECTORY) + list(APPEND MATCHED_LIST ${MATCHED_DIR}) + endforeach() + endforeach() + endforeach() + if("${MATCHED_LIST}") + list(REMOVE_DUPLICATES MATCHED_LIST) + endif() + list(APPEND ${VAR} ${MATCHED_LIST}) + set(${VAR} ${${VAR}} PARENT_SCOPE) +endfunction() + +# Add globbed directories to CMAKE_PREFIX_PATH for upcoming find_paths +append_globbed_directories(CMAKE_PREFIX_PATH + PATTERNS + mod/mod*/*.*.*.*.*/esmf.mod + lib/lib*/*.*.*.*.*/libesmf.a + PATHS + ${CMAKE_PREFIX_PATH} +) + +# Find the installed ESMF files +find_path(ESMF_HEADERS_DIR + ESMC.h + DOC "The path to the directory containing \"ESMC.h\"." + PATH_SUFFIXES "include" +) + +find_path(ESMF_MOD_DIR + esmf.mod + DOC "The path to the directory containing \"esmf.mod\"." + PATH_SUFFIXES "mod" "include" +) + +find_library(ESMF_LIBRARY + libesmf.a + DOC "The path to the directory containing \"libesmf.a\"." + PATH_SUFFIXES "lib" +) + +# Get ESMF's versions number +if(EXISTS ${ESMF_HEADERS_DIR}/ESMC_Macros.h) + file(READ ${ESMF_HEADERS_DIR}/ESMC_Macros.h ESMC_MACROS) + if("${ESMC_MACROS}" MATCHES "#define[ \t]+ESMF_VERSION_MAJOR[ \t]+([0-9]+)") + set(ESMF_VERSION_MAJOR "${CMAKE_MATCH_1}") + endif() + if("${ESMC_MACROS}" MATCHES "#define[ \t]+ESMF_VERSION_MINOR[ \t]+([0-9]+)") + set(ESMF_VERSION_MINOR "${CMAKE_MATCH_1}") + endif() + if("${ESMC_MACROS}" MATCHES "#define[ \t]+ESMF_VERSION_REVISION[ \t]+([0-9]+)") + set(ESMF_VERSION_REVISION "${CMAKE_MATCH_1}") + endif() + set(ESMF_VERSION "${ESMF_VERSION_MAJOR}.${ESMF_VERSION_MINOR}.${ESMF_VERSION_REVISION}") +else() + set(ESMF_VERSION "NOTFOUND") +endif() + +# Throw an error if anything went wrong +find_package_handle_standard_args(ESMF + REQUIRED_VARS + ESMF_HEADERS_DIR + ESMF_MOD_DIR + ESMF_LIBRARY + VERSION_VAR ESMF_VERSION + FAIL_MESSAGE "${ESMF_ERRMSG}" +) + +# Specify the other libraries that need to be linked for ESMF +find_package(NetCDF REQUIRED) +find_package(MPI REQUIRED) +execute_process (COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=libstdc++.so OUTPUT_VARIABLE stdcxx OUTPUT_STRIP_TRAILING_WHITESPACE) +execute_process (COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=libgcc.a OUTPUT_VARIABLE libgcc OUTPUT_STRIP_TRAILING_WHITESPACE) +set(ESMF_LIBRARIES ${ESMF_LIBRARY} ${NETCDF_LIBRARIES} ${MPI_Fortran_LIBRARIES} ${MPI_CXX_LIBRARIES} rt ${stdcxx} ${libgcc}) +set(ESMF_INCLUDE_DIRS ${ESMF_HEADERS_DIR} ${ESMF_MOD_DIR}) + +# Make an imported target for ESMF +if(NOT TARGET ESMF) + add_library(ESMF STATIC IMPORTED) + set_target_properties(ESMF PROPERTIES + IMPORTED_LOCATION ${ESMF_LIBRARY} + ) + target_link_libraries(ESMF + INTERFACE + ${NETCDF_LIBRARIES} + ${MPI_Fortran_LIBRARIES} ${MPI_CXX_LIBRARIES} + rt ${stdcxx} ${libgcc} + ) + target_include_directories(ESMF INTERFACE ${ESMF_INCLUDE_DIRS}) +endif() diff --git a/FindFLAP.cmake b/FindFLAP.cmake new file mode 100755 index 00000000..b9a77d18 --- /dev/null +++ b/FindFLAP.cmake @@ -0,0 +1,29 @@ +#[[ FindFLAP.cmake + + This module finds where FLAP is installed. It sets the following + variables: + FLAP_INCLUDE_DIRS - FLAP's module directory + FLAP_LIBRARIES - The full path to libFLAP.a + +]] + +find_path(FLAP_INCLUDE_DIRS + flap.mod + PATH_SUFFIXES "include" "modules" +) + +find_library(FLAP_LIBRARIES + libFLAP.a + PATH_SUFFIXES "lib" +) + +find_package_handle_standard_args(FLAP + REQUIRED_VARS FLAP_INCLUDE_DIRS FLAP_LIBRARIES +) + +# Make an imported target for FLAP +if(NOT TARGET FLAP) + add_library(FLAP STATIC IMPORTED) + set_target_properties(FLAP IMPORTED_LOCATION ${FLAP_LIBRARIES}) + target_include_directories(FLAP INTERFACE ${FLAP_INCLUDE_DIRS}) +endif() \ No newline at end of file diff --git a/FindGFTL.cmake b/FindGFTL.cmake new file mode 100755 index 00000000..05169b28 --- /dev/null +++ b/FindGFTL.cmake @@ -0,0 +1,23 @@ +#[[ FindGFTL.cmake + + This module finds where gFTL is installed. It sets the following + variables: + GFTL_INCLUDE_DIRS - gFTL's include directory + +]] + +find_path(GFTL_INCLUDE_DIRS + types/key_deferredLengthString.inc + PATH_SUFFIXES "include" +) + +find_package_handle_standard_args(GFTL + REQUIRED_VARS GFTL_INCLUDE_DIRS +) + +# Make an imported target for GFTL +if(NOT TARGET gftl) + add_library(gftl INTERFACE) + target_include_directories(gftl INTERFACE ${GFTL_INCLUDE_DIRS}) + install(TARGETS gftl EXPORT MAPL-targets) +endif() \ No newline at end of file diff --git a/esma.cmake b/esma.cmake old mode 100644 new mode 100755 index a09c1773..0addc0fa --- a/esma.cmake +++ b/esma.cmake @@ -63,10 +63,12 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # But some BASEDIR packages use MPI from C/C++. find_package (MPI REQUIRED) +set(MKL_IS_REQUIRED_ARG "REQUIRED" CACHE STRING "Argument in MKL's find_package call") +mark_as_advanced(MKL_IS_REQUIRED_ARG) if (APPLE) if (DEFINED ENV{MKLROOT}) set (MKL_Fortran) - find_package (MKL REQUIRED) + find_package (MKL ${MKL_IS_REQUIRED_ARG}) else () if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU") #USE FRAMEWORK @@ -75,7 +77,7 @@ if (APPLE) endif () endif () else () - find_package (MKL REQUIRED) + find_package (MKL ${MKL_IS_REQUIRED_ARG}) endif () # Unit testing From b3222f52df70674cfb033e2844040a7ae12fc498 Mon Sep 17 00:00:00 2001 From: Liam Bindle Date: Mon, 30 Sep 2019 14:42:41 -0500 Subject: [PATCH 2/2] Removed FindFLAP.cmake since FLAP's build creates a FLAPConfig.cmake file --- FindBaselibs.cmake | 2 +- FindFLAP.cmake | 29 ----------------------------- 2 files changed, 1 insertion(+), 30 deletions(-) delete mode 100755 FindFLAP.cmake diff --git a/FindBaselibs.cmake b/FindBaselibs.cmake index 9696a2ee..4b4c54cb 100755 --- a/FindBaselibs.cmake +++ b/FindBaselibs.cmake @@ -58,7 +58,7 @@ find_package(FARGPARSE CONFIG) # Find FLAP set(FLAP_IS_REQUIRED_ARG "REQUIRED" CACHE STRING "Argument in FLAP's find_package call") mark_as_advanced(FLAP_IS_REQUIRED_ARG) -find_package(FLAP ${FLAP_IS_REQUIRED_ARG}) +find_package(FLAP ${FLAP_IS_REQUIRED_ARG} CONFIG) # Set non-standard expected variables set (INC_FLAP ${FLAP_INCLUDE_DIRS}) set (LIB_FLAP ${FLAP_LIBRARIES}) diff --git a/FindFLAP.cmake b/FindFLAP.cmake deleted file mode 100755 index b9a77d18..00000000 --- a/FindFLAP.cmake +++ /dev/null @@ -1,29 +0,0 @@ -#[[ FindFLAP.cmake - - This module finds where FLAP is installed. It sets the following - variables: - FLAP_INCLUDE_DIRS - FLAP's module directory - FLAP_LIBRARIES - The full path to libFLAP.a - -]] - -find_path(FLAP_INCLUDE_DIRS - flap.mod - PATH_SUFFIXES "include" "modules" -) - -find_library(FLAP_LIBRARIES - libFLAP.a - PATH_SUFFIXES "lib" -) - -find_package_handle_standard_args(FLAP - REQUIRED_VARS FLAP_INCLUDE_DIRS FLAP_LIBRARIES -) - -# Make an imported target for FLAP -if(NOT TARGET FLAP) - add_library(FLAP STATIC IMPORTED) - set_target_properties(FLAP IMPORTED_LOCATION ${FLAP_LIBRARIES}) - target_include_directories(FLAP INTERFACE ${FLAP_INCLUDE_DIRS}) -endif() \ No newline at end of file