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.
This commit is contained in:
Brad King
2017-02-02 10:05:51 -05:00
parent 2b0256c5ad
commit ae89967f9d

View File

@@ -340,62 +340,44 @@ macro( _HDF5_parse_compile_line
libraries libraries
libraries_hl) libraries_hl)
# Match the include paths if(UNIX)
set( RE " -I *([^\" ]+|\"[^\"]+\")") separate_arguments(_HDF5_COMPILE_ARGS UNIX_COMMAND "${${compile_line_var}}")
string( REGEX MATCHALL "${RE}" include_path_flags "${${compile_line_var}}") else()
foreach( IPATH IN LISTS include_path_flags ) separate_arguments(_HDF5_COMPILE_ARGS WINDOWS_COMMAND "${${compile_line_var}}")
string( REGEX REPLACE "${RE}" "\\1" IPATH "${IPATH}" ) endif()
list( APPEND ${include_paths} ${IPATH} )
endforeach()
# Match the definitions foreach(arg IN LISTS _HDF5_COMPILE_ARGS)
set( RE " -D([^ ]*)") if("${arg}" MATCHES "^-I(.*)$")
string( REGEX MATCHALL "${RE}" definition_flags "${${compile_line_var}}" ) # include directory
foreach( DEF IN LISTS definition_flags ) list(APPEND ${include_paths} "${CMAKE_MATCH_1}")
string( STRIP "${DEF}" DEF ) elseif("${arg}" MATCHES "^-D(.*)$")
list( APPEND ${definitions} ${DEF} ) # compile definition
endforeach() list(APPEND ${definitions} "${CMAKE_MATCH_1}")
elseif("${arg}" MATCHES "^-L(.*)$")
# Match the library paths # library search path
set( RE " -L *([^\" ]+|\"[^\"]+\")") list(APPEND ${library_paths} "${CMAKE_MATCH_1}")
string( REGEX MATCHALL "${RE}" library_path_flags "${${compile_line_var}}") elseif("${arg}" MATCHES "^-l(hdf5.*hl.*)$")
foreach( LPATH IN LISTS library_path_flags ) # library name (hl)
string( REGEX REPLACE "${RE}" "\\1" LPATH "${LPATH}" ) list(APPEND ${libraries_hl} "${CMAKE_MATCH_1}")
list( APPEND ${library_paths} ${LPATH} ) elseif("${arg}" MATCHES "^-l(.*)$")
endforeach() # library name
list(APPEND ${libraries} "${CMAKE_MATCH_1}")
# now search for the lib names specified in the compile line (match -l...) elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$")
# match only -l's preceded by a space or comma # library file
set( RE " -l *([^\" ]+|\"[^\"]+\")") if(NOT EXISTS "${arg}")
string( REGEX MATCHALL "${RE}" library_name_flags "${${compile_line_var}}") continue()
foreach( LNAME IN LISTS library_name_flags ) endif()
string( REGEX REPLACE "${RE}" "\\1" LNAME "${LNAME}" ) get_filename_component(_HDF5_LPATH "${arg}" DIRECTORY)
if(LNAME MATCHES ".*hl") get_filename_component(_HDF5_LNAME "${arg}" NAME_WE)
list(APPEND ${libraries_hl} ${LNAME}) string(REGEX REPLACE "^lib" "" _HDF5_LNAME "${_HDF5_LNAME}")
else() list(APPEND ${library_paths} "${_HDF5_LPATH}")
list(APPEND ${libraries} ${LNAME}) if(_HDF5_LNAME MATCHES "hdf5.*hl")
endif() list(APPEND ${libraries_hl} "${_HDF5_LNAME}")
endforeach() else()
list(APPEND ${libraries} "${_HDF5_LNAME}")
# now search for full library paths with no flags endif()
set( RE " ([^\" ]+|\"[^\"]+\")") endif()
string( REGEX MATCHALL "${RE}" library_name_noflags "${${compile_line_var}}") endforeach()
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()
endmacro() endmacro()
if(NOT HDF5_ROOT) if(NOT HDF5_ROOT)