Skip to content

Commit

Permalink
rework netcdf find
Browse files Browse the repository at this point in the history
  • Loading branch information
jedwards4b committed Nov 23, 2023
1 parent 7374470 commit df3bff4
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 169 deletions.
59 changes: 33 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,17 @@ set (CPRNC_Fortran_MODS ${CMAKE_CURRENT_BINARY_DIR}/compare_vars_mod.mod
${CMAKE_CURRENT_BINARY_DIR}/prec.mod)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

add_executable (cprnc ${CPRNC_Fortran_SRCS} ${CPRNC_GenF90_SRCS})
# Always use -fPIC
set_property(TARGET cprnc PROPERTY POSITION_INDEPENDENT_CODE ON)
set(CMAKE_MACOSX_RPATH 1)

# Compiler-specific compile options
if ("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU")
target_compile_options (cprnc
PRIVATE -ffree-line-length-none)
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ffree-line-length-none")
endif()

if (CMAKE_BUILD_TYPE STREQUAL "DEBUG")
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g")
endif()

#==============================================================================
# DEFINE THE INSTALL
#==============================================================================

# Executable
install (TARGETS cprnc DESTINATION bin)

#==============================================================================
# DEFINE THE DEPENDENCIES
Expand All @@ -63,14 +53,12 @@ else ()
set (GENF90_PATH ${SOURCE_DIR})
unset (SOURCE_DIR)
endif ()
add_dependencies (cprnc genf90)


file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/run_tests
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/test_inputs ${CMAKE_CURRENT_BINARY_DIR}/test_inputs)
enable_testing()
add_test(NAME run_tests COMMAND run_tests -outdir tmp)

#===== Fortran Source Generation with GenF90 =====
foreach (SRC_FILE IN LISTS CPRNC_GenF90_SRCS)
Expand All @@ -81,18 +69,37 @@ foreach (SRC_FILE IN LISTS CPRNC_GenF90_SRCS)
endforeach ()

#===== NetCDF-Fortran =====
INCLUDE(FindNetCDF Fortran)
if (NetCDF_Fortran_FOUND)
target_include_directories (cprnc
PUBLIC ${NetCDF_Fortran_INCLUDE_DIRS})
target_link_libraries (cprnc
PUBLIC ${NetCDF_Fortran_LIBRARIES})
endif ()
INCLUDE(FindNetCDF)
find_library(netcdf_fortran_lib netcdff HINTS ${NetCDF_Fortran_ROOT})
#message (STATUS "netcdf_fortran_lib == ${netcdf_fortran_lib}")
get_filename_component(netcdf_fortran_lib_location ${netcdf_fortran_lib} DIRECTORY)
#message (STATUS "netcdf_fortran_lib_location == ${netcdf_fortran_lib_location}")

find_library(netcdf_c_lib netcdf HINTS ${NetCDF_C_LIBRARY})
#message (STATUS "netcdf_c_lib == ${netcdf_c_lib}")
get_filename_component(netcdf_c_lib_location ${netcdf_c_lib} DIRECTORY)
#message (STATUS "netcdf_c_lib_location == ${netcdf_c_lib_location}")

list(APPEND CMAKE_BUILD_RPATH ${netcdf_fortran_lib_location} ${netcdf_c_lib_location})
#message("CMAKE_BUILD_RPATH is ${CMAKE_BUILD_RPATH}")
add_executable (cprnc ${CPRNC_Fortran_SRCS} ${CPRNC_GenF90_SRCS})
#message("Setting include dir ${NetCDF_Fortran_INCLUDE_DIRS}")
target_include_directories(cprnc PUBLIC ${NetCDF_Fortran_INCLUDE_DIRS})

add_dependencies (cprnc genf90)

