From 0723b2c93590b45a9f551c2ece2d2b80a2a2ae1d Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Fri, 17 Sep 2021 16:11:58 +0200 Subject: MPI: Add fallback detection code for MPI when cross compiling The MPI libraries use a compiler wrapper to automatically inject required flags and libraries into the compiler argument list. However, the wrapper does not support cross-compiling: the wrapper will try to invoke the native compiler which cannot handle the cross architecture MPI libraries and fail. This MR adds some fallback code for this case, which tries to bypass the faulty wrapper and determine the necessary flags and libraries directly from the MPI pkg-config files. The patch tries to be as unintrusive as possible and should not break any existing use-cases. Fixes: #22650 --- Modules/FindMPI.cmake | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'Modules/FindMPI.cmake') diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index d4b4a34af0..62412aeec5 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -267,6 +267,7 @@ cmake_policy(PUSH) cmake_policy(SET CMP0057 NEW) # if IN_LIST include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/FindPkgConfig.cmake) # Generic compiler names set(_MPI_C_GENERIC_COMPILER_NAMES mpicc mpcc mpicc_r mpcc_r) @@ -1572,7 +1573,40 @@ foreach(LANG IN ITEMS C CXX Fortran) if(NOT MPI_PINNED_COMPILER AND NOT MPI_${LANG}_WRAPPER_FOUND) # If MPI_PINNED_COMPILER wasn't given, and the MPI compiler we potentially found didn't work, we withdraw it. set(MPI_${LANG}_COMPILER "MPI_${LANG}_COMPILER-NOTFOUND" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE) - if(NOT MPI_SKIP_GUESSING) + + if(LANG STREQUAL "C") + set(_MPI_PKG "mpi-c") + elseif(LANG STREQUAL "CXX") + set(_MPI_PKG "mpi-cxx") + elseif(LANG STREQUAL "Fortran") + set(_MPI_PKG "mpi-fort") + else() + set(_MPI_PKG "") + endif() + if(_MPI_PKG) + pkg_check_modules("MPI_${LANG}_PKG" "${_MPI_PKG}") + if("${MPI_${LANG}_PKG_FOUND}") + set(MPI_${LANG}_COMPILE_OPTIONS ${MPI_${LANG}_PKG_CFLAGS} CACHE STRING "MPI ${LANG} compilation options" FORCE) + set(MPI_${LANG}_INCLUDE_PATH ${MPI_${LANG}_PKG_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} include directories" FORCE) + set(MPI_${LANG}_LINK_FLAGS ${MPI_${LANG}_PKG_LDFLAGS} CACHE STRING "MPI ${LANG} linker flags" FORCE) + set(MPI_${LANG}_LIB_NAMES ${MPI_${LANG}_PKG_LIBRARIES} CACHE STRING "MPI ${LANG} libraries to link against" FORCE) + foreach(_MPI_LIB IN LISTS MPI_${LANG}_LIB_NAMES) + if(_MPI_LIB) + get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB}" NAME_WE) + get_filename_component(_MPI_LIB_NAME "${_MPI_LIB}" NAME) + get_filename_component(_MPI_LIB_DIR "${_MPI_LIB}" DIRECTORY) + find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY + NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}" + HINTS ${_MPI_LIB_DIR} + DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI" + ) + mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY) + endif() + endforeach() + endif() + endif() + + if(NOT MPI_SKIP_GUESSING AND NOT "${MPI_${LANG}_PKG_FOUND}") # For C++, we may use the settings for C. Should a given compiler wrapper for C++ not exist, but one for C does, we copy over the # settings for C. An MPI distribution that is in this situation would be IBM Platform MPI. if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND) -- cgit v1.2.1