Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Modules / FindHDF5.cmake
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
3
4 #[=======================================================================[.rst:
5 FindHDF5
6 --------
7
8 Find Hierarchical Data Format (HDF5), a library for reading and writing
9 self describing array data.
10
11
12 This module invokes the ``HDF5`` wrapper compiler that should be installed
13 alongside ``HDF5``.  Depending upon the ``HDF5`` Configuration, the wrapper
14 compiler is called either ``h5cc`` or ``h5pcc``.  If this succeeds, the module
15 will then call the compiler with the show argument to see what flags
16 are used when compiling an ``HDF5`` client application.
17
18 The module will optionally accept the ``COMPONENTS`` argument.  If no
19 ``COMPONENTS`` are specified, then the find module will default to finding
20 only the ``HDF5`` C library.  If one or more ``COMPONENTS`` are specified, the
21 module will attempt to find the language bindings for the specified
22 components.  The valid components are ``C``, ``CXX``, ``Fortran``, ``HL``.
23 ``HL`` refers to the "high-level" HDF5 functions for C and Fortran.
24 If the ``COMPONENTS`` argument is not given, the module will
25 attempt to find only the C bindings.
26 For example, to use Fortran HDF5 and HDF5-HL functions, do:
27 ``find_package(HDF5 COMPONENTS Fortran HL)``.
28
29 This module will read the variable
30 ``HDF5_USE_STATIC_LIBRARIES`` to determine whether or not to prefer a
31 static link to a dynamic link for ``HDF5`` and all of it's dependencies.
32 To use this feature, make sure that the ``HDF5_USE_STATIC_LIBRARIES``
33 variable is set before the call to find_package.
34
35 .. versionadded:: 3.10
36   Support for ``HDF5_USE_STATIC_LIBRARIES`` on Windows.
37
38 Both the serial and parallel ``HDF5`` wrappers are considered and the first
39 directory to contain either one will be used.  In the event that both appear
40 in the same directory the serial version is preferentially selected. This
41 behavior can be reversed by setting the variable ``HDF5_PREFER_PARALLEL`` to
42 ``TRUE``.
43
44 In addition to finding the includes and libraries required to compile
45 an ``HDF5`` client application, this module also makes an effort to find
46 tools that come with the ``HDF5`` distribution that may be useful for
47 regression testing.
48
49 Result Variables
50 ^^^^^^^^^^^^^^^^
51
52 This module will set the following variables in your project:
53
54 ``HDF5_FOUND``
55   HDF5 was found on the system
56 ``HDF5_VERSION``
57   .. versionadded:: 3.3
58     HDF5 library version
59 ``HDF5_INCLUDE_DIRS``
60   Location of the HDF5 header files
61 ``HDF5_DEFINITIONS``
62   Required compiler definitions for HDF5
63 ``HDF5_LIBRARIES``
64   Required libraries for all requested bindings
65 ``HDF5_HL_LIBRARIES``
66   Required libraries for the HDF5 high level API for all bindings,
67   if the ``HL`` component is enabled
68
69 Available components are: ``C`` ``CXX`` ``Fortran`` and ``HL``.
70 For each enabled language binding, a corresponding ``HDF5_${LANG}_LIBRARIES``
71 variable, and potentially ``HDF5_${LANG}_DEFINITIONS``, will be defined.
72 If the ``HL`` component is enabled, then an ``HDF5_${LANG}_HL_LIBRARIES`` will
73 also be defined.  With all components enabled, the following variables will be defined:
74
75 ``HDF5_C_DEFINITIONS``
76   Required compiler definitions for HDF5 C bindings
77 ``HDF5_CXX_DEFINITIONS``
78   Required compiler definitions for HDF5 C++ bindings
79 ``HDF5_Fortran_DEFINITIONS``
80   Required compiler definitions for HDF5 Fortran bindings
81 ``HDF5_C_INCLUDE_DIRS``
82   Required include directories for HDF5 C bindings
83 ``HDF5_CXX_INCLUDE_DIRS``
84   Required include directories for HDF5 C++ bindings
85 ``HDF5_Fortran_INCLUDE_DIRS``
86   Required include directories for HDF5 Fortran bindings
87 ``HDF5_C_LIBRARIES``
88   Required libraries for the HDF5 C bindings
89 ``HDF5_CXX_LIBRARIES``
90   Required libraries for the HDF5 C++ bindings
91 ``HDF5_Fortran_LIBRARIES``
92   Required libraries for the HDF5 Fortran bindings
93 ``HDF5_C_HL_LIBRARIES``
94   Required libraries for the high level C bindings
95 ``HDF5_CXX_HL_LIBRARIES``
96   Required libraries for the high level C++ bindings
97 ``HDF5_Fortran_HL_LIBRARIES``
98   Required libraries for the high level Fortran bindings.
99
100 ``HDF5_IS_PARALLEL``
101   HDF5 library has parallel IO support
102 ``HDF5_C_COMPILER_EXECUTABLE``
103   path to the HDF5 C wrapper compiler
104 ``HDF5_CXX_COMPILER_EXECUTABLE``
105   path to the HDF5 C++ wrapper compiler
106 ``HDF5_Fortran_COMPILER_EXECUTABLE``
107   path to the HDF5 Fortran wrapper compiler
108 ``HDF5_C_COMPILER_EXECUTABLE_NO_INTERROGATE``
109   path to the primary C compiler which is also the HDF5 wrapper
110 ``HDF5_CXX_COMPILER_EXECUTABLE_NO_INTERROGATE``
111   path to the primary C++ compiler which is also the HDF5 wrapper
112 ``HDF5_Fortran_COMPILER_EXECUTABLE_NO_INTERROGATE``
113   path to the primary Fortran compiler which is also the HDF5 wrapper
114 ``HDF5_DIFF_EXECUTABLE``
115   path to the HDF5 dataset comparison tool
116
117 With all components enabled, the following targets will be defined:
118
119 ``HDF5::HDF5``
120   All detected ``HDF5_LIBRARIES``.
121 ``hdf5::hdf5``
122   C library.
123 ``hdf5::hdf5_cpp``
124   C++ library.
125 ``hdf5::hdf5_fortran``
126   Fortran library.
127 ``hdf5::hdf5_hl``
128   High-level C library.
129 ``hdf5::hdf5_hl_cpp``
130   High-level C++ library.
131 ``hdf5::hdf5_hl_fortran``
132   High-level Fortran library.
133 ``hdf5::h5diff``
134   ``h5diff`` executable.
135
136 Hints
137 ^^^^^
138
139 The following variables can be set to guide the search for HDF5 libraries and includes:
140
141 ``HDF5_PREFER_PARALLEL``
142   .. versionadded:: 3.4
143
144   set ``true`` to prefer parallel HDF5 (by default, serial is preferred)
145
146 ``HDF5_FIND_DEBUG``
147   .. versionadded:: 3.9
148
149   Set ``true`` to get extra debugging output.
150
151 ``HDF5_NO_FIND_PACKAGE_CONFIG_FILE``
152   .. versionadded:: 3.8
153
154   Set ``true`` to skip trying to find ``hdf5-config.cmake``.
155 #]=======================================================================]
156
157 include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
158 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
159
160 # We haven't found HDF5 yet. Clear its state in case it is set in the parent
161 # scope somewhere else. We can't rely on it because different components may
162 # have been requested for this call.
163 set(HDF5_FOUND OFF)
164 set(HDF5_LIBRARIES)
165 set(HDF5_HL_LIBRARIES)
166
167 # List of the valid HDF5 components
168 set(HDF5_VALID_LANGUAGE_BINDINGS C CXX Fortran)
169
170 # Validate the list of find components.
171 if(NOT HDF5_FIND_COMPONENTS)
172   set(HDF5_LANGUAGE_BINDINGS "C")
173 else()
174   set(HDF5_LANGUAGE_BINDINGS)
175   # add the extra specified components, ensuring that they are valid.
176   set(HDF5_FIND_HL OFF)
177   foreach(_component IN LISTS HDF5_FIND_COMPONENTS)
178     list(FIND HDF5_VALID_LANGUAGE_BINDINGS ${_component} _component_location)
179     if(NOT _component_location EQUAL -1)
180       list(APPEND HDF5_LANGUAGE_BINDINGS ${_component})
181     elseif(_component STREQUAL "HL")
182       set(HDF5_FIND_HL ON)
183     elseif(_component STREQUAL "Fortran_HL") # only for compatibility
184       list(APPEND HDF5_LANGUAGE_BINDINGS Fortran)
185       set(HDF5_FIND_HL ON)
186       set(HDF5_FIND_REQUIRED_Fortran_HL FALSE)
187       set(HDF5_FIND_REQUIRED_Fortran TRUE)
188       set(HDF5_FIND_REQUIRED_HL TRUE)
189     else()
190       message(FATAL_ERROR "${_component} is not a valid HDF5 component.")
191     endif()
192   endforeach()
193   unset(_component)
194   unset(_component_location)
195   if(NOT HDF5_LANGUAGE_BINDINGS)
196     get_property(_langs GLOBAL PROPERTY ENABLED_LANGUAGES)
197     foreach(_lang IN LISTS _langs)
198       if(_lang MATCHES "^(C|CXX|Fortran)$")
199         list(APPEND HDF5_LANGUAGE_BINDINGS ${_lang})
200       endif()
201     endforeach()
202   endif()
203   list(REMOVE_ITEM HDF5_FIND_COMPONENTS Fortran_HL) # replaced by Fortran and HL
204   list(REMOVE_DUPLICATES HDF5_LANGUAGE_BINDINGS)
205 endif()
206
207 # Determine whether to search for serial or parallel executable first
208 if(HDF5_PREFER_PARALLEL)
209   set(HDF5_C_COMPILER_NAMES h5pcc h5cc)
210   set(HDF5_CXX_COMPILER_NAMES h5pc++ h5c++)
211   set(HDF5_Fortran_COMPILER_NAMES h5pfc h5fc)
212 else()
213   set(HDF5_C_COMPILER_NAMES h5cc h5pcc)
214   set(HDF5_CXX_COMPILER_NAMES h5c++ h5pc++)
215   set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc)
216 endif()
217
218 # Test first if the current compilers automatically wrap HDF5
219 function(_HDF5_test_regular_compiler_C success version is_parallel)
220   set(scratch_directory
221     ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5)
222   if(NOT ${success} OR
223      NOT EXISTS ${scratch_directory}/compiler_has_h5_c)
224     set(test_file ${scratch_directory}/cmake_hdf5_test.c)
225     file(WRITE ${test_file}
226       "#include <hdf5.h>\n"
227       "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n"
228       "#ifdef H5_HAVE_PARALLEL\n"
229       "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n"
230       "#endif\n"
231       "int main(int argc, char **argv) {\n"
232       "  int require = 0;\n"
233       "  require += info_ver[argc];\n"
234       "#ifdef H5_HAVE_PARALLEL\n"
235       "  require += info_parallel[argc];\n"
236       "#endif\n"
237       "  hid_t fid;\n"
238       "  fid = H5Fcreate(\"foo.h5\",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);\n"
239       "  return 0;\n"
240       "}")
241     try_compile(${success} SOURCES ${test_file}
242       COPY_FILE ${scratch_directory}/compiler_has_h5_c
243     )
244   endif()
245   if(${success} AND EXISTS ${scratch_directory}/compiler_has_h5_c)
246     file(STRINGS ${scratch_directory}/compiler_has_h5_c INFO_STRINGS
247       REGEX "^INFO:"
248     )
249     string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?"
250       INFO_VER "${INFO_STRINGS}"
251     )
252     set(${version} ${CMAKE_MATCH_1})
253     if(CMAKE_MATCH_3)
254       set(${version} ${HDF5_C_VERSION}.${CMAKE_MATCH_3})
255     endif()
256     set(${version} ${${version}} PARENT_SCOPE)
257
258     if(INFO_STRINGS MATCHES "INFO:PARALLEL")
259       set(${is_parallel} TRUE PARENT_SCOPE)
260     else()
261       set(${is_parallel} FALSE PARENT_SCOPE)
262     endif()
263   endif()
264 endfunction()
265
266 function(_HDF5_test_regular_compiler_CXX success version is_parallel)
267   set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5)
268   if(NOT ${success} OR
269      NOT EXISTS ${scratch_directory}/compiler_has_h5_cxx)
270     set(test_file ${scratch_directory}/cmake_hdf5_test.cxx)
271     file(WRITE ${test_file}
272       "#include <H5Cpp.h>\n"
273       "#ifndef H5_NO_NAMESPACE\n"
274       "using namespace H5;\n"
275       "#endif\n"
276       "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n"
277       "#ifdef H5_HAVE_PARALLEL\n"
278       "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n"
279       "#endif\n"
280       "int main(int argc, char **argv) {\n"
281       "  int require = 0;\n"
282       "  require += info_ver[argc];\n"
283       "#ifdef H5_HAVE_PARALLEL\n"
284       "  require += info_parallel[argc];\n"
285       "#endif\n"
286       "  H5File file(\"foo.h5\", H5F_ACC_TRUNC);\n"
287       "  return 0;\n"
288       "}")
289     try_compile(${success} SOURCES ${test_file}
290       COPY_FILE ${scratch_directory}/compiler_has_h5_cxx
291     )
292   endif()
293   if(${success} AND EXISTS ${scratch_directory}/compiler_has_h5_cxx)
294     file(STRINGS ${scratch_directory}/compiler_has_h5_cxx INFO_STRINGS
295       REGEX "^INFO:"
296     )
297     string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?"
298       INFO_VER "${INFO_STRINGS}"
299     )
300     set(${version} ${CMAKE_MATCH_1})
301     if(CMAKE_MATCH_3)
302       set(${version} ${HDF5_CXX_VERSION}.${CMAKE_MATCH_3})
303     endif()
304     set(${version} ${${version}} PARENT_SCOPE)
305
306     if(INFO_STRINGS MATCHES "INFO:PARALLEL")
307       set(${is_parallel} TRUE PARENT_SCOPE)
308     else()
309       set(${is_parallel} FALSE PARENT_SCOPE)
310     endif()
311   endif()
312 endfunction()
313
314 function(_HDF5_test_regular_compiler_Fortran success is_parallel)
315   if(NOT ${success})
316     set(scratch_directory
317       ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5)
318     set(test_file ${scratch_directory}/cmake_hdf5_test.f90)
319     file(WRITE ${test_file}
320       "program hdf5_hello\n"
321       "  use hdf5\n"
322       "  integer error\n"
323       "  call h5open_f(error)\n"
324       "  call h5close_f(error)\n"
325       "end\n")
326     try_compile(${success} SOURCES ${test_file})
327     if(${success})
328       execute_process(COMMAND ${CMAKE_Fortran_COMPILER} -showconfig
329         OUTPUT_VARIABLE config_output
330         ERROR_VARIABLE config_error
331         RESULT_VARIABLE config_result
332         )
333       if(config_output MATCHES "Parallel HDF5: yes")
334         set(${is_parallel} TRUE PARENT_SCOPE)
335       else()
336         set(${is_parallel} FALSE PARENT_SCOPE)
337       endif()
338     endif()
339   endif()
340 endfunction()
341
342 # Invoke the HDF5 wrapper compiler.  The compiler return value is stored to the
343 # return_value argument, the text output is stored to the output variable.
344 function( _HDF5_invoke_compiler language output_var return_value_var version_var is_parallel_var)
345   set(is_parallel FALSE)
346   if(HDF5_USE_STATIC_LIBRARIES)
347     set(lib_type_args -noshlib)
348   else()
349     set(lib_type_args -shlib)
350   endif()
351   set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5)
352   if("${language}" STREQUAL "C")
353     set(test_file ${scratch_dir}/cmake_hdf5_test.c)
354   elseif("${language}" STREQUAL "CXX")
355     set(test_file ${scratch_dir}/cmake_hdf5_test.cxx)
356   elseif("${language}" STREQUAL "Fortran")
357     set(test_file ${scratch_dir}/cmake_hdf5_test.f90)
358   endif()
359   # Verify that the compiler wrapper can actually compile: sometimes the compiler
360   # wrapper exists, but not the compiler.  E.g. Miniconda / Anaconda Python
361   execute_process(
362     COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file}
363     WORKING_DIRECTORY ${scratch_dir}
364     OUTPUT_VARIABLE output
365     ERROR_VARIABLE output
366     RESULT_VARIABLE return_value
367     )
368   if(return_value AND NOT HDF5_FIND_QUIETLY)
369     message(STATUS
370       "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.")
371   else()
372     execute_process(
373       COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file}
374       WORKING_DIRECTORY ${scratch_dir}
375       OUTPUT_VARIABLE output
376       ERROR_VARIABLE output
377       RESULT_VARIABLE return_value
378       OUTPUT_STRIP_TRAILING_WHITESPACE
379       )
380     if(return_value AND NOT HDF5_FIND_QUIETLY)
381       message(STATUS
382         "Unable to determine HDF5 ${language} flags from HDF5 wrapper.")
383     endif()
384     execute_process(
385       COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig
386       OUTPUT_VARIABLE config_output
387       ERROR_VARIABLE config_output
388       RESULT_VARIABLE return_value
389       OUTPUT_STRIP_TRAILING_WHITESPACE
390       )
391     if(return_value AND NOT HDF5_FIND_QUIETLY)
392       message(STATUS
393         "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.")
394     endif()
395     string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version "${config_output}")
396     if(version)
397       string(REPLACE "HDF5 Version: " "" version "${version}")
398       string(REPLACE "-patch" "." version "${version}")
399     endif()
400     if(config_output MATCHES "Parallel HDF5: yes")
401       set(is_parallel TRUE)
402     endif()
403   endif()
404   foreach(var output return_value version is_parallel)
405     set(${${var}_var} ${${var}} PARENT_SCOPE)
406   endforeach()
407 endfunction()
408
409 # Parse a compile line for definitions, includes, library paths, and libraries.
410 function(_HDF5_parse_compile_line compile_line_var include_paths definitions
411     library_paths libraries libraries_hl)
412
413   separate_arguments(_compile_args NATIVE_COMMAND "${${compile_line_var}}")
414
415   foreach(_arg IN LISTS _compile_args)
416     if("${_arg}" MATCHES "^-I(.*)$")
417       # include directory
418       list(APPEND include_paths "${CMAKE_MATCH_1}")
419     elseif("${_arg}" MATCHES "^-D(.*)$")
420       # compile definition
421       list(APPEND definitions "-D${CMAKE_MATCH_1}")
422     elseif("${_arg}" MATCHES "^-L(.*)$")
423       # library search path
424       list(APPEND library_paths "${CMAKE_MATCH_1}")
425     elseif("${_arg}" MATCHES "^-l(hdf5.*hl.*)$")
426       # library name (hl)
427       list(APPEND libraries_hl "${CMAKE_MATCH_1}")
428     elseif("${_arg}" MATCHES "^-l(.*)$")
429       # library name
430       list(APPEND libraries "${CMAKE_MATCH_1}")
431     elseif("${_arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$")
432       # library file
433       if(NOT EXISTS "${_arg}")
434         continue()
435       endif()
436       get_filename_component(_lpath "${_arg}" DIRECTORY)
437       get_filename_component(_lname "${_arg}" NAME_WE)
438       string(REGEX REPLACE "^lib" "" _lname "${_lname}")
439       list(APPEND library_paths "${_lpath}")
440       if(_lname MATCHES "hdf5.*hl")
441         list(APPEND libraries_hl "${_lname}")
442       else()
443         list(APPEND libraries "${_lname}")
444       endif()
445     endif()
446   endforeach()
447   foreach(var include_paths definitions library_paths libraries libraries_hl)
448     set(${${var}_var} ${${var}} PARENT_SCOPE)
449   endforeach()
450 endfunction()
451
452 # Select a preferred imported configuration from a target
453 function(_HDF5_select_imported_config target imported_conf)
454     # We will first assign the value to a local variable _imported_conf, then assign
455     # it to the function argument at the end.
456     get_target_property(_imported_conf ${target} MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE})
457     if (NOT _imported_conf)
458         # Get available imported configurations by examining target properties
459         get_target_property(_imported_conf ${target} IMPORTED_CONFIGURATIONS)
460         if(HDF5_FIND_DEBUG)
461             message(STATUS "Found imported configurations: ${_imported_conf}")
462         endif()
463         # Find the imported configuration that we prefer.
464         # We do this by making list of configurations in order of preference,
465         # starting with ${CMAKE_BUILD_TYPE} and ending with the first imported_conf
466         set(_preferred_confs ${CMAKE_BUILD_TYPE})
467         list(GET _imported_conf 0 _fallback_conf)
468         list(APPEND _preferred_confs RELWITHDEBINFO RELEASE DEBUG ${_fallback_conf})
469         if(HDF5_FIND_DEBUG)
470             message(STATUS "Start search through imported configurations in the following order: ${_preferred_confs}")
471         endif()
472         # Now find the first of these that is present in imported_conf
473         cmake_policy(PUSH)
474         cmake_policy(SET CMP0057 NEW) # support IN_LISTS
475         foreach (_conf IN LISTS _preferred_confs)
476             if (${_conf} IN_LIST _imported_conf)
477                set(_imported_conf ${_conf})
478                break()
479             endif()
480         endforeach()
481         cmake_policy(POP)
482     endif()
483     if(HDF5_FIND_DEBUG)
484         message(STATUS "Selected imported configuration: ${_imported_conf}")
485     endif()
486     # assign value to function argument
487     set(${imported_conf} ${_imported_conf} PARENT_SCOPE)
488 endfunction()
489
490
491 if(NOT HDF5_ROOT)
492     set(HDF5_ROOT $ENV{HDF5_ROOT})
493 endif()
494 if(HDF5_ROOT)
495     set(_HDF5_SEARCH_OPTS NO_DEFAULT_PATH)
496 else()
497     set(_HDF5_SEARCH_OPTS)
498 endif()
499
500 # Try to find HDF5 using an installed hdf5-config.cmake
501 if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE)
502     find_package(HDF5 QUIET NO_MODULE
503       HINTS ${HDF5_ROOT}
504       ${_HDF5_SEARCH_OPTS}
505       )
506     if( HDF5_FOUND)
507         if(HDF5_FIND_DEBUG)
508             message(STATUS "Found HDF5 at ${HDF5_DIR} via NO_MODULE. Now trying to extract locations etc.")
509         endif()
510         set(HDF5_IS_PARALLEL ${HDF5_ENABLE_PARALLEL})
511         set(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR})
512         set(HDF5_LIBRARIES)
513         if (NOT TARGET hdf5 AND NOT TARGET hdf5-static AND NOT TARGET hdf5-shared)
514             # Some HDF5 versions (e.g. 1.8.18) used hdf5::hdf5 etc
515             set(_target_prefix "hdf5::")
516         endif()
517         set(HDF5_C_TARGET ${_target_prefix}hdf5)
518         set(HDF5_C_HL_TARGET ${_target_prefix}hdf5_hl)
519         set(HDF5_CXX_TARGET ${_target_prefix}hdf5_cpp)
520         set(HDF5_CXX_HL_TARGET ${_target_prefix}hdf5_hl_cpp)
521         set(HDF5_Fortran_TARGET ${_target_prefix}hdf5_fortran)
522         set(HDF5_Fortran_HL_TARGET ${_target_prefix}hdf5_hl_fortran)
523         set(HDF5_DEFINITIONS "")
524         if(HDF5_USE_STATIC_LIBRARIES)
525             set(_suffix "-static")
526         else()
527             set(_suffix "-shared")
528         endif()
529         foreach(_lang ${HDF5_LANGUAGE_BINDINGS})
530
531             #Older versions of hdf5 don't have a static/shared suffix so
532             #if we detect that occurrence clear the suffix
533             if(_suffix AND NOT TARGET ${HDF5_${_lang}_TARGET}${_suffix})
534               if(NOT TARGET ${HDF5_${_lang}_TARGET})
535                 #can't find this component with or without the suffix
536                 #so bail out, and let the following locate HDF5
537                 set(HDF5_FOUND FALSE)
538                 break()
539               endif()
540               set(_suffix "")
541             endif()
542
543             if(HDF5_FIND_DEBUG)
544                 message(STATUS "Trying to get properties of target ${HDF5_${_lang}_TARGET}${_suffix}")
545             endif()
546             # Find library for this target. Complicated as on Windows with a DLL, we need to search for the import-lib.
547             _HDF5_select_imported_config(${HDF5_${_lang}_TARGET}${_suffix} _hdf5_imported_conf)
548             get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} )
549             if (NOT _hdf5_lang_location)
550                 # no import lib, just try LOCATION
551                 get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf})
552                 if (NOT _hdf5_lang_location)
553                     get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION)
554                 endif()
555             endif()
556             if( _hdf5_lang_location )
557                 set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location})
558                 list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
559                 set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
560                 set(HDF5_${_lang}_FOUND TRUE)
561             endif()
562             if(HDF5_FIND_HL)
563                 get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} )
564                 if (NOT _hdf5_lang_hl_location)
565                     get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf})
566                     if (NOT _hdf5_hl_lang_location)
567                         get_target_property(_hdf5_hl_lang_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION)
568                     endif()
569                 endif()
570                 if( _hdf5_lang_hl_location )
571                     set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location})
572                     list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
573                     set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
574                     set(HDF5_HL_FOUND TRUE)
575                 endif()
576                 unset(_hdf5_lang_hl_location)
577             endif()
578             unset(_hdf5_imported_conf)
579             unset(_hdf5_lang_location)
580         endforeach()
581     endif()
582 endif()
583
584 if(NOT HDF5_FOUND)
585   set(_HDF5_NEED_TO_SEARCH FALSE)
586   set(HDF5_COMPILER_NO_INTERROGATE TRUE)
587   # Only search for languages we've enabled
588   foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
589     set(HDF5_${_lang}_LIBRARIES)
590     set(HDF5_${_lang}_HL_LIBRARIES)
591
592     # First check to see if our regular compiler is one of wrappers
593     if(_lang STREQUAL "C")
594       _HDF5_test_regular_compiler_C(
595         HDF5_${_lang}_COMPILER_NO_INTERROGATE
596         HDF5_${_lang}_VERSION
597         HDF5_${_lang}_IS_PARALLEL)
598     elseif(_lang STREQUAL "CXX")
599       _HDF5_test_regular_compiler_CXX(
600         HDF5_${_lang}_COMPILER_NO_INTERROGATE
601         HDF5_${_lang}_VERSION
602         HDF5_${_lang}_IS_PARALLEL)
603     elseif(_lang STREQUAL "Fortran")
604       _HDF5_test_regular_compiler_Fortran(
605         HDF5_${_lang}_COMPILER_NO_INTERROGATE
606         HDF5_${_lang}_IS_PARALLEL)
607     else()
608       continue()
609     endif()
610     if(HDF5_${_lang}_COMPILER_NO_INTERROGATE)
611       if(HDF5_FIND_DEBUG)
612         message(STATUS "HDF5: Using hdf5 compiler wrapper for all ${_lang} compiling")
613       endif()
614       set(HDF5_${_lang}_FOUND TRUE)
615       set(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE
616           "${CMAKE_${_lang}_COMPILER}"
617           CACHE FILEPATH "HDF5 ${_lang} compiler wrapper")
618       set(HDF5_${_lang}_DEFINITIONS)
619       set(HDF5_${_lang}_INCLUDE_DIRS)
620       set(HDF5_${_lang}_LIBRARIES)
621       set(HDF5_${_lang}_HL_LIBRARIES)
622
623       mark_as_advanced(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE)
624
625       set(HDF5_${_lang}_FOUND TRUE)
626       set(HDF5_HL_FOUND TRUE)
627     else()
628       set(HDF5_COMPILER_NO_INTERROGATE FALSE)
629       # If this language isn't using the wrapper, then try to seed the
630       # search options with the wrapper
631       find_program(HDF5_${_lang}_COMPILER_EXECUTABLE
632         NAMES ${HDF5_${_lang}_COMPILER_NAMES} NAMES_PER_DIR
633         HINTS ${HDF5_ROOT}
634         PATH_SUFFIXES bin Bin
635         DOC "HDF5 ${_lang} Wrapper compiler.  Used only to detect HDF5 compile flags."
636         ${_HDF5_SEARCH_OPTS}
637       )
638       mark_as_advanced( HDF5_${_lang}_COMPILER_EXECUTABLE )
639       unset(HDF5_${_lang}_COMPILER_NAMES)
640
641       if(HDF5_${_lang}_COMPILER_EXECUTABLE)
642         _HDF5_invoke_compiler(${_lang} HDF5_${_lang}_COMPILE_LINE
643           HDF5_${_lang}_RETURN_VALUE HDF5_${_lang}_VERSION HDF5_${_lang}_IS_PARALLEL)
644         if(HDF5_${_lang}_RETURN_VALUE EQUAL 0)
645           if(HDF5_FIND_DEBUG)
646             message(STATUS "HDF5: Using hdf5 compiler wrapper to determine ${_lang} configuration")
647           endif()
648           _HDF5_parse_compile_line( HDF5_${_lang}_COMPILE_LINE
649             HDF5_${_lang}_INCLUDE_DIRS
650             HDF5_${_lang}_DEFINITIONS
651             HDF5_${_lang}_LIBRARY_DIRS
652             HDF5_${_lang}_LIBRARY_NAMES
653             HDF5_${_lang}_HL_LIBRARY_NAMES
654           )
655           set(HDF5_${_lang}_LIBRARIES)
656
657           foreach(_lib IN LISTS HDF5_${_lang}_LIBRARY_NAMES)
658             set(_HDF5_SEARCH_NAMES_LOCAL)
659             if("x${_lib}" MATCHES "hdf5")
660               # hdf5 library
661               set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS})
662               if(HDF5_USE_STATIC_LIBRARIES)
663                 if(WIN32)
664                   set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib})
665                 else()
666                   set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a)
667                 endif()
668               endif()
669             else()
670               # external library
671               set(_HDF5_SEARCH_OPTS_LOCAL)
672             endif()
673             find_library(HDF5_${_lang}_LIBRARY_${_lib}
674               NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR
675               HINTS ${HDF5_${_lang}_LIBRARY_DIRS}
676                     ${HDF5_ROOT}
677               ${_HDF5_SEARCH_OPTS_LOCAL}
678               )
679             unset(_HDF5_SEARCH_OPTS_LOCAL)
680             unset(_HDF5_SEARCH_NAMES_LOCAL)
681             if(HDF5_${_lang}_LIBRARY_${_lib})
682               list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}})
683             else()
684               list(APPEND HDF5_${_lang}_LIBRARIES ${_lib})
685             endif()
686           endforeach()
687           if(HDF5_FIND_HL)
688             set(HDF5_${_lang}_HL_LIBRARIES)
689             foreach(_lib IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES)
690               set(_HDF5_SEARCH_NAMES_LOCAL)
691               if("x${_lib}" MATCHES "hdf5")
692                 # hdf5 library
693                 set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS})
694                 if(HDF5_USE_STATIC_LIBRARIES)
695                   if(WIN32)
696                     set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib})
697                   else()
698                     set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a)
699                   endif()
700                 endif()
701               else()
702                 # external library
703                 set(_HDF5_SEARCH_OPTS_LOCAL)
704               endif()
705               find_library(HDF5_${_lang}_LIBRARY_${_lib}
706                 NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR
707                 HINTS ${HDF5_${_lang}_LIBRARY_DIRS}
708                       ${HDF5_ROOT}
709                 ${_HDF5_SEARCH_OPTS_LOCAL}
710                 )
711               unset(_HDF5_SEARCH_OPTS_LOCAL)
712               unset(_HDF5_SEARCH_NAMES_LOCAL)
713               if(HDF5_${_lang}_LIBRARY_${_lib})
714                 list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}})
715               else()
716                 list(APPEND HDF5_${_lang}_HL_LIBRARIES ${_lib})
717               endif()
718             endforeach()
719             set(HDF5_HL_FOUND TRUE)
720           endif()
721
722           set(HDF5_${_lang}_FOUND TRUE)
723           list(REMOVE_DUPLICATES HDF5_${_lang}_DEFINITIONS)
724           list(REMOVE_DUPLICATES HDF5_${_lang}_INCLUDE_DIRS)
725         else()
726           set(_HDF5_NEED_TO_SEARCH TRUE)
727         endif()
728       else()
729         set(_HDF5_NEED_TO_SEARCH TRUE)
730       endif()
731     endif()
732     if(HDF5_${_lang}_VERSION)
733       if(NOT HDF5_VERSION)
734         set(HDF5_VERSION ${HDF5_${_lang}_VERSION})
735       elseif(NOT HDF5_VERSION VERSION_EQUAL HDF5_${_lang}_VERSION)
736         message(WARNING "HDF5 Version found for language ${_lang}, ${HDF5_${_lang}_VERSION} is different than previously found version ${HDF5_VERSION}")
737       endif()
738     endif()
739     if(DEFINED HDF5_${_lang}_IS_PARALLEL)
740       if(NOT DEFINED HDF5_IS_PARALLEL)
741         set(HDF5_IS_PARALLEL ${HDF5_${_lang}_IS_PARALLEL})
742       elseif(NOT HDF5_IS_PARALLEL AND HDF5_${_lang}_IS_PARALLEL)
743         message(WARNING "HDF5 found for language ${_lang} is parallel but previously found language is not parallel.")
744       elseif(HDF5_IS_PARALLEL AND NOT HDF5_${_lang}_IS_PARALLEL)
745         message(WARNING "HDF5 found for language ${_lang} is not parallel but previously found language is parallel.")
746       endif()
747     endif()
748   endforeach()
749   unset(_lib)
750 else()
751   set(_HDF5_NEED_TO_SEARCH TRUE)
752 endif()
753
754 if(NOT HDF5_FOUND AND HDF5_COMPILER_NO_INTERROGATE)
755   # No arguments necessary, all languages can use the compiler wrappers
756   set(HDF5_FOUND TRUE)
757   set(HDF5_METHOD "Included by compiler wrappers")
758   set(HDF5_REQUIRED_VARS HDF5_METHOD)
759 elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH)
760   # Compiler wrappers aren't being used by the build but were found and used
761   # to determine necessary include and library flags
762   set(HDF5_INCLUDE_DIRS)
763   set(HDF5_LIBRARIES)
764   set(HDF5_HL_LIBRARIES)
765   foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
766     if(HDF5_${_lang}_FOUND)
767       if(NOT HDF5_${_lang}_COMPILER_NO_INTERROGATE)
768         list(APPEND HDF5_DEFINITIONS ${HDF5_${_lang}_DEFINITIONS})
769         list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIRS})
770         list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES})
771         if(HDF5_FIND_HL)
772           list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES})
773         endif()
774       endif()
775     endif()
776   endforeach()
777   list(REMOVE_DUPLICATES HDF5_DEFINITIONS)
778   list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS)
779   set(HDF5_FOUND TRUE)
780   set(HDF5_REQUIRED_VARS HDF5_LIBRARIES)
781   if(HDF5_FIND_HL)
782     list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES)
783   endif()
784 endif()
785
786 find_program( HDF5_DIFF_EXECUTABLE
787     NAMES h5diff
788     HINTS ${HDF5_ROOT}
789     PATH_SUFFIXES bin Bin
790     ${_HDF5_SEARCH_OPTS}
791     DOC "HDF5 file differencing tool." )
792 mark_as_advanced( HDF5_DIFF_EXECUTABLE )
793
794 if( NOT HDF5_FOUND )
795     # seed the initial lists of libraries to find with items we know we need
796     set(HDF5_C_LIBRARY_NAMES          hdf5)
797     set(HDF5_C_HL_LIBRARY_NAMES       hdf5_hl ${HDF5_C_LIBRARY_NAMES} )
798
799     set(HDF5_CXX_LIBRARY_NAMES        hdf5_cpp    ${HDF5_C_LIBRARY_NAMES})
800     set(HDF5_CXX_HL_LIBRARY_NAMES     hdf5_hl_cpp ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_CXX_LIBRARY_NAMES})
801
802     set(HDF5_Fortran_LIBRARY_NAMES    hdf5_fortran   ${HDF5_C_LIBRARY_NAMES})
803     set(HDF5_Fortran_HL_LIBRARY_NAMES hdf5_hl_fortran hdf5hl_fortran ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_Fortran_LIBRARY_NAMES})
804
805     # suffixes as seen on Linux, MSYS2, ...
806     set(_lib_suffixes hdf5)
807     if(NOT HDF5_PREFER_PARALLEL)
808       list(APPEND _lib_suffixes hdf5/serial)
809     endif()
810     if(HDF5_USE_STATIC_LIBRARIES)
811       set(_inc_suffixes include/static)
812     else()
813       set(_inc_suffixes include/shared)
814     endif()
815
816     foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
817         set(HDF5_${_lang}_LIBRARIES)
818         set(HDF5_${_lang}_HL_LIBRARIES)
819
820         # The "main" library.
821         set(_hdf5_main_library "")
822
823         # find the HDF5 libraries
824         foreach(LIB IN LISTS HDF5_${_lang}_LIBRARY_NAMES)
825             if(HDF5_USE_STATIC_LIBRARIES)
826                 # According to bug 1643 on the CMake bug tracker, this is the
827                 # preferred method for searching for a static library.
828                 # See https://gitlab.kitware.com/cmake/cmake/-/issues/1643.  We search
829                 # first for the full static library name, but fall back to a
830                 # generic search on the name if the static search fails.
831                 set( THIS_LIBRARY_SEARCH_DEBUG
832                     lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug
833                     lib${LIB}d-static.a lib${LIB}_debug-static.a ${LIB}d-static ${LIB}_D-static ${LIB}_debug-static )
834                 set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a lib${LIB} lib${LIB}-static.a ${LIB}-static)
835             else()
836                 set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared)
837                 set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared)
838                 if(WIN32)
839                   list(APPEND HDF5_DEFINITIONS "-DH5_BUILT_AS_DYNAMIC_LIB")
840                 endif()
841             endif()
842             find_library(HDF5_${LIB}_LIBRARY_DEBUG
843                 NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
844                 HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
845                 ${_HDF5_SEARCH_OPTS}
846             )
847             find_library(HDF5_${LIB}_LIBRARY_RELEASE
848                 NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
849                 HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
850                 ${_HDF5_SEARCH_OPTS}
851             )
852
853             # Set the "main" library if not already set.
854             if (NOT _hdf5_main_library)
855               if (HDF5_${LIB}_LIBRARY_RELEASE)
856                 set(_hdf5_main_library "${HDF5_${LIB}_LIBRARY_RELEASE}")
857               elseif (HDF5_${LIB}_LIBRARY_DEBUG)
858                 set(_hdf5_main_library "${HDF5_${LIB}_LIBRARY_DEBUG}")
859               endif ()
860             endif ()
861
862             select_library_configurations( HDF5_${LIB} )
863             list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY})
864         endforeach()
865         if(HDF5_${_lang}_LIBRARIES)
866             set(HDF5_${_lang}_FOUND TRUE)
867         endif()
868
869         # Append the libraries for this language binding to the list of all
870         # required libraries.
871         list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES})
872
873         # find the HDF5 include directories
874         set(_hdf5_inc_extra_paths)
875         set(_hdf5_inc_extra_suffixes)
876         if("${_lang}" STREQUAL "Fortran")
877             set(HDF5_INCLUDE_FILENAME hdf5.mod HDF5.mod)
878
879             # Add library-based search paths for Fortran modules.
880             if (NOT _hdf5_main_library STREQUAL "")
881               # gfortran module directory
882               if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "LCC")
883                 get_filename_component(_hdf5_library_dir "${_hdf5_main_library}" DIRECTORY)
884                 list(APPEND _hdf5_inc_extra_paths "${_hdf5_library_dir}")
885                 unset(_hdf5_library_dir)
886                 list(APPEND _hdf5_inc_extra_suffixes gfortran/modules)
887               endif ()
888             endif ()
889         elseif("${_lang}" STREQUAL "CXX")
890             set(HDF5_INCLUDE_FILENAME H5Cpp.h)
891         else()
892             set(HDF5_INCLUDE_FILENAME hdf5.h)
893         endif()
894
895         unset(_hdf5_main_library)
896
897         find_path(HDF5_${_lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME}
898             HINTS ${HDF5_ROOT}
899             PATHS $ENV{HOME}/.local/include ${_hdf5_inc_extra_paths}
900             PATH_SUFFIXES include Include ${_inc_suffixes} ${_lib_suffixes} ${_hdf5_inc_extra_suffixes}
901             ${_HDF5_SEARCH_OPTS}
902         )
903         mark_as_advanced(HDF5_${_lang}_INCLUDE_DIR)
904         unset(_hdf5_inc_extra_paths)
905         unset(_hdf5_inc_extra_suffixes)
906         # set the _DIRS variable as this is what the user will normally use
907         set(HDF5_${_lang}_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR})
908         list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR})
909
910         if(HDF5_FIND_HL)
911             foreach(LIB IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES)
912                 if(HDF5_USE_STATIC_LIBRARIES)
913                     # According to bug 1643 on the CMake bug tracker, this is the
914                     # preferred method for searching for a static library.
915                     # See https://gitlab.kitware.com/cmake/cmake/-/issues/1643.  We search
916                     # first for the full static library name, but fall back to a
917                     # generic search on the name if the static search fails.
918                     set( THIS_LIBRARY_SEARCH_DEBUG
919                         lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug
920                         lib${LIB}d-static.a lib${LIB}_debug-static.a lib${LIB}d-static lib${LIB}_D-static lib${LIB}_debug-static )
921                     set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a lib${LIB} lib${LIB}-static.a lib${LIB}-static)
922                 else()
923                     set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared)
924                     set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared)
925                 endif()
926                 find_library(HDF5_${LIB}_LIBRARY_DEBUG
927                     NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
928                     HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
929                     ${_HDF5_SEARCH_OPTS}
930                 )
931                 find_library(HDF5_${LIB}_LIBRARY_RELEASE
932                     NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
933                     HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
934                     ${_HDF5_SEARCH_OPTS}
935                 )
936
937                 select_library_configurations( HDF5_${LIB} )
938                 list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY})
939             endforeach()
940
941             # Append the libraries for this language binding to the list of all
942             # required libraries.
943             list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES})
944         endif()
945     endforeach()
946     if(HDF5_FIND_HL AND HDF5_HL_LIBRARIES)
947         set(HDF5_HL_FOUND TRUE)
948     endif()
949
950     list(REMOVE_DUPLICATES HDF5_DEFINITIONS)
951     list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS)
952
953     # If the HDF5 include directory was found, open H5pubconf.h to determine if
954     # HDF5 was compiled with parallel IO support
955     set( HDF5_IS_PARALLEL FALSE )
956     set( HDF5_VERSION "" )
957     foreach( _dir IN LISTS HDF5_INCLUDE_DIRS )
958       foreach(_hdr "${_dir}/H5pubconf.h" "${_dir}/H5pubconf-64.h" "${_dir}/H5pubconf-32.h")
959         if( EXISTS "${_hdr}" )
960             file( STRINGS "${_hdr}"
961                 HDF5_HAVE_PARALLEL_DEFINE
962                 REGEX "HAVE_PARALLEL 1" )
963             if( HDF5_HAVE_PARALLEL_DEFINE )
964                 set( HDF5_IS_PARALLEL TRUE )
965             endif()
966             unset(HDF5_HAVE_PARALLEL_DEFINE)
967
968             file( STRINGS "${_hdr}"
969                 HDF5_VERSION_DEFINE
970                 REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" )
971             if( "${HDF5_VERSION_DEFINE}" MATCHES
972                 "H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?\"" )
973                 set( HDF5_VERSION "${CMAKE_MATCH_1}" )
974                 if( CMAKE_MATCH_3 )
975                   set( HDF5_VERSION ${HDF5_VERSION}.${CMAKE_MATCH_3})
976                 endif()
977             endif()
978             unset(HDF5_VERSION_DEFINE)
979         endif()
980       endforeach()
981     endforeach()
982     unset(_hdr)
983     unset(_dir)
984     set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL
985         "HDF5 library compiled with parallel IO support" )
986     mark_as_advanced( HDF5_IS_PARALLEL )
987
988     set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS)
989     if(HDF5_FIND_HL)
990         list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES)
991     endif()
992 endif()
993
994 # For backwards compatibility we set HDF5_INCLUDE_DIR to the value of
995 # HDF5_INCLUDE_DIRS
996 if( HDF5_INCLUDE_DIRS )
997   set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" )
998 endif()
999
1000 # If HDF5_REQUIRED_VARS is empty at this point, then it's likely that
1001 # something external is trying to explicitly pass already found
1002 # locations
1003 if(NOT HDF5_REQUIRED_VARS)
1004     set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS)
1005 endif()
1006
1007 find_package_handle_standard_args(HDF5
1008     REQUIRED_VARS ${HDF5_REQUIRED_VARS}
1009     VERSION_VAR   HDF5_VERSION
1010     HANDLE_COMPONENTS
1011 )
1012
1013 unset(_HDF5_SEARCH_OPTS)
1014
1015 if( HDF5_FOUND AND NOT HDF5_DIR)
1016   # hide HDF5_DIR for the non-advanced user to avoid confusion with
1017   # HDF5_DIR-NOT_FOUND while HDF5 was found.
1018   mark_as_advanced(HDF5_DIR)
1019 endif()
1020
1021 if (HDF5_FOUND)
1022   if (NOT TARGET HDF5::HDF5)
1023     add_library(HDF5::HDF5 INTERFACE IMPORTED)
1024     string(REPLACE "-D" "" _hdf5_definitions "${HDF5_DEFINITIONS}")
1025     set_target_properties(HDF5::HDF5 PROPERTIES
1026       INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}"
1027       INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}")
1028     unset(_hdf5_definitions)
1029     target_link_libraries(HDF5::HDF5 INTERFACE ${HDF5_LIBRARIES})
1030   endif ()
1031
1032   foreach (hdf5_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
1033     if (hdf5_lang STREQUAL "C")
1034       set(hdf5_target_name "hdf5")
1035     elseif (hdf5_lang STREQUAL "CXX")
1036       set(hdf5_target_name "hdf5_cpp")
1037     elseif (hdf5_lang STREQUAL "Fortran")
1038       set(hdf5_target_name "hdf5_fortran")
1039     else ()
1040       continue ()
1041     endif ()
1042
1043     if (NOT TARGET "hdf5::${hdf5_target_name}")
1044       if (HDF5_COMPILER_NO_INTERROGATE)
1045         add_library("hdf5::${hdf5_target_name}" INTERFACE IMPORTED)
1046         string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_DEFINITIONS}")
1047         set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES
1048           INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_INCLUDE_DIRS}"
1049           INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}")
1050       else()
1051         if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY")
1052           set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}")
1053           set(_hdf5_location_release "${HDF5_${hdf5_target_name}_LIBRARY_RELEASE}")
1054           set(_hdf5_location_debug "${HDF5_${hdf5_target_name}_LIBRARY_DEBUG}")
1055         elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY")
1056           set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY}")
1057           set(_hdf5_location_release "${HDF5_${hdf5_lang}_LIBRARY_RELEASE}")
1058           set(_hdf5_location_debug "${HDF5_${hdf5_lang}_LIBRARY_DEBUG}")
1059         elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}")
1060           set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}")
1061         else ()
1062           # Error if we still don't have the location.
1063           message(SEND_ERROR
1064             "HDF5 was found, but a different variable was set which contains "
1065             "the location of the `hdf5::${hdf5_target_name}` library.")
1066         endif ()
1067         add_library("hdf5::${hdf5_target_name}" UNKNOWN IMPORTED)
1068         string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_DEFINITIONS}")
1069         if (NOT HDF5_${hdf5_lang}_INCLUDE_DIRS)
1070          set(HDF5_${hdf5_lang}_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS})
1071         endif ()
1072         set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES
1073           INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_INCLUDE_DIRS}"
1074           INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}")
1075         if (_hdf5_location_release)
1076           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY
1077             IMPORTED_CONFIGURATIONS RELEASE)
1078           set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY
1079             IMPORTED_LOCATION_RELEASE "${_hdf5_location_release}")
1080         endif()
1081         if (_hdf5_location_debug)
1082           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY
1083             IMPORTED_CONFIGURATIONS DEBUG)
1084           set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY
1085             IMPORTED_LOCATION_DEBUG "${_hdf5_location_debug}")
1086         endif()
1087         if (NOT _hdf5_location_release AND NOT _hdf5_location_debug)
1088           set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY
1089             IMPORTED_LOCATION "${_hdf5_location}")
1090         endif()
1091         if (_hdf5_libtype STREQUAL "SHARED")
1092           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND
1093             PROPERTY
1094               INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_DYNAMIC_LIB)
1095         elseif (_hdf5_libtype STREQUAL "STATIC")
1096           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND
1097             PROPERTY
1098               INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_STATIC_LIB)
1099         endif ()
1100         unset(_hdf5_definitions)
1101         unset(_hdf5_libtype)
1102         unset(_hdf5_location)
1103         unset(_hdf5_location_release)
1104         unset(_hdf5_location_debug)
1105       endif ()
1106     endif ()
1107
1108     if (NOT HDF5_FIND_HL)
1109       continue ()
1110     endif ()
1111
1112     set(hdf5_alt_target_name "")
1113     if (hdf5_lang STREQUAL "C")
1114       set(hdf5_target_name "hdf5_hl")
1115     elseif (hdf5_lang STREQUAL "CXX")
1116       set(hdf5_target_name "hdf5_hl_cpp")
1117     elseif (hdf5_lang STREQUAL "Fortran")
1118       set(hdf5_target_name "hdf5_hl_fortran")
1119       set(hdf5_alt_target_name "hdf5hl_fortran")
1120     else ()
1121       continue ()
1122     endif ()
1123
1124     if (NOT TARGET "hdf5::${hdf5_target_name}")
1125       if (HDF5_COMPILER_NO_INTERROGATE)
1126         add_library("hdf5::${hdf5_target_name}" INTERFACE IMPORTED)
1127         string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_HL_DEFINITIONS}")
1128         set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES
1129           INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_HL_INCLUDE_DIRS}"
1130           INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}")
1131       else()
1132         if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY")
1133           set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}")
1134           set(_hdf5_location_release "${HDF5_${hdf5_target_name}_LIBRARY_RELEASE}")
1135           set(_hdf5_location_debug "${HDF5_${hdf5_target_name}_LIBRARY_DEBUG}")
1136         elseif (DEFINED "HDF5_${hdf5_lang}_HL_LIBRARY")
1137           set(_hdf5_location "${HDF5_${hdf5_lang}_HL_LIBRARY}")
1138           set(_hdf5_location_release "${HDF5_${hdf5_lang}_HL_LIBRARY_RELEASE}")
1139           set(_hdf5_location_debug "${HDF5_${hdf5_lang}_HL_LIBRARY_DEBUG}")
1140         elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}")
1141           set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}")
1142         elseif (hdf5_alt_target_name AND DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_alt_target_name}")
1143           set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_alt_target_name}}")
1144         else ()
1145           # Error if we still don't have the location.
1146           message(SEND_ERROR
1147             "HDF5 was found, but a different variable was set which contains "
1148             "the location of the `hdf5::${hdf5_target_name}` library.")
1149         endif ()
1150         add_library("hdf5::${hdf5_target_name}" UNKNOWN IMPORTED)
1151         string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_HL_DEFINITIONS}")
1152         set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES
1153           INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_HL_INCLUDE_DIRS}"
1154           INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}")
1155         if (_hdf5_location_release)
1156           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY
1157             IMPORTED_CONFIGURATIONS RELEASE)
1158           set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY
1159             IMPORTED_LOCATION_RELEASE "${_hdf5_location_release}")
1160         endif()
1161         if (_hdf5_location_debug)
1162           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY
1163             IMPORTED_CONFIGURATIONS DEBUG)
1164           set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY
1165             IMPORTED_LOCATION_DEBUG "${_hdf5_location_debug}")
1166         endif()
1167         if (NOT _hdf5_location_release AND NOT _hdf5_location_debug)
1168           set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY
1169             IMPORTED_LOCATION "${_hdf5_location}")
1170         endif()
1171         if (_hdf5_libtype STREQUAL "SHARED")
1172           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND
1173             PROPERTY
1174               INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_DYNAMIC_LIB)
1175         elseif (_hdf5_libtype STREQUAL "STATIC")
1176           set_property(TARGET "hdf5::${hdf5_target_name}" APPEND
1177             PROPERTY
1178               INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_STATIC_LIB)
1179         endif ()
1180         unset(_hdf5_definitions)
1181         unset(_hdf5_libtype)
1182         unset(_hdf5_location)
1183       endif ()
1184     endif ()
1185   endforeach ()
1186   unset(hdf5_lang)
1187
1188   if (HDF5_DIFF_EXECUTABLE AND NOT TARGET hdf5::h5diff)
1189     add_executable(hdf5::h5diff IMPORTED)
1190     set_target_properties(hdf5::h5diff PROPERTIES
1191       IMPORTED_LOCATION "${HDF5_DIFF_EXECUTABLE}")
1192   endif ()
1193 endif ()
1194
1195 if (HDF5_FIND_DEBUG)
1196   message(STATUS "HDF5_DIR: ${HDF5_DIR}")
1197   message(STATUS "HDF5_DEFINITIONS: ${HDF5_DEFINITIONS}")
1198   message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}")
1199   message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}")
1200   message(STATUS "HDF5_HL_LIBRARIES: ${HDF5_HL_LIBRARIES}")
1201   foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
1202     message(STATUS "HDF5_${_lang}_DEFINITIONS: ${HDF5_${_lang}_DEFINITIONS}")
1203     message(STATUS "HDF5_${_lang}_INCLUDE_DIR: ${HDF5_${_lang}_INCLUDE_DIR}")
1204     message(STATUS "HDF5_${_lang}_INCLUDE_DIRS: ${HDF5_${_lang}_INCLUDE_DIRS}")
1205     message(STATUS "HDF5_${_lang}_LIBRARY: ${HDF5_${_lang}_LIBRARY}")
1206     message(STATUS "HDF5_${_lang}_LIBRARIES: ${HDF5_${_lang}_LIBRARIES}")
1207     message(STATUS "HDF5_${_lang}_HL_LIBRARY: ${HDF5_${_lang}_HL_LIBRARY}")
1208     message(STATUS "HDF5_${_lang}_HL_LIBRARIES: ${HDF5_${_lang}_HL_LIBRARIES}")
1209   endforeach()
1210   message(STATUS "Defined targets (if any):")
1211   foreach(_lang IN  ITEMS "" "_cpp" "_fortran")
1212     foreach(_hl IN  ITEMS "" "_hl")
1213       foreach(_prefix IN ITEMS "hdf5::" "")
1214         foreach(_suffix IN ITEMS "-static" "-shared" "")
1215           set (_target ${_prefix}hdf5${_hl}${_lang}${_suffix})
1216           if (TARGET  ${_target})
1217             message(STATUS "... ${_target}")
1218           else()
1219             #message(STATUS "... ${_target} does not exist")
1220           endif()
1221         endforeach()
1222       endforeach()
1223     endforeach()
1224   endforeach()
1225 endif()
1226 unset(_lang)
1227 unset(_HDF5_NEED_TO_SEARCH)