From a7cc231bd3838f330fa8102b05f55ab52454a60f Mon Sep 17 00:00:00 2001 From: Nikita Nemkin Date: Sun, 16 Feb 2025 11:36:03 +0500 Subject: [PATCH] FindMPI: Improve configuration extraction To avoid issues with multi-line scripts, regexes that match unquoted shell command arguments shouldn't include newlines. Fixes: #12553 Co-authored-by: K. R. Walker --- Modules/FindMPI.cmake | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index e66a42f553..e8039aa42e 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -536,7 +536,7 @@ function (_MPI_interrogate_compiler LANG) # It has to be called as "compchk.sh ". Here, is one out of 32 (i686), 64 (ia64) or 32e (x86_64). # The compiler is identified by filename, and can be either the MPI compiler or the underlying compiler. # NOTE: It is vital to run this script while the environment variables are set up, otherwise it can check the wrong compiler. - if(MPI_COMPILE_CMDLINE MATCHES "^([^\" ]+/compchk.sh|\"[^\"]+/compchk.sh\") +([^ ]+)") + if(MPI_COMPILE_CMDLINE MATCHES "^([^\"\n ]+/compchk.sh|\"[^\"]+/compchk.sh\") +([^ ]+)") # Now CMAKE_MATCH_1 contains the path to the compchk.sh file and CMAKE_MATCH_2 the architecture flag. unset(COMPILER_CHECKER_OUTPUT) execute_process( @@ -551,7 +551,7 @@ function (_MPI_interrogate_compiler LANG) endif() else() # Since the check passed, we can remove the compchk.sh script. - string(REGEX REPLACE "^([^\" ]+|\"[^\"]+\")/compchk.sh.*\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}") + string(REGEX REPLACE "^([^\"\n ]+|\"[^\"]+\")/compchk.sh.*\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}") endif() endif() endif() @@ -624,10 +624,10 @@ function (_MPI_interrogate_compiler LANG) # Especially with M(VA)PICH-1, this appears to happen erroneously, and therefore we should translate # this output into an additional include directory and then drop it from the output. # noqa: spellcheck on - if(MPI_COMPILE_CMDLINE MATCHES "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h") + if(MPI_COMPILE_CMDLINE MATCHES "^ln -s ([^\"\n ]+|\"[^\"]+\") mpif.h") get_filename_component(MPI_INCLUDE_DIRS_WORK "${CMAKE_MATCH_1}" DIRECTORY) - string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}") - string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}") + string(REGEX REPLACE "^ln -s ([^\"\n ]+|\"[^\"]+\") mpif.h\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}") + string(REGEX REPLACE "^ln -s ([^\"\n ]+|\"[^\"]+\") mpif.h\n" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}") string(REGEX REPLACE "\nrm -f mpif.h$" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}") string(REGEX REPLACE "\nrm -f mpif.h$" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}") endif() @@ -645,7 +645,7 @@ function (_MPI_interrogate_compiler LANG) # on Windows seems to require any specific ones, either. if(NOT MSVC) # Extract compile options from the compile command line. - string(REGEX MATCHALL "(^| )-f([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_OPTIONS "${MPI_COMPILE_CMDLINE}") + string(REGEX MATCHALL "(^| )-f([^\"\n ]+|\"[^\"]+\")" MPI_ALL_COMPILE_OPTIONS "${MPI_COMPILE_CMDLINE}") foreach(_MPI_COMPILE_OPTION IN LISTS MPI_ALL_COMPILE_OPTIONS) string(REGEX REPLACE "^ " "" _MPI_COMPILE_OPTION "${_MPI_COMPILE_OPTION}") @@ -673,7 +673,7 @@ function (_MPI_interrogate_compiler LANG) endif() # Same deal as above, for the definitions. - string(REGEX MATCHALL "(^| )${_MPI_PREPROCESSOR_FLAG_REGEX}-D *([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_DEFINITIONS "${MPI_COMPILE_CMDLINE}") + string(REGEX MATCHALL "(^| )${_MPI_PREPROCESSOR_FLAG_REGEX}-D *([^\"\n ]+|\"[^\"]+\")" MPI_ALL_COMPILE_DEFINITIONS "${MPI_COMPILE_CMDLINE}") foreach(_MPI_COMPILE_DEFINITION IN LISTS MPI_ALL_COMPILE_DEFINITIONS) string(REGEX REPLACE "^ ?${_MPI_PREPROCESSOR_FLAG_REGEX}-D *" "" _MPI_COMPILE_DEFINITION "${_MPI_COMPILE_DEFINITION}") @@ -684,7 +684,7 @@ function (_MPI_interrogate_compiler LANG) endforeach() # Extract include paths from compile command line - string(REGEX MATCHALL "(^|\n| )${_MPI_PREPROCESSOR_FLAG_REGEX}${CMAKE_INCLUDE_FLAG_${LANG}} *([^\" ]+|\"[^\"]+\")" + string(REGEX MATCHALL "(^|\n| )${_MPI_PREPROCESSOR_FLAG_REGEX}${CMAKE_INCLUDE_FLAG_${LANG}} *([^\"\n ]+|\"[^\"]+\")" MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}") # If extracting failed to work, we'll try using -showme:incdirs. @@ -707,7 +707,7 @@ function (_MPI_interrogate_compiler LANG) endforeach() # The next step are linker flags and library directories. Here, we first take the flags given in raw -L or -LIBPATH: syntax. - string(REGEX MATCHALL "(^| )${CMAKE_LIBRARY_PATH_FLAG} *([^\" ]+|\"[^\"]+\")" MPI_DIRECT_LINK_PATHS "${MPI_LINK_CMDLINE}") + string(REGEX MATCHALL "(^| )${CMAKE_LIBRARY_PATH_FLAG} *([^\"\n ]+|\"[^\"]+\")" MPI_DIRECT_LINK_PATHS "${MPI_LINK_CMDLINE}") foreach(_MPI_LPATH IN LISTS MPI_DIRECT_LINK_PATHS) string(REGEX REPLACE "(^| )${CMAKE_LIBRARY_PATH_FLAG} *" "" _MPI_LPATH "${_MPI_LPATH}") list(APPEND MPI_ALL_LINK_PATHS "${_MPI_LPATH}") @@ -715,7 +715,7 @@ function (_MPI_interrogate_compiler LANG) # If the link commandline hasn't been filtered (e.g. when using MSVC and /link), we need to extract the relevant parts first. if(NOT _MPI_FILTERED_LINK_INFORMATION) - string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker +)([^\" ]+|\"[^\"]+\")" MPI_LINK_FLAGS "${MPI_LINK_CMDLINE}") + string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker +)([^\"\n ]+|\"[^\"]+\")" MPI_LINK_FLAGS "${MPI_LINK_CMDLINE}") # In this case, we could also find some indirectly given linker paths, e.g. prefixed by -Xlinker or -Wl, # Since syntaxes like -Wl,-L -Wl,/my/path/to/lib are also valid, we parse these paths by first removing -Wl, and -Xlinker @@ -724,7 +724,7 @@ function (_MPI_interrogate_compiler LANG) # Now we can parse the leftover output. Note that spaces can now be handled since the above example would reduce to # -L /my/path/to/lib and can be extracted correctly. - string(REGEX MATCHALL "^(${CMAKE_LIBRARY_PATH_FLAG},? *|--library-path=)([^\" ]+|\"[^\"]+\")" + string(REGEX MATCHALL "^(${CMAKE_LIBRARY_PATH_FLAG},? *|--library-path=)([^\"\n ]+|\"[^\"]+\")" MPI_INDIRECT_LINK_PATHS "${MPI_LINK_FLAGS_RAW}") foreach(_MPI_LPATH IN LISTS MPI_INDIRECT_LINK_PATHS) @@ -733,7 +733,7 @@ function (_MPI_interrogate_compiler LANG) endforeach() # We need to remove the flags we extracted from the linker flag list now. - string(REGEX REPLACE "(^| )(-Wl,|-Xlinker +)(${CMAKE_LIBRARY_PATH_FLAG},? *(-Wl,|-Xlinker +)?|--library-path=)([^\" ]+|\"[^\"]+\")" "" + string(REGEX REPLACE "(^| )(-Wl,|-Xlinker +)(${CMAKE_LIBRARY_PATH_FLAG},? *(-Wl,|-Xlinker +)?|--library-path=)([^\"\n ]+|\"[^\"]+\")" "" MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE}") # Some MPI implementations pass on options they themselves were built with. Since -z,noexecstack is a common @@ -742,7 +742,7 @@ function (_MPI_interrogate_compiler LANG) string(REGEX REPLACE "(^| )-Xlinker +-z +-Xlinker +[^ ]+" "" MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE_FILTERED}") # We only consider options of the form -Wl or -Xlinker: - string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker +)([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE_FILTERED}") + string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker +)([^\"\n ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE_FILTERED}") # As a next step, we assemble the linker flags extracted in a preliminary flags string foreach(_MPI_LINK_FLAG IN LISTS MPI_ALL_LINK_FLAGS) @@ -755,7 +755,7 @@ function (_MPI_interrogate_compiler LANG) endforeach() else() # In the filtered case, we obtain the link time flags by just stripping the library paths. - string(REGEX REPLACE "(^| )${CMAKE_LIBRARY_PATH_FLAG} *([^\" ]+|\"[^\"]+\")" "" MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE}") + string(REGEX REPLACE "(^| )${CMAKE_LIBRARY_PATH_FLAG} *([^\"\n ]+|\"[^\"]+\")" "" MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE}") endif() # If we failed to extract any linker paths, we'll try using the -showme:libdirs option with the MPI compiler. @@ -777,7 +777,7 @@ function (_MPI_interrogate_compiler LANG) # Extract the set of libraries to link against from the link command line # This only makes sense if CMAKE_LINK_LIBRARY_FLAG is defined, i.e. a -lxxxx syntax is supported by the compiler. if(CMAKE_LINK_LIBRARY_FLAG) - string(REGEX MATCHALL "(^| )${CMAKE_LINK_LIBRARY_FLAG}([^\" ]+|\"[^\"]+\")" + string(REGEX MATCHALL "(^| )${CMAKE_LINK_LIBRARY_FLAG}([^\"\n ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}") foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES) @@ -800,7 +800,7 @@ function (_MPI_interrogate_compiler LANG) else() string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_SHARED_LIBRARY_SUFFIX}") endif() - set(_MPI_LIB_NAME_REGEX "(([^\" ]+(${_MPI_LIB_SUFFIX_REGEX}))|(\"[^\"]+(${_MPI_LIB_SUFFIX_REGEX})\"))( +|$)") + set(_MPI_LIB_NAME_REGEX "(([^\"\n ]+(${_MPI_LIB_SUFFIX_REGEX}))|(\"[^\"]+(${_MPI_LIB_SUFFIX_REGEX})\"))( +|$)") string(REPLACE "." "\\." _MPI_LIB_NAME_REGEX "${_MPI_LIB_NAME_REGEX}") string(REGEX MATCHALL "${_MPI_LIB_NAME_REGEX}" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")