Skip to content

Commit 382ea72

Browse files
committed
.\cmake\FindHDF5.cmake
findhdf5 template
1 parent 17b14c4 commit 382ea72

File tree

6 files changed

+76
-33
lines changed

6 files changed

+76
-33
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ include(cmake/compilers.cmake)
2424

2525
file(GENERATE OUTPUT .gitignore CONTENT "*")
2626

27-
if(find)
27+
if(find_netcdf)
2828
find_package(NetCDF COMPONENTS C Fortran)
2929
endif()
3030
if(NOT NetCDF_FOUND AND NOT TARGET NetCDF::NetCDF_Fortran)

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ cmake -DNetCDF_ROOT=/path/to/netcdff -B build
6767

6868
or set environment variable `NetCDF_ROOT=/path/to/netcdff`
6969

70+
To not find existing netCDF (force build of netCDF from source) add option:
71+
72+
```sh
73+
cmake -Dfind_netcdf=off -Bbuild
74+
```
75+
7076
To use nc4fortran as a CMake ExternalProject do like:
7177

7278
```cmake

cmake/FindHDF5.cmake

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ message(DEBUG "HDF5 version match 0, 1: ${CMAKE_MATCH_0} ${CMAKE_MATCH_1}")
157157

158158
# avoid picking up incompatible zlib over the desired zlib
159159
if(NOT ZLIB_ROOT)
160-
get_filename_component(ZLIB_ROOT ${HDF5_C_INCLUDE_DIR} DIRECTORY)
160+
cmake_path(GET HDF5_C_INCLUDE_DIR PARENT_PATH ZLIB_ROOT)
161161
list(APPEND ZLIB_ROOT ${HDF5_ROOT})
162162
endif()
163163

@@ -182,16 +182,19 @@ if(hdf5_have_zlib)
182182
NAMES szip sz
183183
NAMES_PER_DIR
184184
HINTS ${SZIP_ROOT} ${ZLIB_ROOT}
185+
PATH_SUFFIXES lib lib64
185186
DOC "SZIP API"
186187
)
187188

188189
find_path(SZIP_INCLUDE_DIR
189190
NAMES szlib.h
190191
HINTS ${SZIP_ROOT} ${ZLIB_ROOT}
192+
PATH_SUFFIXES include
191193
DOC "SZIP header"
192194
)
193195

194-
if(NOT SZIP_LIBRARY AND SZIP_INCLUDE_DIR)
196+
if(NOT (SZIP_LIBRARY AND SZIP_INCLUDE_DIR))
197+
message(VERBOSE "FindHDF5: SZIP not found, but HDF5 indicates it was built with SZIP. This may cause build errors.")
195198
return()
196199
endif()
197200

@@ -226,6 +229,8 @@ endif()
226229

227230
hdf5_fortran_wrap(hdf5_lib_dirs hdf5_inc_dirs)
228231

232+
# "PATH" Env var is useful on HPC for finding HDF5 libraries
233+
229234
if(MSVC)
230235
set(CMAKE_FIND_LIBRARY_PREFIXES lib)
231236
endif()
@@ -236,7 +241,7 @@ set(_hl_stub_names hdf5_hl_f90cstub)
236241
set(_stub_names hdf5_f90cstub)
237242

238243
# distro names (Ubuntu)
239-
if(parallel IN_LIST HDF5_FIND_COMPONENTS)
244+
if(HDF5_parallel_FOUND)
240245
list(APPEND _names hdf5_openmpi_fortran hdf5_mpich_fortran)
241246
list(APPEND _hl_names hdf5_openmpihl_fortran hdf5_mpichhl_fortran)
242247
else()
@@ -265,28 +270,27 @@ NAMES_PER_DIR
265270
DOC "HDF5 Fortran API"
266271
)
267272

273+
cmake_path(GET HDF5_Fortran_LIBRARY PARENT_PATH hdf5_libdir)
274+
268275
find_library(HDF5_Fortran_HL_LIBRARY
269276
NAMES ${_hl_names}
270-
HINTS ${HDF5_ROOT} ${hdf5_lib_dirs}
271-
PATH_SUFFIXES ${hdf5_lsuf}
272-
NAMES_PER_DIR
277+
HINTS ${hdf5_libdir}
278+
NO_DEFAULT_PATH
273279
DOC "HDF5 Fortran HL high-level API"
274280
)
275281

276282
# not all platforms have this stub
277283
find_library(HDF5_Fortran_HL_stub
278284
NAMES ${_hl_stub_names}
279-
HINTS ${HDF5_ROOT} ${hdf5_lib_dirs}
280-
PATH_SUFFIXES ${hdf5_lsuf}
281-
NAMES_PER_DIR
285+
HINTS ${hdf5_libdir}
286+
NO_DEFAULT_PATH
282287
DOC "Fortran C HL interface, not all HDF5 implementations have/need this"
283288
)
284289

285290
find_library(HDF5_Fortran_stub
286291
NAMES ${_stub_names}
287-
HINTS ${HDF5_ROOT} ${hdf5_lib_dirs}
288-
PATH_SUFFIXES ${hdf5_lsuf}
289-
NAMES_PER_DIR
292+
HINTS ${hdf5_libdir}
293+
NO_DEFAULT_PATH
290294
DOC "Fortran C interface, not all HDF5 implementations have/need this"
291295
)
292296

@@ -303,7 +307,7 @@ if(HDF5_ROOT)
303307
DOC "HDF5 Fortran module path"
304308
)
305309
else()
306-
if(parallel IN_LIST HDF5_FIND_COMPONENTS)
310+
if(HDF5_parallel_FOUND)
307311
# HDF5-MPI system library presents a unique challenge, as when non-MPI HDF5 is
308312
# also installed, which is typically necessary for other system libraries, the
309313
# HDF5-MPI compiler wrapper often includes that wrong non-MPI include dir first.
@@ -362,8 +366,15 @@ endfunction(find_hdf5_fortran)
362366

363367
function(find_hdf5_cxx)
364368

369+
if(parallel IN_LIST HDF5_FIND_COMPONENTS AND NOT HDF5_parallel_FOUND)
370+
# avoid expensive C++ find when MPI isn't linked properly
371+
return()
372+
endif()
373+
365374
hdf5_cxx_wrap(hdf5_lib_dirs hdf5_inc_dirs)
366375

376+
# "PATH" Env var is useful on HPC for finding HDF5 libraries
377+
367378
if(MSVC)
368379
set(CMAKE_FIND_LIBRARY_PREFIXES lib)
369380
endif()
@@ -372,7 +383,7 @@ set(_names hdf5_cpp)
372383
set(_hl_names hdf5_hl_cpp)
373384

374385
# distro names (Ubuntu)
375-
if(parallel IN_LIST HDF5_FIND_COMPONENTS)
386+
if(HDF5_parallel_FOUND)
376387
list(APPEND _names hdf5_openmpi_cpp hdf5_mpich_cpp)
377388
list(APPEND _hl_names hdf5_openmpi_hl_cpp hdf5_mpich_hl_cpp)
378389
else()
@@ -397,11 +408,12 @@ NAMES_PER_DIR
397408
DOC "HDF5 C++ API"
398409
)
399410

411+
cmake_path(GET HDF5_CXX_LIBRARY PARENT_PATH hdf5_libdir)
412+
400413
find_library(HDF5_CXX_HL_LIBRARY
401414
NAMES ${_hl_names}
402-
HINTS ${HDF5_ROOT} ${hdf5_lib_dirs}
403-
PATH_SUFFIXES ${hdf5_lsuf}
404-
NAMES_PER_DIR
415+
HINTS ${hdf5_libdir}
416+
NO_DEFAULT_PATH
405417
DOC "HDF5 C++ high-level API"
406418
)
407419

@@ -425,6 +437,8 @@ function(find_hdf5_c)
425437

426438
hdf5_c_wrap(hdf5_lib_dirs hdf5_inc_dirs)
427439

440+
# "PATH" Env var is useful on HPC for finding HDF5 libraries
441+
428442
if(MSVC)
429443
set(CMAKE_FIND_LIBRARY_PREFIXES lib)
430444
endif()
@@ -459,11 +473,12 @@ NAMES_PER_DIR
459473
DOC "HDF5 C library (necessary for all languages)"
460474
)
461475

476+
cmake_path(GET HDF5_C_LIBRARY PARENT_PATH hdf5_libdir)
477+
462478
find_library(HDF5_C_HL_LIBRARY
463479
NAMES ${_hl_names}
464-
HINTS ${HDF5_ROOT} ${hdf5_lib_dirs}
465-
PATH_SUFFIXES ${hdf5_lsuf}
466-
NAMES_PER_DIR
480+
HINTS ${hdf5_libdir}
481+
NO_DEFAULT_PATH
467482
DOC "HDF5 C high level interface"
468483
)
469484

@@ -488,7 +503,7 @@ function(hdf5_fortran_wrap lib_var inc_var)
488503
set(lib_dirs)
489504
set(inc_dirs)
490505

491-
if(parallel IN_LIST HDF5_FIND_COMPONENTS)
506+
if(HDF5_parallel_FOUND)
492507
set(wrapper_names h5pfc h5pfc.openmpi h5pfc.mpich)
493508
else()
494509
set(wrapper_names h5fc)
@@ -545,7 +560,7 @@ function(hdf5_cxx_wrap lib_var inc_var)
545560
set(lib_dirs)
546561
set(inc_dirs)
547562

548-
if(parallel IN_LIST HDF5_FIND_COMPONENTS)
563+
if(HDF5_parallel_FOUND)
549564
set(wrapper_names h5c++.openmpi h5c++.mpich)
550565
else()
551566
set(wrapper_names h5c++)
@@ -897,17 +912,29 @@ if(HDF5_FOUND)
897912
set_property(TARGET HDF5::HDF5 PROPERTY INTERFACE_LINK_LIBRARIES "${HDF5_LIBRARIES}")
898913
set_property(TARGET HDF5::HDF5 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}")
899914

900-
target_include_directories(HDF5::HDF5 INTERFACE
901-
$<$<BOOL:${hdf5_have_szip}>:${SZIP_INCLUDE_DIR}>
902-
)
915+
if(hdf5_have_szip)
916+
if(IS_DIRECTORY "${SZIP_INCLUDE_DIR}")
917+
target_include_directories(HDF5::HDF5 INTERFACE ${SZIP_INCLUDE_DIR})
918+
else()
919+
message(STATUS "FindHDF5: SZIP_INCLUDE_DIR ${SZIP_INCLUDE_DIR} is not a directory.")
920+
endif()
921+
endif()
922+
923+
target_link_libraries(HDF5::HDF5 INTERFACE $<$<BOOL:${hdf5_have_zlib}>:ZLIB::ZLIB>)
924+
925+
if(hdf5_have_szip)
926+
if(EXISTS "${SZIP_LIBRARY}")
927+
target_link_libraries(HDF5::HDF5 INTERFACE ${SZIP_LIBRARY})
928+
else()
929+
message(STATUS "FindHDF5: SZIP_LIBRARY ${SZIP_LIBRARY} is not a file.")
930+
endif()
931+
endif()
932+
903933
target_link_libraries(HDF5::HDF5 INTERFACE
904-
$<$<BOOL:${hdf5_have_zlib}>:ZLIB::ZLIB>
905-
$<$<BOOL:${hdf5_have_szip}>:${SZIP_LIBRARY}>
906934
${CMAKE_THREAD_LIBS_INIT}
907935
${CMAKE_DL_LIBS}
908936
$<$<BOOL:${UNIX}>:m>
909937
)
910-
911938
endif()
912939
endif(HDF5_FOUND)
913940

cmake/netcdf.cmake

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ if(NOT DEFINED HDF5_ROOT AND DEFINED ENV{HDF5_ROOT})
1111
set(HDF5_ROOT $ENV{HDF5_ROOT})
1212
endif()
1313

14-
find_package(HDF5 COMPONENTS C Fortran)
14+
if(find_hdf5)
15+
find_package(HDF5 COMPONENTS C Fortran)
16+
endif()
1517
if(HDF5_FOUND)
1618
add_custom_target(HDF5)
1719
else()
@@ -20,7 +22,9 @@ endif()
2022

2123
# --- NetCDF-C
2224

23-
find_package(NetCDF COMPONENTS C)
25+
if(find_netcdf)
26+
find_package(NetCDF COMPONENTS C)
27+
endif()
2428
if(NetCDF_C_FOUND)
2529
add_custom_target(NETCDF_C)
2630
else()

options.cmake

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ message(STATUS "${PROJECT_NAME} ${PROJECT_VERSION} CMake ${CMAKE_VERSION} Toolch
22

33
option(nc4fortran_COVERAGE "Code coverage tests")
44
option(tidy "Run clang-tidy on the code")
5-
option(find "find NetCDF libraries" ON)
5+
6+
option(find_hdf5 "find HDF5 libraries" ON)
7+
option(find_netcdf "find NetCDF libraries" ON)
68

79
option(nc4fortran_BUILD_TESTING "Build tests" ${nc4fortran_IS_TOP_LEVEL})
810

911
set_property(DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED true)
1012

1113
# Necessary for shared library with Visual Studio / Windows oneAPI
1214
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true)
15+
16+
if(nc4fortran_IS_TOP_LEVEL AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
17+
set_property(CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE "${PROJECT_BINARY_DIR}/local")
18+
endif()

test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ set_property(TEST deflate_props deflate_read PROPERTY FIXTURES_REQUIRED deflate_
3535
set_property(TEST deflate_props deflate_read PROPERTY REQUIRED_FILES ${CMAKE_CURRENT_BINARY_DIR}/deflate1.nc)
3636

3737

38-
if(${PROJECT_NAME}_COVERAGE)
38+
if(nc4fortran_COVERAGE)
3939
setup_target_for_coverage_gcovr_html(
4040
NAME coverage
4141
EXECUTABLE ${CMAKE_CTEST_COMMAND}

0 commit comments

Comments
 (0)