Commit 9bb3b803 authored by Coon, Ethan's avatar Coon, Ethan
Browse files

updates cmake to support find_package NetCDF

parent 40df2f7b
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.13.3)
project(ELM_physics)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
enable_testing()
project(ELM_physics CXX)
# need netcdf
list(APPEND CMAKE_MODULE_PATH "${ELM_physics_SOURCE_DIR}/config/cmake")
include(AddImportedLibrary)
if (BUILD_SHARED_LIBS)
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_SKIP_INSTALL_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_RPATH}")
else()
SET(CMAKE_SKIP_INSTALL_RPATH ON CACHE BOOL "Turn off for static install." FORCE)
SET(CMAKE_SKIP_RPATH ON CACHE BOOL "Turn off for static install." FORCE)
endif()
find_package(NetCDF REQUIRED)
message("Found NetCDF = ${NetCDF_C_LIBRARIES}")
add_subdirectory (src)
add_subdirectory (driver)
install(TARGETS ELM_driver DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin)
install(TARGETS physics DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/lib)
\ No newline at end of file
# -*- mode: cmake -*-
#
# Usage:
#
# ADD_IMPORTED_LIBRARY(name [SHARED | STATIC]
# LOCATION <path>
# [ LINK_LANGUAGES <lang1> <lang2> <lang3> ... ]
# [ LINK_INTERFACE_LIBRARIES <lib1> <lib2> ... ]
# )
#
include(CMakeParseArguments)
include(PrintVariable)
function(ADD_IMPORTED_LIBRARY target_name)
set(_options SHARED STATIC)
set(_oneValueArgs LOCATION)
set(_multiValueArgs LINK_LANGUAGES LINK_INTERFACE_LIBRARIES)
cmake_parse_arguments(PARSE "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN} )
# --- Check what has been passed in
# SHARED and STATIC can not be set at the same time
if ( "${PARSE_STATIC}" AND "${PARSE_SHARED}" )
message(FATAL_ERROR "Can not specify imported library as shared and static.")
endif()
# Require a location
if ( NOT PARSE_LOCATION )
message(FATAL_ERROR "Must specify a location to define an imported library target.")
endif()
# Check to see if name already exists as a target
if ( TARGET "${target_name}" )
message(FATAL_ERROR "Target ${name} is already defined.")
endif()
# --- Set the library type
set(lib_type UNKNOWN)
if(PARSE_STATIC)
set(lib_type STATIC)
endif()
if(PARSE_SHARED)
set(lib_type SHARED)
endif()
# --- Add the library target
add_library(${target_name} ${lib_type} IMPORTED)
# --- Update the global property that tracks imported targets
set(prop_name IMPORTED_${lib_type}_LIBRARIES)
get_property(prop_value GLOBAL PROPERTY ${prop_name})
set_property(GLOBAL PROPERTY ${prop_name} ${prop_value} ${target_name})
# --- Set the properties
set_target_properties(${target_name} PROPERTIES
IMPORTED_LOCATION ${PARSE_LOCATION})
if (PARSE_LINK_LANGUAGES)
set_target_properties(${target_name} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "${PARSE_LINK_LANGUAGES}")
endif()
if (PARSE_LINK_INTERFACE_LIBRARIES)
set_target_properties(${target_name} PROPERTIES
INTERFACE_LINK_LIBRARIES "${PARSE_LINK_INTERFACE_LIBRARIES}")
endif()
endfunction(ADD_IMPORTED_LIBRARY)
#
# Useful macros
#
macro(PRINT_LINK_LIBRARIES target_lib)
if (TARGET ${target_lib})
get_property(_link_libs TARGET ${target_lib} PROPERTY INTERFACE_LINK_LIBRARIES)
message(STATUS "\tINTERFACE_LINK_LIBRARIES for target=${target_lib}: ${_link_libs}")
endif()
endmacro(PRINT_LINK_LIBRARIES)
# -*- mode: cmake -*-
#
# Amanzi
# ADD_PACKAGE_DEPENDENCY(<PACKNAME> DEPENDS_ON <req_pack>)
#
# CMake module
include(CMakeParseArguments)
# Amanzi modules
include(PrintVariable)
include(ParseLibraryList)
function(ADD_PACKAGE_DEPENDENCY)
# Macro: _print_usage
macro(_print_usage)
message("\nADD_PACKAGE_DEPENDENCY(<target_package> DEPENDS_ON <req_package>)\n"
" Add req_package to target_package dependencies.\n")
endmacro(_print_usage)
# Parse the arguments
set(_options "")
set(_oneValue "DEPENDS_ON")
set(_multiValue "")
cmake_parse_arguments(ADD_PACK "${_options}" "${_oneValue}" "${_multiValue}" ${ARGN})
# Define the target package name
list(GET ADD_PACK_UNPARSED_ARGUMENTS 0 target_package)
if ( NOT target_package )
_print_usage()
message(FATAL_ERROR "Must define a target_package")
endif()
# Define the required package
set(req_package "")
if(ADD_PACK_DEPENDS_ON)
set(req_package ${ADD_PACK_DEPENDS_ON})
else()
_print_usage()
message(FATAL_ERROR "Must define a required package")
endif()
# Find required package
message(STATUS "${target_package} depends on ${req_package}")
message(STATUS "Updating ${target_package}_LIBRARIES and ${target_package}_INCLUDE_DIRS")
find_package(${req_package} REQUIRED)
if( ${req_package}_LIBRARIES AND ${req_package}_INCLUDE_DIRS )
# Add the include paths
set(_save_inc_list ${${target_package}_INCLUDE_DIRS})
list(APPEND _save_inc_list ${${req_package}_INCLUDE_DIRS})
set(${target_package}_INCLUDE_DIRS ${_save_inc_list} PARENT_SCOPE)
list(REMOVE_DUPLICATES ${target_package}_INCLUDE_DIRS)
# Add the libraries....this can be tricky because some packages
# *cough* HDF5 *cough* return a list with keywords debug, optimized
# general in the list. These keywords are flags that are used when
# CMAKE_BUILD_TYPE is set. Need to construct the LIBRARIES carefully
# if these are present.
parse_library_list(${${target_package}_LIBRARIES}
FOUND target_libs_split
DEBUG target_debug_libs
OPT target_opt_libs
GENERAL target_gen_libs)
parse_library_list(${${req_package}_LIBRARIES}
FOUND req_libs_split
DEBUG req_debug_libs
OPT req_opt_libs
GENERAL req_gen_libs)
# _save_lib_list tmp storage
set(_save_lib_list "")
if ( ${target_libs_split} OR ${req_libs_split} )
# Define the parsed lists if the orginal list did not contain keywords
if ( NOT ${target_libs_split} )
set(target_debug_libs ${${target_package}_LIBRARIES})
set(target_opt_libs ${${target_package}_LIBRARIES})
set(target_general_libs ${${target_package}_LIBRARIES})
endif()
if ( NOT ${req_libs_split} )
set(req_debug_libs ${${req_package}_LIBRARIES})
set(req_opt_libs ${${req_package}_LIBRARIES})
set(req_general_libs ${${req_package}_LIBRARIES})
endif()
# Define each type and store in tmp lists removing duplicates
set(_save_debug_list "")
set(_save_opt_list "")
set(_save_gen_list "")
if ( target_debug_libs OR req_debug_libs )
set(_save_debug_list "${target_debug_libs}" "${req_debug_libs}")
list(REMOVE_DUPLICATES _save_debug_list)
#print_variable(_save_debug_list)
endif()
if ( target_opt_libs OR req_opt_libs )
set(_save_opt_list "${target_opt_libs}" "${req_opt_libs}")
list(REMOVE_DUPLICATES _save_opt_list)
#print_variable(_save_opt_list)
endif()
if ( target_gen_libs OR req_gen_libs )
set(_save_gen_list "${target_gen_libs}" "${req_gen_libs}")
list(REVERSE _save_gen_list)
list(REMOVE_DUPLICATES _save_gen_list)
list(REVERSE _save_gen_list)
#print_variable(_save_gen_list)
endif()
# Now build the _save_lib_list with the keywords
if(_save_debug_list)
list(APPEND _save_lib_list "debug")
list(APPEND _save_lib_list "${_save_debug_list}")
endif()
if(_save_opt_list)
list(APPEND _save_lib_list "optimized")
list(APPEND _save_lib_list "${_save_opt_list}")
endif()
if(_save_gen_list)
list(APPEND _save_lib_list "general")
list(APPEND _save_lib_list "${_save_gen_list}")
endif()
else()
# Neither list has keywords
set(_save_lib_list "${${target_package}_LIBRARIES}" "${${req_package}_LIBRARIES}")
list(REVERSE _save_lib_list)
list(REMOVE_DUPLICATES _save_lib_list)
list(REVERSE _save_lib_list)
endif()
set(${target_package}_LIBRARIES ${_save_lib_list} PARENT_SCOPE)
endif()
endfunction(ADD_PACKAGE_DEPENDENCY)
# -*- mode: cmake -*-
#
# Amanzi NetCDF Find Module
#
# Usage:
# Control the search through NetCDF_DIR or setting environment variable
# NetCDF_ROOT to the NetCDF installation prefix.
# By default only searches for C library. To search for the C++ library
# set 'CXX' in the COMPONENTS option in find_package(NetCDF)
#
# This module does not search default paths!
#
# Following variables are set:
# NetCDF_FOUND (BOOL) Flag indicating if NetCDF was found
# NetCDF_INCLUDE_DIR (PATH) Path to the NetCDF include file
# NetCDF_INCLUDE_DIRS (LIST) List of all required include files
# NetCDF_C_LIBRARIES (LIST) List of all required libraries to link to
# the NetCDF C library
# NetCDF_CXX_LIBRARIES (LIST) List of all required libraries to link to
# the NetCDF C++ library (If CXX is in COMPONENTS)
#
# Additional variables set
# NetCDF_C_LIBRARY (FILE) NetCDF C library
# NetCDF_CXX_LIBRARY (FILE) NetCDF C++ library (If CXX is in the COMPONENTS)
# NetCDF_LARGE_DIMS (BOOL) Checks the header files for size of
# NC_MAX_DIMS, NC_MAX_VARS and NC_MAX_VARS_DIMS
# Returns TRUE if
# NC_MAX_DIMS >= 655363
# NC_MAX_VARS >= 524288
# NC_MAX_VAR_DIMS >= 8
#
# #############################################################################
# Standard CMake modules see CMAKE_ROOT/Modules
include(FindPackageHandleStandardArgs)
# Amanzi CMake functions see <root>/tools/cmake for source
include(PrintVariable)
include(AddPackageDependency)
# Macro to handle print out
macro(_netcdf_status mess)
if (NOT NetCDF_FIND_QUIETLY)
message(STATUS "${mess}")
endif()
endmacro()
# Search for the nc-config binary
find_program(NetCDF_CONFIG_BINARY nc-config
HINTS ${NetCDF_DIR} ${NetCDF_BIN_DIR}
PATH_SUFFIXES bin Bin
DOC "NetCDF configuration script")
if (NetCDF_C_LIBRARIES AND NetCDF_INCLUDE_DIRS )
# Do nothing. Variables are set. No need to search again
else(NetCDF_C_LIBRARIES AND NetCDF_INCLUDE_DIRS)
# Cache variables
if (NetCDF_DIR)
set(NetCDF_DIR "${NetCDF_DIR}" CACHE PATH "Path to search for NetCDF include and library files")
endif()
if (NetCDF_INCLUDE_DIR)
set(NetCDF_INCLUDE_DIR "${NetCDF_INCLUDE_DIR}" CACHE PATH "Path to search for NetCDF include files")
endif()
if (NetCDF_LIBRARY_DIR)
set(NetCDF_LIBRARY_DIR "${NetCDF_LIBRARY_DIR}" CACHE PATH "Path to search for NetCDF library files")
endif()
if (NOT NetCDF_INCLUDE_DIR )
# Search for include files
# Search order preference:
# (1) NetCDF_INCLUDE_DIR - check existence of path AND if the include files exist
# (2) NetCDF_DIR/<include>
# (3) Default CMake paths See cmake --html-help=out.html file for more information.
#
set(netcdf_inc_names "netcdf.h")
if (NetCDF_INCLUDE_DIR)
if (EXISTS "${NetCDF_INCLUDE_DIR}")
find_path(cdf_test_include_path
NAMES ${netcdf_inc_names}
HINTS ${NetCDF_INCLUDE_DIR}
NO_DEFAULT_PATH)
if (NOT cdf_test_include_path)
message(WARNING "Can not locate ${netcdf_inc_names} in ${NetCDF_INCLUDE_DIR}")
endif()
set(NetCDF_INCLUDE_DIR "${cdf_test_include_path}")
else()
message(WARNING "NetCDF_INCLUDE_DIR=${NetCDF_INCLUDE_DIR} does not exist")
set(NetCDF_INCLUDE_DIR "NetCDF_INCLUDE_DIR-NOTFOUND")
endif()
else()
set(netcdf_inc_suffixes "include")
if (NetCDF_DIR)
if (EXISTS "${NetCDF_DIR}" )
find_path(NetCDF_INCLUDE_DIR
NAMES ${netcdf_inc_names}
HINTS ${NetCDF_DIR}
PATH_SUFFIXES ${netcdf_inc_suffixes}
NO_DEFAULT_PATH)
else()
message(WARNING "NetCDF_DIR=${NetCDF_DIR} does not exist")
set(NetCDF_INCLUDE_DIR "NetCDF_INCLUDE_DIR-NOTFOUND")
endif()
else()
find_path(NetCDF_INCLUDE_DIR
NAMES ${netcdf_inc_names}
PATH_SUFFIXES ${netcdf_inc_suffixes})
endif()
endif()
if (NOT NetCDF_INCLUDE_DIR)
message(WARNING "Can not locate NetCDF include directory")
endif()
endif(NOT NetCDF_INCLUDE_DIR)
if (NOT NetCDF_C_LIBRARIES)
# Search for libraries
# Search order preference:
# (1) NetCDF_LIBRARY_DIR - check existence of path AND if the include files exist
# (2) NetCDF_DIR/<lib,Lib>
# (3) Default CMake paths See cmake --html-help=out.html file for more information.
#
if (NetCDF_LIBRARY_DIR)
if (EXISTS "${NetCDF_LIBRARY_DIR}")
find_library(_NetCDF_C_LIBRARY
NAMES netcdf
HINTS ${NetCDF_LIBRARY_DIR}
NO_DEFAULT_PATH)
else()
message(WARNING "NetCDF_LIBRARY_DIR=${NetCDF_LIBRARY_DIR} does not exist")
set(NetCDF_C_LIBRARY NetCDF_C_LIBRARY-NOTFOUND)
endif()
else()
if (NetCDF_DIR)
if (EXISTS "${NetCDF_DIR}")
find_library(_NetCDF_C_LIBRARY
NAMES netcdf
HINTS ${NetCDF_DIR}
PATH_SUFFIXES "lib" "Lib"
NO_DEFAULT_PATH)
else()
message(WARNING "NetCDF_DIR=${NetCDF_DIR} does not exist")
set(NetCDF_C_LIBRARY "NetCDF_C_LIBRARY-NOTFOUND")
endif()
else()
find_library(_NetCDF_C_LIBRARY
NAMES netcdf
PATH_SUFFIXES ${netcdf_lib_suffixes})
endif()
endif()
# Define the NetCDF library targets
if (_NetCDF_C_LIBRARY)
if (NetCDF_CONFIG_BINARY)
execute_process(COMMAND "${NetCDF_CONFIG_BINARY}" "--has-hdf5"
RESULT_VARIABLE _ret_code
OUTPUT_VARIABLE _stdout
ERROR_VARIABLE _stderr)
string(REGEX REPLACE "[\n\r ]" "" _hdf5_answer ${_stdout})
_netcdf_status("${NetCDF_CONFIG_BINARY} --has-hdf5 returned '${_hdf5_answer}'")
string(COMPARE EQUAL "${_hdf5_answer}" "yes" _has_hdf5)
if (${_has_hdf5} )
set(NetCDF_NEEDS_HDF5 TRUE)
_netcdf_status( "NetCDF requires HDF5")
else()
set(NetCDF_NEEDS_HDF5 FALSE)
_netcdf_status( "NetCDF does not require HDF5")
endif()
endif()
# If NetCDF was built with HDF5 then add that to the target properties
# NetCDF calls HDF5 HL routines and not all HDF5 installations will have
# this library. Warn the user if HL is not detected. Use the
# HDF5_C_LIBRARIES to define link needs since it will contain hdf5 and
# hdf5_hl.
set(_NetCDF_C_LIBRARY_LINK_LIBS)
if (NetCDF_NEEDS_HDF5)
find_package(HDF5 QUIET REQUIRED COMPONENTS C HL)
if (HDF5_FOUND)
if (NOT HDF5_HL_FOUND)
message(WARNING "NetCDF calls the HDF5 HL library but this HDF5 does not have one")
endif()
set(_NetCDF_C_LIBRARY_LINK_LIBS ${HDF5_HL_LIBRARIES} ${HDF5_C_LIBRARIES})
list(APPEND NetCDF_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS})
endif()
endif()
# Now create the target 'netcdf'
add_imported_library(netcdf LOCATION "${_NetCDF_C_LIBRARY}" LINK_LANGUAGES "C")
if (_NetCDF_C_LIBRARY_LINK_LIBS)
set_target_properties(netcdf PROPERTIES
INTERFACE_LINK_LIBRARIES "${_NetCDF_C_LIBRARY_LINK_LIBS}")
endif()
set(NetCDF_C_LIBRARY netcdf)
set(NetCDF_C_LIBRARIES ${NetCDF_C_LIBRARY} ${_NetCDF_C_LIBRARY_LINK_LIBS})
set(NetCDF_C_FOUND TRUE)
endif(_NetCDF_C_LIBRARY)
endif(NOT NetCDF_C_LIBRARIES)
endif(NetCDF_C_LIBRARIES AND NetCDF_INCLUDE_DIRS)
# Large dimension check here
if (NetCDF_INCLUDE_DIR)
set(netcdf_h "${NetCDF_INCLUDE_DIR}/netcdf.h" )
_netcdf_status( "NetCDF include file ${netcdf_h} will be searched for define values")
file(STRINGS "${netcdf_h}" netcdf_max_dims_string REGEX "^#define NC_MAX_DIMS")
string(REGEX REPLACE "[^0-9]" "" netcdf_max_dims "${netcdf_max_dims_string}")
file(STRINGS "${netcdf_h}" netcdf_max_vars_string REGEX "^#define NC_MAX_VARS")
string(REGEX REPLACE "[^0-9]" "" netcdf_max_vars "${netcdf_max_vars_string}")
file(STRINGS "${netcdf_h}" netcdf_max_var_dims_string REGEX "^#define NC_MAX_VAR_DIMS")
string(REGEX REPLACE "[^0-9]" "" netcdf_max_var_dims "${netcdf_max_var_dims_string}")
if (
( (netcdf_max_dims EQUAL 65536) OR (netcdf_max_dims GREATER 65536) ) AND
( (netcdf_max_vars EQUAL 524288) OR (netcdf_max_vars GREATER 524288) ) AND
( (netcdf_max_var_dims EQUAL 8) OR (netcdf_max_var_dims GREATER 8) )
)
set(NetCDF_LARGE_DIMS TRUE)
else()
message(WARNING "The NetCDF found in ${NetCDF_DIR} does not have the correct NC_MAX_DIMS, NC_MAX_VARS and NC_MAX_VAR_DIMS\n"
"It may not be compatible with other TPL libraries such MOAB and ExodusII\n" )
set(NetCDF_LARGE_DIMS FALSE)
endif()
endif()
# Determine the version
if (NOT NetCDF_VERSION)
if (NetCDF_CONFIG_BINARY)
execute_process(COMMAND "${NetCDF_CONFIG_BINARY}" "--version"
RESULT_VARIABLE _ret_code
OUTPUT_VARIABLE _stdout
ERROR_VARIABLE _stderr)
string(REGEX REPLACE "[\n\r ]" "" _version_answer "${_stdout}")
string(REGEX REPLACE "netCDF" "" NetCDF_VERSION "${_version_answer}")
endif()
endif()
# Search for the C++ libraries if requested
if (NetCDF_FIND_COMPONENTS)
list(FIND NetCDF_FIND_COMPONENTS "CXX" _search_cxx_library)
if (( NOT NetCDF_CXX_LIBRARIES ) AND
( NOT ("${_search_cxx_library}" LESS "0") ) )
if (NetCDF_LIBRARY_DIR)
if (EXISTS "${NetCDF_LIBRARY_DIR}")
find_library(_NetCDF_CXX_LIBRARY
NAMES netcdf_c++
HINTS ${NetCDF_LIBRARY_DIR}
NO_DEFAULT_PATH)
else()
message(WARNING "NetCDF_LIBRARY_DIR=${NetCDF_LIBRARY_DIR} does not exist")
set(NetCDF_CXX_LIBRARY NetCDF_CXX_LIBRARY-NOTFOUND)
endif()
else()
if (NetCDF_DIR)
if (EXISTS "${NetCDF_DIR}")
find_library(_NetCDF_CXX_LIBRARY
NAMES netcdf_c++
HINTS ${NetCDF_DIR}
PATH_SUFFIXES "lib" "Lib"
NO_DEFAULT_PATH)
else()
message(WARNING "NetCDF_DIR=${NetCDF_DIR} does not exist")
set(NetCDF_CXX_LIBRARY "NetCDF_CXX_LIBRARY-NOTFOUND")
endif()
else()
find_library(_NetCDF_CXX_LIBRARY
NAMES netcdf_c++
PATH_SUFFIXES ${netcdf_lib_suffixes})
endif()
endif()
if (_NetCDF_CXX_LIBRARY)
add_imported_library(netcdf_c++ LOCATION "${_NetCDF_C_LIBRARY}" LINK_LANGUAGES "CXX")
set_target_properties(netcdf_c++ PROPERTIES
INTERFACE_LINK_LIBRARIES "${NetCDF_C_LIBRARY}")
set(NetCDF_CXX_LIBRARY netcdf_c++)
set(NetCDF_CXX_FOUND TRUE)
set(NetCDF_CXX_LIBRARIES ${NetCDF_CXX_LIBRARY} ${NetCDF_C_LIBRARIES})
endif()
endif()
endif(NetCDF_FIND_COMPONENTS)
# Send useful message if everything is found
find_package_handle_standard_args(NetCDF DEFAULT_MSG
NetCDF_VERSION
NetCDF_C_LIBRARIES
NetCDF_INCLUDE_DIRS)
mark_as_advanced(
NetCDF_INCLUDE_DIR
NetCDF_INCLUDE_DIRS
NetCDF_C_LIBRARY
NetCDF_CXX_LIBRARY
NetCDF_C_LIBRARIES
)
# -*- mode: cmake -*-
#
# Amanzi
#
# PARSE_LIBRARY_LIST( <lib_list>
# DEBUG <out_debug_list>
# OPT <out_opt_list>