Skip to content

Commit

Permalink
Merge pull request #29 from climbfuji/find_netcdf_pkgconfig
Browse files Browse the repository at this point in the history
Simple PkgConfig based version of FindNetCDF
  • Loading branch information
mark-a-potts authored Feb 29, 2020
2 parents 994d66f + 13a1369 commit b605db0
Showing 1 changed file with 31 additions and 177 deletions.
208 changes: 31 additions & 177 deletions Modules/FindNetCDF.cmake
Original file line number Diff line number Diff line change
@@ -1,198 +1,52 @@
# Copyright https://github.com/jedbrown/cmake-modules (git shortlog -s)
# All rights reserved.

# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:

# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.

# * Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# - Find NetCDF
# Find the native NetCDF includes and library
# Find the native NetCDF and NetCDF-Fortran includes and library
#
# NETCDF_INCLUDES - where to find netcdf.h, etc
# NETCDF_LIBRARIES - Link these libraries when using NetCDF
# NETCDF_FOUND - True if NetCDF found including required interfaces (see below)
#
# Your package can require certain interfaces to be FOUND by setting these
#
# NETCDF_CXX - require the C++ interface and link the C++ library
# NETCDF_F77 - require the F77 interface and link the fortran library
# NETCDF_F90 - require the F90 interface and link the fortran library
#
# The following are not for general use and are included in
# NETCDF_LIBRARIES if the corresponding option above is set.
#
# NETCDF_LIBRARIES_C - Just the C interface
# NETCDF_LIBRARIES_CXX - C++ interface, if available
# NETCDF_LIBRARIES_F77 - Fortran 77 interface, if available
# NETCDF_LIBRARIES_F90 - Fortran 90 interface, if available
#
# Normal usage would be:
# set (NETCDF_F90 "YES")
# find_package (NetCDF REQUIRED)
# target_link_libraries (uses_f90_interface ${NETCDF_LIBRARIES})
# target_link_libraries (only_uses_c_interface ${NETCDF_LIBRARIES_C})
#
# Use this for static NetCDF builds before calling find_package:
# set(NETCDF_USE_STATIC_LIBRARIES TRUE)
#

if (NETCDF_INCLUDES AND NETCDF_LIBRARIES)
# Already in cache, be silent
set (NETCDF_FIND_QUIETLY TRUE)
endif (NETCDF_INCLUDES AND NETCDF_LIBRARIES)

if(DEFINED NETCDF)
set(NETCDF_DIR ${NETCDF})
elseif(DEFINED ENV{NETCDF})
set(NETCDF_DIR $ENV{NETCDF})
set(NETCDF $ENV{NETCDF})
endif()
if(DEFINED ENV{NETCDF_FORTRAN})
set(NETCDF_FORTRAN $ENV{NETCDF_FORTRAN})
endif()
find_path (NETCDF_INCLUDES netcdf.h
HINTS ${NETCDF_DIR}/include $ENV{SSEC_NETCDF_DIR}/include )

find_program (NETCDF_META netcdf_meta.h
HINTS ${NETCDF_INCLUDES} ${CMAKE_INSTALL_PREFIX}
)
if (NETCDF_META)
file (STRINGS ${NETCDF_META} NETCDF_VERSION REGEX "define NC_VERSION_MAJOR")
string (REGEX REPLACE "#define NC_VERSION_MAJOR " "" NETCDF_VERSION ${NETCDF_VERSION})
string (REGEX REPLACE "\\/\\*\\!< netcdf-c major version. \\*\\/" "" NETCDF_VERSION ${NETCDF_VERSION})
string (REGEX REPLACE " " "" NETCDF_VERSION ${NETCDF_VERSION} )
if(${NETCDF_VERSION} GREATER "3")
set(NETCDF_F90 "YES")
endif()
endif (NETCDF_META)

find_library (NETCDF_flib
names libnetcdff.so netcdff.so libnetcdff.dylib netcdff.dylib libnetcdff.a netcdff.a
HINTS
${NETCDF_DIR}/lib
${NETCDF_FORTRAN_DIR}/lib
${NETCDF_FORTRAN}/lib
${NETCDF_FORTRAN_ROOT}/lib
${NETCDF_DIR}/lib64
${NETCDF_FORTRAN_DIR}/lib64
${NETCDF_FORTRAN}/lib64
${NETCDF_FORTRAN_ROOT}/lib64
)

if (NETCDF_flib)
get_filename_component(NETCDF_flib_ext ${NETCDF_flib} EXT)
if(NETCDF_flib_ext STREQUAL ".a")
set(NETCDF_IS_STATIC TRUE)
else()
set(NETCDF_IS_STATIC FALSE)
if (NOT NETCDF_INCLUDES OR NOT NETCDF_LIBRARIES)
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(NetCDF REQUIRED netcdf>=4)
if(NetCDF_FOUND)
if(NETCDF_USE_STATIC_LIBRARIES)
set(NETCDF_INCLUDES ${NetCDF_STATIC_INCLUDE_DIRS})
string(REPLACE ";" " " NETCDF_LIBRARIES "${NetCDF_STATIC_LDFLAGS}")
else()
set(NETCDF_INCLUDES ${NetCDF_INCLUDE_DIRS})
string(REPLACE ";" " " NETCDF_LIBRARIES "${NetCDF_LDFLAGS}")
endif()
pkg_check_modules(NetCDFF REQUIRED netcdf-fortran>=4)
if(NetCDFF_FOUND)
if(NETCDF_USE_STATIC_LIBRARIES)
set(NETCDF_INCLUDES "${NetCDFF_STATIC_INCLUDE_DIRS};${NETCDF_INCLUDES}")
string(REPLACE ";" " " NETCDF_LIBRARIES "${NetCDFF_STATIC_LDFLAGS}")
else()
set(NETCDF_INCLUDES "${NetCDFF_INCLUDE_DIRS};${NETCDF_INCLUDES}")
string(REPLACE ";" " " NETCDFF_LIBRARIES "${NetCDFF_LDFLAGS}")
set(NETCDF_LIBRARIES "${NETCDFF_LIBRARIES} ${NETCDF_LIBRARIES}")
endif()
endif()
endif()
set(NETCDF_F90 "YES")
endif()
find_library (NETCDF_LIBRARIES_C
NAMES netcdf
HINTS ${NETCDF_DIR}/lib )
mark_as_advanced(NETCDF_LIBRARIES_C)

