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: [PATCH] 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 6e5a25e2ef..cf849185da 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)
-- 
GitLab