diff --git a/CMakeLists.txt b/CMakeLists.txt index 66cd1a1..6535b49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 @@ -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) @@ -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) diff --git a/cmake/FindNetCDF.cmake b/cmake/FindNetCDF.cmake index 344714b..74e8181 100644 --- a/cmake/FindNetCDF.cmake +++ b/cmake/FindNetCDF.cmake @@ -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__PATH CMake variables, where -# is the COMPONENT language one needs. -# -# Once done, this will define: -# -# NetCDF__FOUND (BOOL) - system has NetCDF -# NetCDF__IS_SHARED (BOOL) - whether library is shared/dynamic -# NetCDF__INCLUDE_DIR (PATH) - Location of the C header file -# NetCDF__INCLUDE_DIRS (LIST) - the NetCDF include directories -# NetCDF__LIBRARY (FILE) - Path to the C library file -# NetCDF__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}")