if("${NETCDF_DIR}" STREQUAL "")
message(STATUS "Could NOT find netCDF (missing NETCDF_DIR)(found version \"\")")
else()
find_file (NETCDF_NCDUMP
NAMES ncdump
HINTS ${NETCDF_DIR}/bin )
mark_as_advanced(NETCDF_NCDUMP)
execute_process(COMMAND ${NETCDF_NCDUMP}
ERROR_VARIABLE NCDUMP_INFO)
string(FIND "${NCDUMP_INFO}" "version" VERSION_LOC REVERSE)
math(EXPR VERSION_LOC "${VERSION_LOC} + 9")
string(SUBSTRING "${NCDUMP_INFO}" ${VERSION_LOC} 1 NETCDF_MAJOR_VERSION)
if ("${NETCDF_MAJOR_VERSION}" LESS 4)
message(FATAL_ERROR "
Current NETCDF is ${NETCDF_DIR}
!!!! NETCDF version 4.0 and above is required !!!!
")
endif()

set (NetCDF_has_interfaces "YES") # will be set to NO if we're missing any interfaces
set (NetCDF_libs ${NETCDF_LIBRARIES_C} ${NETCDF_LIBRARIES_Fortran})
get_filename_component (NetCDF_lib_dirs "${NETCDF_LIBRARIES_C}" PATH)

macro (NetCDF_check_interface lang header libs)
if (NETCDF_${lang})
find_path (NETCDF_INCLUDES_${lang} NAMES ${header}
HINTS ${NETCDF_INCLUDES} ${NETCDF_FORTRAN}/include NO_DEFAULT_PATH)
find_library (NETCDF_LIBRARIES_${lang} NAMES ${libs}
HINTS ${NetCDF_lib_dirs} ${NETCDF_FORTRAN}/lib NO_DEFAULT_PATH)
mark_as_advanced (NETCDF_INCLUDES_${lang} NETCDF_LIBRARIES_${lang})
if (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
list (INSERT NetCDF_libs 0 ${NETCDF_LIBRARIES_${lang}}) # prepend so that -lnetcdf is last
else (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
set (NetCDF_has_interfaces "NO")
message (STATUS "Failed to find NetCDF interface for ${lang}")
endif (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
endif (NETCDF_${lang})
endmacro (NetCDF_check_interface)

set(NETCDF_F90 true)
set(NETCDF_F77 true)

NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++)
NetCDF_check_interface (F77 netcdf.inc netcdff)
NetCDF_check_interface (F90 netcdf.mod netcdff)
if( NETCDF_LIBRARIES_F90 )
set( NETCDF4 "YES" )
endif()
endif()

macro (NetCDF_check_interface lang header libs)
if (NETCDF_${lang})
find_path (NETCDF_INCLUDES_${lang} NAMES ${header}
HINTS ${NETCDF_INCLUDES} ${NETCDF_FORTRAN}/include NO_DEFAULT_PATH)
find_library (NETCDF_LIBRARIES_${lang} NAMES ${libs}
HINTS ${NetCDF_lib_dirs} ${NETCDF_FORTRAN}/lib NO_DEFAULT_PATH)
mark_as_advanced (NETCDF_INCLUDES_${lang} NETCDF_LIBRARIES_${lang})
if (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
list (INSERT NetCDF_libs 0 ${NETCDF_LIBRARIES_${lang}}) # prepend so that -lnetcdf is last
else (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
set (NetCDF_has_interfaces "NO")
message (STATUS "Failed to find NetCDF interface for ${lang}")
endif (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
endif (NETCDF_${lang})
endmacro (NetCDF_check_interface)

set(NETCDF_F90 true)
set(NETCDF_F77 true)

NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++)
NetCDF_check_interface (F77 netcdf.inc netcdff)
NetCDF_check_interface (F90 netcdf.mod netcdff)
if( NETCDF_LIBRARIES_F90 )
set( NETCDF4 "YES" )
endif()

set (NETCDF_LIBRARIES "${NetCDF_libs}" CACHE STRING "All NetCDF libraries required for interface level")

if(NETCDF_IS_STATIC)
find_package(HDF5 MODULE COMPONENTS C HL REQUIRED)
find_package(ZLIB MODULE REQUIRED)
set(NETCDF_LIBRARIES "${NETCDF_LIBRARIES};${HDF5_HL_LIBRARIES};${HDF5_LIBRARIES};${ZLIB_LIBRARIES}")
endif()
endif(PKG_CONFIG_FOUND)
endif (NOT NETCDF_INCLUDES OR NOT NETCDF_LIBRARIES)

# handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if
# all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (NetCDF DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDES NetCDF_has_interfaces)
find_package_handle_standard_args (NETCDF_LIBRARIES NETCDF_INCLUDES)

mark_as_advanced (NETCDF_LIBRARIES NETCDF_INCLUDES)

0 comments on commit b605db0

Please sign in to comment.