#===== Check for necessities =====
if (NOT NetCDF_Fortran_FOUND)
message (FATAL_ERROR "Must have NetCDF Fortran libraries")
endif ()
# Always use -fPIC
set_property(TARGET cprnc PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries (cprnc
PUBLIC ${NetCDF_Fortran_LIBRARIES} ${NetCDF_C_LIBRARIES} ${NetCDF_LIBRARIES})


enable_testing()
add_test(NAME run_tests COMMAND run_tests -outdir tmp)

#==============================================================================
# DEFINE THE INSTALL
#==============================================================================

# Executable
install (TARGETS cprnc DESTINATION bin)
239 changes: 96 additions & 143 deletions cmake/FindNetCDF.cmake
Original file line number Diff line number Diff line change
@@ -1,143 +1,96 @@
# - Try to find NetCDF
#
# This can be controlled by setting the NetCDF_PATH (or, equivalently, the
# NETCDF environment variable), or NetCDF_<lang>_PATH CMake variables, where
# <lang> is the COMPONENT language one needs.
#
# Once done, this will define:
#
# NetCDF_<lang>_FOUND (BOOL) - system has NetCDF
# NetCDF_<lang>_IS_SHARED (BOOL) - whether library is shared/dynamic
# NetCDF_<lang>_INCLUDE_DIR (PATH) - Location of the C header file
# NetCDF_<lang>_INCLUDE_DIRS (LIST) - the NetCDF include directories
# NetCDF_<lang>_LIBRARY (FILE) - Path to the C library file
# NetCDF_<lang>_LIBRARIES (LIST) - link these to use NetCDF
#
# The available COMPONENTS are: C Fortran
# If no components are specified, it assumes only C
include (LibFind)
include (LibCheck)

# Define NetCDF C Component
define_package_component (NetCDF DEFAULT
COMPONENT C
INCLUDE_NAMES netcdf.h
LIBRARY_NAMES netcdf)

# Define NetCDF Fortran Component
define_package_component (NetCDF
COMPONENT Fortran
INCLUDE_NAMES netcdf.mod netcdf.inc
LIBRARY_NAMES netcdff)

# Search for list of valid components requested
find_valid_components (NetCDF)

#==============================================================================
# SEARCH FOR VALIDATED COMPONENTS
foreach (NCDFcomp IN LISTS NetCDF_FIND_VALID_COMPONENTS)

# If not found already, search...
if (NOT NetCDF_${NCDFcomp}_FOUND)

# Manually add the MPI include and library dirs to search paths
# and search for the package component
if (MPI_${NCDFcomp}_FOUND)
initialize_paths (NetCDF_${NCDFcomp}_PATHS
INCLUDE_DIRECTORIES ${MPI_${NCDFcomp}_INCLUDE_PATH}
LIBRARIES ${MPI_${NCDFcomp}_LIBRARIES})
find_package_component(NetCDF COMPONENT ${NCDFcomp}
PATHS ${NetCDF_${NCDFcomp}_PATHS})
else ()
find_package_component(NetCDF COMPONENT ${NCDFcomp})
endif ()

# Continue only if component found
if (NetCDF_${NCDFcomp}_FOUND)

# Checks
if (NCDFcomp STREQUAL C)

# Check version
check_version (NetCDF
NAME "netcdf_meta.h"
HINTS ${NetCDF_C_INCLUDE_DIRS}
MACRO_REGEX "NC_VERSION_")

# Check for parallel support
check_macro (NetCDF_C_HAS_PARALLEL
NAME TryNetCDF_PARALLEL.c
HINTS ${CMAKE_MODULE_PATH}
DEFINITIONS -I${NetCDF_C_INCLUDE_DIR}
COMMENT "whether NetCDF has parallel support")

# Check if logging enabled
set(CMAKE_REQUIRED_INCLUDES ${NetCDF_C_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${NetCDF_C_LIBRARIES})
CHECK_FUNCTION_EXISTS(nc_set_log_level NetCDF_C_LOGGING_ENABLED)

endif ()

# Dependencies
if (NCDFcomp STREQUAL C AND NOT NetCDF_C_IS_SHARED)

# DEPENDENCY: PnetCDF (if PnetCDF enabled)
check_macro (NetCDF_C_HAS_PNETCDF
NAME TryNetCDF_PNETCDF.c
HINTS ${CMAKE_MODULE_PATH}
DEFINITIONS -I${NetCDF_C_INCLUDE_DIR}
COMMENT "whether NetCDF has PnetCDF support")
if (NetCDF_C_HAS_PNETCDF)
find_package (PnetCDF COMPONENTS C)
if (CURL_FOUND)
list (APPEND NetCDF_C_INCLUDE_DIRS ${PnetCDF_C_INCLUDE_DIRS})
list (APPEND NetCDF_C_LIBRARIES ${PnetCDF_C_LIBRARIES})
endif ()
endif ()

# DEPENDENCY: CURL (If DAP enabled)
check_macro (NetCDF_C_HAS_DAP
NAME TryNetCDF_DAP.c
HINTS ${CMAKE_MODULE_PATH}
DEFINITIONS -I${NetCDF_C_INCLUDE_DIR}
COMMENT "whether NetCDF has DAP support")
if (NetCDF_C_HAS_DAP)
find_package (CURL)
if (CURL_FOUND)
list (APPEND NetCDF_C_INCLUDE_DIRS ${CURL_INCLUDE_DIRS})
list (APPEND NetCDF_C_LIBRARIES ${CURL_LIBRARIES})
endif ()
endif ()

# DEPENDENCY: HDF5
find_package (HDF5 COMPONENTS HL C)
if (HDF5_C_FOUND)
list (APPEND NetCDF_C_INCLUDE_DIRS ${HDF5_C_INCLUDE_DIRS}
${HDF5_HL_INCLUDE_DIRS})
list (APPEND NetCDF_C_LIBRARIES ${HDF5_C_LIBRARIES}
${HDF5_HL_LIBRARIES})
endif ()

# DEPENDENCY: LIBDL Math
list (APPEND NetCDF_C_LIBRARIES -ldl -lm)

elseif (NCDFcomp STREQUAL Fortran AND NOT NetCDF_Fortran_IS_SHARED)

# DEPENDENCY: NetCDF
set (orig_comp ${NCDFcomp})
set (orig_comps ${NetCDF_FIND_VALID_COMPONENTS})
find_package (NetCDF COMPONENTS C)
set (NetCDF_FIND_VALID_COMPONENTS ${orig_comps})
set (NCDFcomp ${orig_comp})
if (NetCDF_C_FOUND)
list (APPEND NetCDF_Fortran_INCLUDE_DIRS ${NetCDF_C_INCLUDE_DIRS})
list (APPEND NetCDF_Fortran_LIBRARIES ${NetCDF_C_LIBRARIES})
endif ()

endif ()

endif ()

endif ()

endforeach ()
# First try to locate nf-config.
find_program(NetCDF_Fortran_CONFIG_EXECUTABLE
NAMES nf-config
HINTS ENV NetCDF_ROOT NetCDF_Fortran_ROOT
PATH_SUFFIXES bin Bin
DOC "NetCDF config program. Used to detect NetCDF Fortran include directory and linker flags." )
mark_as_advanced(NetCDF_Fortran_CONFIG_EXECUTABLE)
find_program(NetCDF_C_CONFIG_EXECUTABLE
NAMES nc-config
HINTS ENV NetCDF_ROOT NetCDF_C_ROOT
PATH_SUFFIXES bin Bin
DOC "NetCDF config program. Used to detect NetCDF C include directory and linker flags." )
mark_as_advanced(NetCDF_C_CONFIG_EXECUTABLE)


if(NetCDF_Fortran_CONFIG_EXECUTABLE)
# Found nf-config - use it to retrieve include directory and linking flags.
# Note that if the process fails (as e.g. on Windows), the output variables
# will remain empty
execute_process(COMMAND ${NetCDF_Fortran_CONFIG_EXECUTABLE} --includedir
OUTPUT_VARIABLE DEFAULT_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${NetCDF_Fortran_CONFIG_EXECUTABLE} --flibs
OUTPUT_VARIABLE flibs
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (flibs)
set(NetCDF_Fortran_LIBRARIES ${flibs} CACHE STRING "NetCDF libraries (or linking flags)")
set(AUTODETECTED_NetCDF_Fortran_LIBRARIES ON)
endif()

execute_process(COMMAND ${NetCDF_Fortran_CONFIG_EXECUTABLE} --prefix
OUTPUT_VARIABLE root
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (root)
set(NetCDF_Fortran_ROOT ${root} CACHE STRING "NetCDF Fortran Root")
set(AUTODETECTED_NetCDF_Fortran_ROOT ON)
endif()

endif()

if(NetCDF_C_CONFIG_EXECUTABLE)
# Found nc-config - use it to retrieve include directory and linking flags.
# Note that if the process fails (as e.g. on Windows), the output variables
# will remain empty
execute_process(COMMAND ${NetCDF_C_CONFIG_EXECUTABLE} --includedir
OUTPUT_VARIABLE DEFAULT_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${NetCDF_C_CONFIG_EXECUTABLE} --libs
OUTPUT_VARIABLE libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (flibs)
set(NetCDF_C_LIBRARIES ${libs} CACHE STRING "NetCDF libraries (or linking flags)")
set(AUTODETECTED_NetCDF_C ON)
endif()

endif()

# Determine default name of NetCDf library
# If nf-config succeeded, its result takes priority as it has already been
# used to set NetCDF_LIBRARIES
if(DEFINED ENV{NetCDFLIBNAME})
set(DEFAULT_LIBRARY_NAME "$ENV{NETCDFLIBNAME}")
else()
set(DEFAULT_LIBRARY_NAME netcdff)
endif()

find_path(NetCDF_Fortran_INCLUDE_DIRS netcdf.mod
HINTS "${DEFAULT_INCLUDE_DIR}" "$ENV{NetCDF_Fortran_INCLDE_DIRS}" "$ENV{CONDA_PREFIX}/Library/include"
DOC "NetCDF Fortran include directories")

find_library(NetCDF_Fortran_LIBRARY NAMES ${DEFAULT_LIBRARY_NAME}
HINTS "${DEFAULT_LIBRARY_DIR}" "$ENV{NetCDF_Fortran_LIBRARY}" "$ENV{CONDA_PREFIX}/Library/lib"
DOC "NetCDF libraries (or linking flags)")

find_path(NetCDF_C_INCLUDE_DIRS netcdf.h
HINTS "${DEFAULT_INCLUDE_DIR}" "$ENV{NetCDF_C_INCLDE_DIRS}" "$ENV{CONDA_PREFIX}/Library/include"
DOC "NetCDF C include directories")

find_library(NetCDF_C_LIBRARY NAMES ${DEFAULT_LIBRARY_NAME}
HINTS "${DEFAULT_LIBRARY_DIR}" "$ENV{NetCDF_C_LIBRARY}" "$ENV{CONDA_PREFIX}/Library/lib"
DOC "NetCDF C libraries (or linking flags)")

if(AUTODETECTED_NetCDF)
mark_as_advanced(NetCDF_Fortran_INCLUDE_DIRS NetCDF_Fortran_LIBRARIES)
mark_as_advanced(NetCDF_C_INCLUDE_DIRS NetCDF_C_LIBRARIES)
mark_as_advanced(NetCDF_Fortran_ROOT)
endif()

# Process default arguments (QUIET, REQUIRED)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args (NetCDF DEFAULT_MSG NetCDF_Fortran_LIBRARIES NetCDF_Fortran_INCLUDE_DIRS)
find_package_handle_standard_args (NetCDF DEFAULT_MSG NetCDF_C_LIBRARIES NetCDF_C_INCLUDE_DIRS)

add_library(netcdf INTERFACE IMPORTED GLOBAL)
set_property(TARGET netcdf APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${NetCDF_C_INCLUDE_DIRS} ${NetCDF_Fortran_INCLUDE_DIRS}")
set_property(TARGET netcdf APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${NetCDF_Fortran_LIBRARIES} ${NetCDF_C_LIBRARIES}")

0 comments on commit df3bff4

Please sign in to comment.