From ae89967f9dc9308003630531ef34764030f98bd0 Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Thu, 2 Feb 2017 10:05:51 -0500 Subject: FindHDF5: Fix command-line parsing argument extraction order Re-implement our internal `_HDF5_parse_compile_line` helper to process command line arguments all at once and in order. Otherwise the libraries named by absolute path and those named by `-l` arguments are not kept in order. The new implementation will not handle separate arguments like `-I /path/to/include/dir` but I have not seen the HDF5 compiler wrappers produce this form. If necessary the parsing loop can be extended with a state variable to keep track of such pairs. --- Modules/FindHDF5.cmake | 92 ++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 55 deletions(-) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 6e5a25e..cf84918 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -340,62 +340,44 @@ macro( _HDF5_parse_compile_line libraries libraries_hl) - # Match the include paths - set( RE " -I *([^\" ]+|\"[^\"]+\")") - string( REGEX MATCHALL "${RE}" include_path_flags "${${compile_line_var}}") - foreach( IPATH IN LISTS include_path_flags ) - string( REGEX REPLACE "${RE}" "\\1" IPATH "${IPATH}" ) - list( APPEND ${include_paths} ${IPATH} ) - endforeach() - - # Match the definitions - set( RE " -D([^ ]*)") - string( REGEX MATCHALL "${RE}" definition_flags "${${compile_line_var}}" ) - foreach( DEF IN LISTS definition_flags ) - string( STRIP "${DEF}" DEF ) - list( APPEND ${definitions} ${DEF} ) - endforeach() - - # Match the library paths - set( RE " -L *([^\" ]+|\"[^\"]+\")") - string( REGEX MATCHALL "${RE}" library_path_flags "${${compile_line_var}}") - foreach( LPATH IN LISTS library_path_flags ) - string( REGEX REPLACE "${RE}" "\\1" LPATH "${LPATH}" ) - list( APPEND ${library_paths} ${LPATH} ) - endforeach() - - # now search for the lib names specified in the compile line (match -l...) - # match only -l's preceded by a space or comma - set( RE " -l *([^\" ]+|\"[^\"]+\")") - string( REGEX MATCHALL "${RE}" library_name_flags "${${compile_line_var}}") - foreach( LNAME IN LISTS library_name_flags ) - string( REGEX REPLACE "${RE}" "\\1" LNAME "${LNAME}" ) - if(LNAME MATCHES ".*hl") - list(APPEND ${libraries_hl} ${LNAME}) - else() - list(APPEND ${libraries} ${LNAME}) - endif() - endforeach() + if(UNIX) + separate_arguments(_HDF5_COMPILE_ARGS UNIX_COMMAND "${${compile_line_var}}") + else() + separate_arguments(_HDF5_COMPILE_ARGS WINDOWS_COMMAND "${${compile_line_var}}") + endif() - # now search for full library paths with no flags - set( RE " ([^\" ]+|\"[^\"]+\")") - string( REGEX MATCHALL "${RE}" library_name_noflags "${${compile_line_var}}") - foreach( LIB IN LISTS library_name_noflags ) - string( REGEX REPLACE "${RE}" "\\1" LIB "${LIB}" ) - get_filename_component(LIB "${LIB}" ABSOLUTE) - if(NOT EXISTS ${LIB} OR IS_DIRECTORY ${LIB}) - continue() - endif() - get_filename_component(LPATH ${LIB} DIRECTORY) - get_filename_component(LNAME ${LIB} NAME_WE) - string( REGEX REPLACE "^lib" "" LNAME ${LNAME} ) - list( APPEND ${library_paths} ${LPATH} ) - if(LNAME MATCHES ".*hl") - list(APPEND ${libraries_hl} ${LNAME}) - else() - list(APPEND ${libraries} ${LNAME}) - endif() - endforeach() + foreach(arg IN LISTS _HDF5_COMPILE_ARGS) + if("${arg}" MATCHES "^-I(.*)$") + # include directory + list(APPEND ${include_paths} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-D(.*)$") + # compile definition + list(APPEND ${definitions} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-L(.*)$") + # library search path + list(APPEND ${library_paths} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-l(hdf5.*hl.*)$") + # library name (hl) + list(APPEND ${libraries_hl} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-l(.*)$") + # library name + list(APPEND ${libraries} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$") + # library file + if(NOT EXISTS "${arg}") + continue() + endif() + get_filename_component(_HDF5_LPATH "${arg}" DIRECTORY) + get_filename_component(_HDF5_LNAME "${arg}" NAME_WE) + string(REGEX REPLACE "^lib" "" _HDF5_LNAME "${_HDF5_LNAME}") + list(APPEND ${library_paths} "${_HDF5_LPATH}") + if(_HDF5_LNAME MATCHES "hdf5.*hl") + list(APPEND ${libraries_hl} "${_HDF5_LNAME}") + else() + list(APPEND ${libraries} "${_HDF5_LNAME}") + endif() + endif() + endforeach() endmacro() if(NOT HDF5_ROOT) -- cgit v0.12 From 3d5ad7236c8ce444323fb63cd9ff50fb5f757830 Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Thu, 2 Feb 2017 09:13:46 -0500 Subject: FindHDF5: Initialize/finalize internal search options variable While at it, use a more private name. --- Modules/FindHDF5.cmake | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index cf84918..99b2309 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -609,13 +609,15 @@ elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) endif() if(HDF5_ROOT) - set(SEARCH_OPTS NO_DEFAULT_PATH) + set(_HDF5_SEARCH_OPTS NO_DEFAULT_PATH) +else() + set(_HDF5_SEARCH_OPTS) endif() find_program( HDF5_DIFF_EXECUTABLE NAMES h5diff HINTS ${HDF5_ROOT} PATH_SUFFIXES bin Bin - ${SEARCH_OPTS} + ${_HDF5_SEARCH_OPTS} DOC "HDF5 file differencing tool." ) mark_as_advanced( HDF5_DIFF_EXECUTABLE ) @@ -644,7 +646,7 @@ if( NOT HDF5_FOUND ) HINTS ${HDF5_ROOT} PATHS $ENV{HOME}/.local/include PATH_SUFFIXES include Include - ${SEARCH_OPTS} + ${_HDF5_SEARCH_OPTS} ) mark_as_advanced(HDF5_${LANGUAGE}_INCLUDE_DIR) list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR}) @@ -668,12 +670,12 @@ if( NOT HDF5_FOUND ) find_library(HDF5_${LIB}_LIBRARY_DEBUG NAMES ${THIS_LIBRARY_SEARCH_DEBUG} HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib - ${SEARCH_OPTS} + ${_HDF5_SEARCH_OPTS} ) find_library( HDF5_${LIB}_LIBRARY_RELEASE NAMES ${THIS_LIBRARY_SEARCH_RELEASE} HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib - ${SEARCH_OPTS} + ${_HDF5_SEARCH_OPTS} ) select_library_configurations( HDF5_${LIB} ) list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY}) @@ -705,12 +707,12 @@ if( NOT HDF5_FOUND ) find_library(HDF5_${LIB}_LIBRARY_DEBUG NAMES ${THIS_LIBRARY_SEARCH_DEBUG} HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib - ${SEARCH_OPTS} + ${_HDF5_SEARCH_OPTS} ) find_library( HDF5_${LIB}_LIBRARY_RELEASE NAMES ${THIS_LIBRARY_SEARCH_RELEASE} HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib - ${SEARCH_OPTS} + ${_HDF5_SEARCH_OPTS} ) select_library_configurations( HDF5_${LIB} ) list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY}) @@ -785,3 +787,5 @@ find_package_handle_standard_args(HDF5 VERSION_VAR HDF5_VERSION HANDLE_COMPONENTS ) + +unset(_HDF5_SEARCH_OPTS) -- cgit v0.12 From 77f6d22ad1f1b461297a463eb5f40fbb0d0825aa Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Thu, 2 Feb 2017 09:16:47 -0500 Subject: FindHDF5: Use keywords in find_library calls Clarify the purpose of each argument. --- Modules/FindHDF5.cmake | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 99b2309..f07d0c7 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -516,7 +516,10 @@ if(NOT HDF5_FOUND AND NOT HDF5_ROOT) endif() foreach(L IN LISTS HDF5_${__lang}_LIBRARY_NAMES) - find_library(HDF5_${__lang}_LIBRARY_${L} ${L} ${HDF5_${__lang}_LIBRARY_DIRS}) + find_library(HDF5_${__lang}_LIBRARY_${L} + NAMES ${L} + HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + ) if(HDF5_${__lang}_LIBRARY_${L}) list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) else() @@ -526,7 +529,10 @@ if(NOT HDF5_FOUND AND NOT HDF5_ROOT) if(FIND_HL) set(HDF5_${__lang}_HL_LIBRARIES) foreach(L IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) - find_library(HDF5_${__lang}_LIBRARY_${L} ${L} ${HDF5_${__lang}_LIBRARY_DIRS}) + find_library(HDF5_${__lang}_LIBRARY_${L} + NAMES ${L} + HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + ) if(HDF5_${__lang}_LIBRARY_${L}) list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) else() -- cgit v0.12 From 4908969f578ded9d87f244bd8ada65ba0c51cf28 Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Thu, 2 Feb 2017 09:21:21 -0500 Subject: FindHDF5: Fix search with HDF5_ROOT Refactoring in commit v3.6.0-rc1~72^2 (HDF5: Rework component searching to correctly find HL for all bindings, 2016-05-12) turned off a large amount of its logic when HDF5_ROOT is set. This caused use of the hdf5 compiler wrapper to extract all needed libraries (e.g. z, dl as dependencies of hdf5 static libraries) to be skipped when using HDF5_ROOT. Fix the search logic to honor HDF5_ROOT in all code paths. Restrict the search for hdf5-specific components to this root, but allow external libraries to be found anywhere. Fixes: #16566 --- Modules/FindHDF5.cmake | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index f07d0c7..94a8729 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -383,10 +383,18 @@ endmacro() if(NOT HDF5_ROOT) set(HDF5_ROOT $ENV{HDF5_ROOT}) endif() +if(HDF5_ROOT) + set(_HDF5_SEARCH_OPTS NO_DEFAULT_PATH) +else() + set(_HDF5_SEARCH_OPTS) +endif() # Try to find HDF5 using an installed hdf5-config.cmake -if(NOT HDF5_FOUND AND NOT HDF5_ROOT) - find_package(HDF5 QUIET NO_MODULE) +if(NOT HDF5_FOUND) + find_package(HDF5 QUIET NO_MODULE + HINTS ${HDF5_ROOT} + ${_HDF5_SEARCH_OPTS} + ) if( HDF5_FOUND) set(HDF5_IS_PARALLEL ${HDF5_ENABLE_PARALLEL}) set(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR}) @@ -440,7 +448,7 @@ if(NOT HDF5_FOUND AND NOT HDF5_ROOT) endif() endif() -if(NOT HDF5_FOUND AND NOT HDF5_ROOT) +if(NOT HDF5_FOUND) set(_HDF5_NEED_TO_SEARCH False) set(HDF5_COMPILER_NO_INTERROGATE True) # Only search for languages we've enabled @@ -488,8 +496,10 @@ if(NOT HDF5_FOUND AND NOT HDF5_ROOT) # search options with the wrapper find_program(HDF5_${__lang}_COMPILER_EXECUTABLE NAMES ${HDF5_${__lang}_COMPILER_NAMES} NAMES_PER_DIR + HINTS ${HDF5_ROOT} PATH_SUFFIXES bin Bin DOC "HDF5 ${__lang} Wrapper compiler. Used only to detect HDF5 compile flags." + ${_HDF5_SEARCH_OPTS} ) mark_as_advanced( HDF5_${__lang}_COMPILER_EXECUTABLE ) unset(HDF5_${__lang}_COMPILER_NAMES) @@ -516,10 +526,20 @@ if(NOT HDF5_FOUND AND NOT HDF5_ROOT) endif() foreach(L IN LISTS HDF5_${__lang}_LIBRARY_NAMES) + if(x"${L}" MATCHES "hdf5") + # hdf5 library + set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) + else() + # external library + set(_HDF5_SEARCH_OPTS_LOCAL) + endif() find_library(HDF5_${__lang}_LIBRARY_${L} NAMES ${L} HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + ${HDF5_ROOT} + ${_HDF5_SEARCH_OPTS_LOCAL} ) + unset(_HDF5_SEARCH_OPTS_LOCAL) if(HDF5_${__lang}_LIBRARY_${L}) list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) else() @@ -529,10 +549,20 @@ if(NOT HDF5_FOUND AND NOT HDF5_ROOT) if(FIND_HL) set(HDF5_${__lang}_HL_LIBRARIES) foreach(L IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) + if("x${L}" MATCHES "hdf5") + # hdf5 library + set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) + else() + # external library + set(_HDF5_SEARCH_OPTS_LOCAL) + endif() find_library(HDF5_${__lang}_LIBRARY_${L} NAMES ${L} HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + ${HDF5_ROOT} + ${_HDF5_SEARCH_OPTS_LOCAL} ) + unset(_HDF5_SEARCH_OPTS_LOCAL) if(HDF5_${__lang}_LIBRARY_${L}) list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) else() @@ -614,11 +644,6 @@ elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) endif() endif() -if(HDF5_ROOT) - set(_HDF5_SEARCH_OPTS NO_DEFAULT_PATH) -else() - set(_HDF5_SEARCH_OPTS) -endif() find_program( HDF5_DIFF_EXECUTABLE NAMES h5diff HINTS ${HDF5_ROOT} -- cgit v0.12 From 5564c01703c20f992769f4e152bcc74ceddc5942 Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Fri, 3 Feb 2017 08:51:52 -0500 Subject: FindHDF5: Restore fallback to static libraries Since commit v3.6.1~6^2~2 (FindHDF5: Fix h5cc arg parsing to work with homebrew on Mac, 2016-07-11) we treated `HDF5_USE_STATIC_LIBRARIES` OFF as a requirement for shared libraries. It is just supposed to be a preference. Even if `HDF5_USE_STATIC_LIBRARIES` is not set we should still fall back to finding static libraries if shared libraries are not available. Issue: #16566 --- Modules/FindHDF5.cmake | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 94a8729..b10e313 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -518,28 +518,26 @@ if(NOT HDF5_FOUND) ) set(HDF5_${__lang}_LIBRARIES) - set(_HDF5_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(HDF5_USE_STATIC_LIBRARIES) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - endif() - foreach(L IN LISTS HDF5_${__lang}_LIBRARY_NAMES) + set(_HDF5_SEARCH_NAMES_LOCAL) if(x"${L}" MATCHES "hdf5") # hdf5 library set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) + if(UNIX AND HDF5_USE_STATIC_LIBRARIES) + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + endif() else() # external library set(_HDF5_SEARCH_OPTS_LOCAL) endif() find_library(HDF5_${__lang}_LIBRARY_${L} - NAMES ${L} + NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR HINTS ${HDF5_${__lang}_LIBRARY_DIRS} ${HDF5_ROOT} ${_HDF5_SEARCH_OPTS_LOCAL} ) unset(_HDF5_SEARCH_OPTS_LOCAL) + unset(_HDF5_SEARCH_NAMES_LOCAL) if(HDF5_${__lang}_LIBRARY_${L}) list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) else() @@ -549,20 +547,25 @@ if(NOT HDF5_FOUND) if(FIND_HL) set(HDF5_${__lang}_HL_LIBRARIES) foreach(L IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) + set(_HDF5_SEARCH_NAMES_LOCAL) if("x${L}" MATCHES "hdf5") # hdf5 library set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) + if(UNIX AND HDF5_USE_STATIC_LIBRARIES) + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + endif() else() # external library set(_HDF5_SEARCH_OPTS_LOCAL) endif() find_library(HDF5_${__lang}_LIBRARY_${L} - NAMES ${L} + NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR HINTS ${HDF5_${__lang}_LIBRARY_DIRS} ${HDF5_ROOT} ${_HDF5_SEARCH_OPTS_LOCAL} ) unset(_HDF5_SEARCH_OPTS_LOCAL) + unset(_HDF5_SEARCH_NAMES_LOCAL) if(HDF5_${__lang}_LIBRARY_${L}) list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) else() @@ -572,8 +575,6 @@ if(NOT HDF5_FOUND) set(HDF5_HL_FOUND True) endif() - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_HDF5_CMAKE_FIND_LIBRARY_SUFFIXES}) - set(HDF5_${__lang}_FOUND True) mark_as_advanced(HDF5_${__lang}_DEFINITIONS) mark_as_advanced(HDF5_${__lang}_INCLUDE_DIRS) -- cgit v0.12 From cf0d8f1fd6ad5d4bc85d7788af459238df494260 Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Fri, 3 Feb 2017 10:57:10 -0500 Subject: FindHDF5: Restore HDF5_INCLUDE_DIR in all code paths This compatibility variable should be set no matter which method was used to find HDF5. Even if `HDF5_INCLUDE_DIRS` was set by copying the `HDF5_INCLUDE_DIR` value from `hdf5-config.cmake` it will not hurt to copy the same value back. Issue: #16566 --- Modules/FindHDF5.cmake | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index b10e313..e1199a7 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -796,17 +796,18 @@ if( NOT HDF5_FOUND ) "HDF5 library compiled with parallel IO support" ) mark_as_advanced( HDF5_IS_PARALLEL ) - # For backwards compatibility we set HDF5_INCLUDE_DIR to the value of - # HDF5_INCLUDE_DIRS - if( HDF5_INCLUDE_DIRS ) - set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" ) - endif() set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS) if(FIND_HL) list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES) endif() endif() +# For backwards compatibility we set HDF5_INCLUDE_DIR to the value of +# HDF5_INCLUDE_DIRS +if( HDF5_INCLUDE_DIRS ) + set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" ) +endif() + # If HDF5_REQUIRED_VARS is empty at this point, then it's likely that # something external is trying to explicitly pass already found # locations -- cgit v0.12