Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using find_package() in FindBaselibs to support generic build environments #29

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 68 additions & 87 deletions FindBaselibs.cmake
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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=<path>.")
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} CONFIG)
# 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)
105 changes: 105 additions & 0 deletions FindESMF.cmake
Original file line number Diff line number Diff line change
@@ -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()
23 changes: 23 additions & 0 deletions FindGFTL.cmake
Original file line number Diff line number Diff line change
@@ -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()
6 changes: 4 additions & 2 deletions esma.cmake
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -75,7 +77,7 @@ if (APPLE)
endif ()
endif ()
else ()
find_package (MKL REQUIRED)
find_package (MKL ${MKL_IS_REQUIRED_ARG})
endif ()

# Unit testing
Expand Down