1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5FindMPI
6-------
7
8Find a Message Passing Interface (MPI) implementation.
9
10The Message Passing Interface (MPI) is a library used to write
11high-performance distributed-memory parallel applications, and is
12typically deployed on a cluster.  MPI is a standard interface (defined
13by the MPI forum) for which many implementations are available.
14
15.. versionadded:: 3.10
16  Major overhaul of the module: many new variables, per-language components,
17  support for a wider variety of runtimes.
18
19Variables for using MPI
20^^^^^^^^^^^^^^^^^^^^^^^
21
22The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``.
23Each of these controls the various MPI languages to search for.
24The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the
25MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API
26that was removed again in MPI-3.
27
28Depending on the enabled components the following variables will be set:
29
30``MPI_FOUND``
31  Variable indicating that MPI settings for all requested languages have been found.
32  If no components are specified, this is true if MPI settings for all enabled languages
33  were detected. Note that the ``MPICXX`` component does not affect this variable.
34``MPI_VERSION``
35  Minimal version of MPI detected among the requested languages, or all enabled languages
36  if no components were specified.
37
38This module will set the following variables per language in your
39project, where ``<lang>`` is one of C, CXX, or Fortran:
40
41``MPI_<lang>_FOUND``
42  Variable indicating the MPI settings for ``<lang>`` were found and that
43  simple MPI test programs compile with the provided settings.
44``MPI_<lang>_COMPILER``
45  MPI compiler for ``<lang>`` if such a program exists.
46``MPI_<lang>_COMPILE_OPTIONS``
47  Compilation options for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
48``MPI_<lang>_COMPILE_DEFINITIONS``
49  Compilation definitions for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
50``MPI_<lang>_INCLUDE_DIRS``
51  Include path(s) for MPI header.
52``MPI_<lang>_LINK_FLAGS``
53  Linker flags for MPI programs.
54``MPI_<lang>_LIBRARIES``
55  All libraries to link MPI programs against.
56
57.. versionadded:: 3.9
58  Additionally, the following :prop_tgt:`IMPORTED` targets are defined:
59
60``MPI::MPI_<lang>``
61  Target for using MPI from ``<lang>``.
62
63The following variables indicating which bindings are present will be defined:
64
65``MPI_MPICXX_FOUND``
66  Variable indicating whether the MPI-2 C++ bindings are present (introduced in MPI-2, removed with MPI-3).
67``MPI_Fortran_HAVE_F77_HEADER``
68  True if the Fortran 77 header ``mpif.h`` is available.
69``MPI_Fortran_HAVE_F90_MODULE``
70  True if the Fortran 90 module ``mpi`` can be used for accessing MPI (MPI-2 and higher only).
71``MPI_Fortran_HAVE_F08_MODULE``
72  True if the Fortran 2008 ``mpi_f08`` is available to MPI programs (MPI-3 and higher only).
73
74If possible, the MPI version will be determined by this module. The facilities to detect the MPI version
75were introduced with MPI-1.2, and therefore cannot be found for older MPI versions.
76
77``MPI_<lang>_VERSION_MAJOR``
78  Major version of MPI implemented for ``<lang>`` by the MPI distribution.
79``MPI_<lang>_VERSION_MINOR``
80  Minor version of MPI implemented for ``<lang>`` by the MPI distribution.
81``MPI_<lang>_VERSION``
82  MPI version implemented for ``<lang>`` by the MPI distribution.
83
84Note that there's no variable for the C bindings being accessible through ``mpi.h``, since the MPI standards
85always have required this binding to work in both C and C++ code.
86
87For running MPI programs, the module sets the following variables
88
89``MPIEXEC_EXECUTABLE``
90  Executable for running MPI programs, if such exists.
91``MPIEXEC_NUMPROC_FLAG``
92  Flag to pass to ``mpiexec`` before giving it the number of processors to run on.
93``MPIEXEC_MAX_NUMPROCS``
94  Number of MPI processors to utilize. Defaults to the number
95  of processors detected on the host system.
96``MPIEXEC_PREFLAGS``
97  Flags to pass to ``mpiexec`` directly before the executable to run.
98``MPIEXEC_POSTFLAGS``
99  Flags to pass to ``mpiexec`` after other flags.
100
101Variables for locating MPI
102^^^^^^^^^^^^^^^^^^^^^^^^^^
103
104This module performs a four step search for an MPI implementation:
105
1061. Search for ``MPIEXEC_EXECUTABLE`` and, if found, use its base directory.
1072. Check if the compiler has MPI support built-in. This is the case if the user passed a
108   compiler wrapper as ``CMAKE_<LANG>_COMPILER`` or if they use Cray system compiler wrappers.
1093. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
1104. Try to find an MPI implementation that does not ship such a wrapper by guessing settings.
111   Currently, only Microsoft MPI and MPICH2 on Windows are supported.
112
113For controlling the ``MPIEXEC_EXECUTABLE`` step, the following variables may be set:
114
115``MPIEXEC_EXECUTABLE``
116  Manually specify the location of ``mpiexec``.
117``MPI_HOME``
118  Specify the base directory of the MPI installation.
119``ENV{MPI_HOME}``
120  Environment variable to specify the base directory of the MPI installation.
121``ENV{I_MPI_ROOT}``
122  Environment variable to specify the base directory of the MPI installation.
123
124For controlling the compiler wrapper step, the following variables may be set:
125
126``MPI_<lang>_COMPILER``
127  Search for the specified compiler wrapper and use it.
128``MPI_<lang>_COMPILER_FLAGS``
129  Flags to pass to the MPI compiler wrapper during interrogation. Some compiler wrappers
130  support linking debug or tracing libraries if a specific flag is passed and this variable
131  may be used to obtain them.
132``MPI_COMPILER_FLAGS``
133  Used to initialize ``MPI_<lang>_COMPILER_FLAGS`` if no language specific flag has been given.
134  Empty by default.
135``MPI_EXECUTABLE_SUFFIX``
136  A suffix which is appended to all names that are being looked for. For instance you may set this
137  to ``.mpich`` or ``.openmpi`` to prefer the one or the other on Debian and its derivatives.
138
139In order to control the guessing step, the following variable may be set:
140
141``MPI_GUESS_LIBRARY_NAME``
142  Valid values are ``MSMPI`` and ``MPICH2``. If set, only the given library will be searched for.
143  By default, ``MSMPI`` will be preferred over ``MPICH2`` if both are available.
144  This also sets ``MPI_SKIP_COMPILER_WRAPPER`` to ``true``, which may be overridden.
145
146Each of the search steps may be skipped with the following control variables:
147
148``MPI_ASSUME_NO_BUILTIN_MPI``
149  If true, the module assumes that the compiler itself does not provide an MPI implementation and
150  skips to step 2.
151``MPI_SKIP_COMPILER_WRAPPER``
152  If true, no compiler wrapper will be searched for.
153``MPI_SKIP_GUESSING``
154  If true, the guessing step will be skipped.
155
156Additionally, the following control variable is available to change search behavior:
157
158``MPI_CXX_SKIP_MPICXX``
159  Add some definitions that will disable the MPI-2 C++ bindings.
160  Currently supported are MPICH, Open MPI, Platform MPI and derivatives thereof,
161  for example MVAPICH or Intel MPI.
162
163If the find procedure fails for a variable ``MPI_<lang>_WORKS``, then the settings detected by or passed to
164the module did not work and even a simple MPI test program failed to compile.
165
166If all of these parameters were not sufficient to find the right MPI implementation, a user may
167disable the entire autodetection process by specifying both a list of libraries in ``MPI_<lang>_LIBRARIES``
168and a list of include directories in ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``.
169Any other variable may be set in addition to these two. The module will then validate the MPI settings and store the
170settings in the cache.
171
172Cache variables for MPI
173^^^^^^^^^^^^^^^^^^^^^^^
174
175The variable ``MPI_<lang>_INCLUDE_DIRS`` will be assembled from the following variables.
176For C and CXX:
177
178``MPI_<lang>_HEADER_DIR``
179  Location of the ``mpi.h`` header on disk.
180
181For Fortran:
182
183``MPI_Fortran_F77_HEADER_DIR``
184  Location of the Fortran 77 header ``mpif.h``, if it exists.
185``MPI_Fortran_MODULE_DIR``
186  Location of the ``mpi`` or ``mpi_f08`` modules, if available.
187
188For all languages the following variables are additionally considered:
189
190``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``
191  A :ref:`;-list <CMake Language Lists>` of paths needed in addition to the normal include directories.
192``MPI_<include_name>_INCLUDE_DIR``
193  Path variables for include folders referred to by ``<include_name>``.
194``MPI_<lang>_ADDITIONAL_INCLUDE_VARS``
195  A :ref:`;-list <CMake Language Lists>` of ``<include_name>`` that will be added to the include locations of ``<lang>``.
196
197The variable ``MPI_<lang>_LIBRARIES`` will be assembled from the following variables:
198
199``MPI_<lib_name>_LIBRARY``
200  The location of a library called ``<lib_name>`` for use with MPI.
201``MPI_<lang>_LIB_NAMES``
202  A :ref:`;-list <CMake Language Lists>` of ``<lib_name>`` that will be added to the include locations of ``<lang>``.
203
204Usage of mpiexec
205^^^^^^^^^^^^^^^^
206
207When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically
208use all of the ``MPIEXEC_EXECUTABLE`` flags as follows:
209
210::
211
212   ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
213     ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
214
215where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to
216pass to the MPI program.
217
218Advanced variables for using MPI
219^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
220
221The module can perform some advanced feature detections upon explicit request.
222
223**Important notice:** The following checks cannot be performed without *executing* an MPI test program.
224Consider the special considerations for the behavior of :command:`try_run` during cross compilation.
225Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems.
226You should only enable these detections if you absolutely need the information.
227
228If the following variables are set to true, the respective search will be performed:
229
230``MPI_DETERMINE_Fortran_CAPABILITIES``
231  Determine for all available Fortran bindings what the values of ``MPI_SUBARRAYS_SUPPORTED`` and
232  ``MPI_ASYNC_PROTECTS_NONBLOCKING`` are and make their values available as ``MPI_Fortran_<binding>_SUBARRAYS``
233  and ``MPI_Fortran_<binding>_ASYNCPROT``, where ``<binding>`` is one of ``F77_HEADER``, ``F90_MODULE`` and
234  ``F08_MODULE``.
235``MPI_DETERMINE_LIBRARY_VERSION``
236  For each language, find the output of ``MPI_Get_library_version`` and make it available as ``MPI_<lang>_LIBRARY_VERSION_STRING``.
237  This information is usually tied to the runtime component of an MPI implementation and might differ depending on ``<lang>``.
238  Note that the return value is entirely implementation defined. This information might be used to identify
239  the MPI vendor and for example pick the correct one of multiple third party binaries that matches the MPI vendor.
240
241Backward Compatibility
242^^^^^^^^^^^^^^^^^^^^^^
243
244.. deprecated:: 3.10
245
246For backward compatibility with older versions of FindMPI, these
247variables are set:
248
249::
250
251   MPI_COMPILER        MPI_LIBRARY        MPI_EXTRA_LIBRARY
252   MPI_COMPILE_FLAGS   MPI_INCLUDE_PATH   MPI_LINK_FLAGS
253   MPI_LIBRARIES
254
255In new projects, please use the ``MPI_<lang>_XXX`` equivalents.
256Additionally, the following variables are deprecated:
257
258``MPI_<lang>_COMPILE_FLAGS``
259  Use ``MPI_<lang>_COMPILE_OPTIONS`` and ``MPI_<lang>_COMPILE_DEFINITIONS`` instead.
260``MPI_<lang>_INCLUDE_PATH``
261  For consumption use ``MPI_<lang>_INCLUDE_DIRS`` and for specifying folders use ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`` instead.
262``MPIEXEC``
263  Use ``MPIEXEC_EXECUTABLE`` instead.
264#]=======================================================================]
265
266cmake_policy(PUSH)
267cmake_policy(SET CMP0057 NEW) # if IN_LIST
268
269include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
270find_package(PkgConfig QUIET)
271
272# Generic compiler names
273set(_MPI_C_GENERIC_COMPILER_NAMES          mpicc    mpcc      mpicc_r mpcc_r)
274set(_MPI_CXX_GENERIC_COMPILER_NAMES        mpicxx   mpiCC     mpcxx   mpCC    mpic++   mpc++
275                                           mpicxx_r mpiCC_r   mpcxx_r mpCC_r  mpic++_r mpc++_r)
276set(_MPI_Fortran_GENERIC_COMPILER_NAMES    mpif95   mpif95_r  mpf95   mpf95_r
277                                           mpif90   mpif90_r  mpf90   mpf90_r
278                                           mpif77   mpif77_r  mpf77   mpf77_r
279                                           mpifc)
280
281#Fujitsu cross/own compiler names
282set(_MPI_Fujitsu_C_COMPILER_NAMES        mpifccpx mpifcc)
283set(_MPI_Fujitsu_CXX_COMPILER_NAMES      mpiFCCpx mpiFCC)
284set(_MPI_Fujitsu_Fortran_COMPILER_NAMES  mpifrtpx mpifrt)
285
286# GNU compiler names
287set(_MPI_GNU_C_COMPILER_NAMES              mpigcc mpgcc mpigcc_r mpgcc_r)
288set(_MPI_GNU_CXX_COMPILER_NAMES            mpig++ mpg++ mpig++_r mpg++_r mpigxx)
289set(_MPI_GNU_Fortran_COMPILER_NAMES        mpigfortran mpgfortran mpigfortran_r mpgfortran_r
290                                           mpig77 mpig77_r mpg77 mpg77_r)
291
292# Intel MPI compiler names on Windows
293if(WIN32)
294  list(APPEND _MPI_C_GENERIC_COMPILER_NAMES       mpicc.bat)
295  list(APPEND _MPI_CXX_GENERIC_COMPILER_NAMES     mpicxx.bat)
296  list(APPEND _MPI_Fortran_GENERIC_COMPILER_NAMES mpifc.bat)
297
298  # Intel MPI compiler names
299  set(_MPI_Intel_C_COMPILER_NAMES            mpiicc.bat)
300  set(_MPI_Intel_CXX_COMPILER_NAMES          mpiicpc.bat)
301  set(_MPI_Intel_Fortran_COMPILER_NAMES      mpiifort.bat mpif77.bat mpif90.bat)
302
303  # Intel MPI compiler names
304  set(_MPI_IntelLLVM_C_COMPILER_NAMES            mpiicc.bat)
305  set(_MPI_IntelLLVM_CXX_COMPILER_NAMES          mpiicpc.bat)
306  set(_MPI_IntelLLVM_Fortran_COMPILER_NAMES      mpiifort.bat mpif77.bat mpif90.bat)
307
308  # Intel MPI compiler names for MSMPI
309  set(_MPI_MSVC_C_COMPILER_NAMES             mpicl.bat)
310  set(_MPI_MSVC_CXX_COMPILER_NAMES           mpicl.bat)
311else()
312  # Intel compiler names
313  set(_MPI_Intel_C_COMPILER_NAMES            mpiicc)
314  set(_MPI_Intel_CXX_COMPILER_NAMES          mpiicpc  mpiicxx mpiic++)
315  set(_MPI_Intel_Fortran_COMPILER_NAMES      mpiifort mpiif95 mpiif90 mpiif77)
316
317  # Intel compiler names
318  set(_MPI_IntelLLVM_C_COMPILER_NAMES            mpiicc)
319  set(_MPI_IntelLLVM_CXX_COMPILER_NAMES          mpiicpc  mpiicxx mpiic++)
320  set(_MPI_IntelLLVM_Fortran_COMPILER_NAMES      mpiifort mpiif95 mpiif90 mpiif77)
321endif()
322
323# PGI compiler names
324set(_MPI_PGI_C_COMPILER_NAMES              mpipgicc mpipgcc mppgcc)
325set(_MPI_PGI_CXX_COMPILER_NAMES            mpipgic++ mpipgCC mppgCC)
326set(_MPI_PGI_Fortran_COMPILER_NAMES        mpipgifort mpipgf95 mpipgf90 mppgf95 mppgf90 mpipgf77 mppgf77)
327
328# XLC MPI Compiler names
329set(_MPI_XL_C_COMPILER_NAMES               mpxlc      mpxlc_r    mpixlc     mpixlc_r)
330set(_MPI_XL_CXX_COMPILER_NAMES             mpixlcxx   mpixlC     mpixlc++   mpxlcxx   mpxlc++   mpixlc++   mpxlCC
331                                           mpixlcxx_r mpixlC_r   mpixlc++_r mpxlcxx_r mpxlc++_r mpixlc++_r mpxlCC_r)
332set(_MPI_XL_Fortran_COMPILER_NAMES         mpixlf95   mpixlf95_r mpxlf95 mpxlf95_r
333                                           mpixlf90   mpixlf90_r mpxlf90 mpxlf90_r
334                                           mpixlf77   mpixlf77_r mpxlf77 mpxlf77_r
335                                           mpixlf     mpixlf_r   mpxlf   mpxlf_r)
336
337# Cray Compiler names
338set(_MPI_Cray_C_COMPILER_NAMES             cc)
339set(_MPI_Cray_CXX_COMPILER_NAMES           CC)
340set(_MPI_Cray_Fortran_COMPILER_NAMES       ftn)
341
342# Prepend vendor-specific compiler wrappers to the list. If we don't know the compiler,
343# attempt all of them.
344# By attempting vendor-specific compiler names first, we should avoid situations where the compiler wrapper
345# stems from a proprietary MPI and won't know which compiler it's being used for. For instance, Intel MPI
346# controls its settings via the I_MPI_CC environment variables if the generic name is being used.
347# If we know which compiler we're working with, we can use the most specialized wrapper there is in order to
348# pick up the right settings for it.
349foreach (LANG IN ITEMS C CXX Fortran)
350  set(_MPI_${LANG}_COMPILER_NAMES "")
351  foreach (id IN ITEMS Fujitsu FujitsuClang GNU Intel IntelLLVM MSVC PGI XL)
352    if (NOT CMAKE_${LANG}_COMPILER_ID OR CMAKE_${LANG}_COMPILER_ID STREQUAL id)
353      foreach(_COMPILER_NAME IN LISTS _MPI_${id}_${LANG}_COMPILER_NAMES)
354        list(APPEND _MPI_${LANG}_COMPILER_NAMES ${_COMPILER_NAME}${MPI_EXECUTABLE_SUFFIX})
355      endforeach()
356    endif()
357    unset(_MPI_${id}_${LANG}_COMPILER_NAMES)
358  endforeach()
359  foreach(_COMPILER_NAME IN LISTS _MPI_${LANG}_GENERIC_COMPILER_NAMES)
360    list(APPEND _MPI_${LANG}_COMPILER_NAMES ${_COMPILER_NAME}${MPI_EXECUTABLE_SUFFIX})
361  endforeach()
362  unset(_MPI_${LANG}_GENERIC_COMPILER_NAMES)
363endforeach()
364
365# Names to try for mpiexec
366# Only mpiexec commands are guaranteed to behave as described in the standard,
367# mpirun commands are not covered by the standard in any way whatsoever.
368# lamexec is the executable for LAM/MPI, srun is for SLURM or Open MPI with SLURM support.
369# srun -n X <executable> is however a valid command, so it behaves 'like' mpiexec.
370set(_MPIEXEC_NAMES_BASE                   mpiexec mpiexec.hydra mpiexec.mpd mpirun lamexec srun)
371
372unset(_MPIEXEC_NAMES)
373foreach(_MPIEXEC_NAME IN LISTS _MPIEXEC_NAMES_BASE)
374  list(APPEND _MPIEXEC_NAMES "${_MPIEXEC_NAME}${MPI_EXECUTABLE_SUFFIX}")
375endforeach()
376unset(_MPIEXEC_NAMES_BASE)
377
378function (_MPI_check_compiler LANG QUERY_FLAG OUTPUT_VARIABLE RESULT_VARIABLE)
379  if(DEFINED MPI_${LANG}_COMPILER_FLAGS)
380    separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS NATIVE_COMMAND "${MPI_${LANG}_COMPILER_FLAGS}")
381  else()
382    separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS NATIVE_COMMAND "${MPI_COMPILER_FLAGS}")
383  endif()
384  execute_process(
385    COMMAND ${MPI_${LANG}_COMPILER} ${_MPI_COMPILER_WRAPPER_OPTIONS} ${QUERY_FLAG}
386    OUTPUT_VARIABLE  WRAPPER_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE
387    ERROR_VARIABLE   WRAPPER_OUTPUT ERROR_STRIP_TRAILING_WHITESPACE
388    RESULT_VARIABLE  WRAPPER_RETURN)
389  # Some compiler wrappers will yield spurious zero return values, for example
390  # Intel MPI tolerates unknown arguments and if the MPI wrappers loads a shared
391  # library that has invalid or missing version information there would be warning
392  # messages emitted by ld.so in the compiler output. In either case, we'll treat
393  # the output as invalid.
394  if("${WRAPPER_OUTPUT}" MATCHES "undefined reference|unrecognized|need to set|no version information available|command not found")
395    set(WRAPPER_RETURN 255)
396  endif()
397  # Ensure that no error output might be passed upwards.
398  if(NOT WRAPPER_RETURN EQUAL 0)
399    unset(WRAPPER_OUTPUT)
400  else()
401    # Strip leading whitespace
402    string(REGEX REPLACE "^ +" "" WRAPPER_OUTPUT "${WRAPPER_OUTPUT}")
403  endif()
404  set(${OUTPUT_VARIABLE} "${WRAPPER_OUTPUT}" PARENT_SCOPE)
405  set(${RESULT_VARIABLE} "${WRAPPER_RETURN}" PARENT_SCOPE)
406endfunction()
407
408macro(_MPI_env_set_ifnot VAR VALUE)
409  if(NOT DEFINED ENV{${VAR}})
410    set(_MPI_${VAR}_WAS_SET FALSE)
411    set(ENV{${VAR}} ${${VALUE}})
412  else()
413    set(_MPI_${VAR}_WAS_SET TRUE)
414  endif()
415endmacro()
416
417macro(_MPI_env_unset_ifnot VAR)
418  if(NOT _MPI_${VAR}_WAS_SET)
419    unset(ENV{${VAR}})
420  endif()
421endmacro()
422
423function (_MPI_interrogate_compiler LANG)
424  unset(MPI_COMPILE_CMDLINE)
425  unset(MPI_LINK_CMDLINE)
426
427  unset(MPI_COMPILE_OPTIONS_WORK)
428  unset(MPI_COMPILE_DEFINITIONS_WORK)
429  unset(MPI_INCLUDE_DIRS_WORK)
430  unset(MPI_LINK_FLAGS_WORK)
431  unset(MPI_LIB_NAMES_WORK)
432  unset(MPI_LIB_FULLPATHS_WORK)
433
434  # Define the MPICH and Intel MPI compiler variables to the compilers set in CMake.
435  # It's possible to have a per-compiler configuration in these MPI implementations and
436  # a particular MPICH derivate might check compiler interoperability.
437  # Intel MPI in particular does this with I_MPI_CHECK_COMPILER.
438  file(TO_NATIVE_PATH "${CMAKE_${LANG}_COMPILER}" _MPI_UNDERLAYING_COMPILER)
439  # On Windows, the Intel MPI batch scripts can only work with filnames - Full paths will break them.
440  # Due to the lack of other MPICH-based wrappers for Visual C++, we may treat this as default.
441  if(MSVC)
442    get_filename_component(_MPI_UNDERLAYING_COMPILER "${_MPI_UNDERLAYING_COMPILER}" NAME)
443  endif()
444  if("${LANG}" STREQUAL "C")
445    _MPI_env_set_ifnot(I_MPI_CC _MPI_UNDERLAYING_COMPILER)
446    _MPI_env_set_ifnot(MPICH_CC _MPI_UNDERLAYING_COMPILER)
447  elseif("${LANG}" STREQUAL "CXX")
448    _MPI_env_set_ifnot(I_MPI_CXX _MPI_UNDERLAYING_COMPILER)
449    _MPI_env_set_ifnot(MPICH_CXX _MPI_UNDERLAYING_COMPILER)
450  elseif("${LANG}" STREQUAL "Fortran")
451    _MPI_env_set_ifnot(I_MPI_FC _MPI_UNDERLAYING_COMPILER)
452    _MPI_env_set_ifnot(MPICH_FC _MPI_UNDERLAYING_COMPILER)
453    _MPI_env_set_ifnot(I_MPI_F77 _MPI_UNDERLAYING_COMPILER)
454    _MPI_env_set_ifnot(MPICH_F77 _MPI_UNDERLAYING_COMPILER)
455    _MPI_env_set_ifnot(I_MPI_F90 _MPI_UNDERLAYING_COMPILER)
456    _MPI_env_set_ifnot(MPICH_F90 _MPI_UNDERLAYING_COMPILER)
457  endif()
458
459  # Set these two variables for Intel MPI:
460  #   - I_MPI_DEBUG_INFO_STRIP: It adds 'objcopy' lines to the compiler output. We support stripping them
461  #     (see below), but if we can avoid them in the first place, we should.
462  #   - I_MPI_FORT_BIND: By default Intel MPI makes the C/C++ compiler wrappers link Fortran bindings.
463  #     This is so that mixed-language code doesn't require additional libraries when linking with mpicc.
464  #     For our purposes, this makes little sense, since correct MPI usage from CMake already circumvenes this.
465  set(_MPI_ENV_VALUE "disable")
466  _MPI_env_set_ifnot(I_MPI_DEBUG_INFO_STRIP _MPI_ENV_VALUE)
467  _MPI_env_set_ifnot(I_MPI_FORT_BIND _MPI_ENV_VALUE)
468
469  # Check whether the -showme:compile option works. This indicates that we have either Open MPI
470  # or a newer version of LAM/MPI, and implies that -showme:link will also work.
471  # Open MPI also supports -show, but separates linker and compiler information
472  _MPI_check_compiler(${LANG} "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
473  if (MPI_COMPILER_RETURN EQUAL 0)
474    _MPI_check_compiler(${LANG} "-showme:link" MPI_LINK_CMDLINE MPI_COMPILER_RETURN)
475
476    if (NOT MPI_COMPILER_RETURN EQUAL 0)
477      unset(MPI_COMPILE_CMDLINE)
478    endif()
479  endif()
480
481  # MPICH and MVAPICH offer -compile-info and -link-info.
482  # For modern versions, both do the same as -show. However, for old versions, they do differ
483  # when called for mpicxx and mpif90 and it's necessary to use them over -show in order to find the
484  # removed MPI C++ bindings.
485  if (NOT MPI_COMPILER_RETURN EQUAL 0)
486    _MPI_check_compiler(${LANG} "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
487
488    if (MPI_COMPILER_RETURN EQUAL 0)
489      _MPI_check_compiler(${LANG} "-link-info" MPI_LINK_CMDLINE MPI_COMPILER_RETURN)
490
491      if (NOT MPI_COMPILER_RETURN EQUAL 0)
492        unset(MPI_COMPILE_CMDLINE)
493      endif()
494    endif()
495  endif()
496
497  # Cray compiler wrappers come usually without a separate mpicc/c++/ftn, but offer
498  # --cray-print-opts=...
499  if (NOT MPI_COMPILER_RETURN EQUAL 0)
500    _MPI_check_compiler(${LANG} "--cray-print-opts=cflags"
501                        MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
502
503    if (MPI_COMPILER_RETURN EQUAL 0)
504      # Pass --no-as-needed so the mpi library is always linked. Otherwise, the
505      # Cray compiler wrapper puts an --as-needed flag around the mpi library,
506      # and it is not linked unless code directly refers to it.
507      _MPI_check_compiler(${LANG} "--no-as-needed;--cray-print-opts=libs"
508                          MPI_LINK_CMDLINE MPI_COMPILER_RETURN)
509
510      if (NOT MPI_COMPILER_RETURN EQUAL 0)
511        unset(MPI_COMPILE_CMDLINE)
512        unset(MPI_LINK_CMDLINE)
513      endif()
514    endif()
515  endif()
516
517  # MPICH, MVAPICH2 and Intel MPI just use "-show". Open MPI also offers this, but the
518  # -showme commands are more specialized.
519  if (NOT MPI_COMPILER_RETURN EQUAL 0)
520    _MPI_check_compiler(${LANG} "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
521  endif()
522
523  # Older versions of LAM/MPI have "-showme". Open MPI also supports this.
524  # Unknown to MPICH, MVAPICH and Intel MPI.
525  if (NOT MPI_COMPILER_RETURN EQUAL 0)
526    _MPI_check_compiler(${LANG} "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
527  endif()
528
529  if (MPI_COMPILER_RETURN EQUAL 0 AND DEFINED MPI_COMPILE_CMDLINE)
530    # Intel MPI can be run with -compchk or I_MPI_CHECK_COMPILER set to 1.
531    # In this case, -show will be prepended with a line to the compiler checker. This is a script that performs
532    # compatibility checks and returns a non-zero exit code together with an error if something fails.
533    # It has to be called as "compchk.sh <arch> <compiler>". Here, <arch> is one out of 32 (i686), 64 (ia64) or 32e (x86_64).
534    # The compiler is identified by filename, and can be either the MPI compiler or the underlying compiler.
535    # NOTE: It is vital to run this script while the environment variables are set up, otherwise it can check the wrong compiler.
536    if("${MPI_COMPILE_CMDLINE}" MATCHES "^([^\" ]+/compchk.sh|\"[^\"]+/compchk.sh\") +([^ ]+)")
537      # Now CMAKE_MATCH_1 contains the path to the compchk.sh file and CMAKE_MATCH_2 the architecture flag.
538      unset(COMPILER_CHECKER_OUTPUT)
539      execute_process(
540      COMMAND ${CMAKE_MATCH_1} ${CMAKE_MATCH_2} ${MPI_${LANG}_COMPILER}
541      OUTPUT_VARIABLE  COMPILER_CHECKER_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE
542      ERROR_VARIABLE   COMPILER_CHECKER_OUTPUT ERROR_STRIP_TRAILING_WHITESPACE
543      RESULT_VARIABLE  MPI_COMPILER_RETURN)
544      # If it returned a non-zero value, the check below will fail and cause the interrogation to be aborted.
545      if(NOT MPI_COMPILER_RETURN EQUAL 0)
546        if(NOT MPI_FIND_QUIETLY)
547          message(STATUS "Intel MPI compiler check failed: ${COMPILER_CHECKER_OUTPUT}")
548        endif()
549      else()
550        # Since the check passed, we can remove the compchk.sh script.
551        string(REGEX REPLACE "^([^\" ]+|\"[^\"]+\")/compchk.sh.*\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
552      endif()
553    endif()
554  endif()
555
556  # Revert changes to the environment made previously
557  if("${LANG}" STREQUAL "C")
558    _MPI_env_unset_ifnot(I_MPI_CC)
559    _MPI_env_unset_ifnot(MPICH_CC)
560  elseif("${LANG}" STREQUAL "CXX")
561    _MPI_env_unset_ifnot(I_MPI_CXX)
562    _MPI_env_unset_ifnot(MPICH_CXX)
563  elseif("${LANG}" STREQUAL "Fortran")
564    _MPI_env_unset_ifnot(I_MPI_FC)
565    _MPI_env_unset_ifnot(MPICH_FC)
566    _MPI_env_unset_ifnot(I_MPI_F77)
567    _MPI_env_unset_ifnot(MPICH_F77)
568    _MPI_env_unset_ifnot(I_MPI_F90)
569    _MPI_env_unset_ifnot(MPICH_F90)
570  endif()
571
572  _MPI_env_unset_ifnot(I_MPI_DEBUG_INFO_STRIP)
573  _MPI_env_unset_ifnot(I_MPI_FORT_BIND)
574
575  if (NOT (MPI_COMPILER_RETURN EQUAL 0) OR NOT (DEFINED MPI_COMPILE_CMDLINE))
576    # Cannot interrogate this compiler, so exit.
577    set(MPI_${LANG}_WRAPPER_FOUND FALSE PARENT_SCOPE)
578    return()
579  endif()
580  unset(MPI_COMPILER_RETURN)
581
582  # We have our command lines, but we might need to copy MPI_COMPILE_CMDLINE
583  # into MPI_LINK_CMDLINE, if we didn't find the link line.
584  if (NOT DEFINED MPI_LINK_CMDLINE)
585    set(MPI_LINK_CMDLINE "${MPI_COMPILE_CMDLINE}")
586  endif()
587
588  # Visual Studio parsers permit each flag prefixed by either / or -.
589  # We'll normalize this to the - syntax we use for CMake purposes anyways.
590  if(MSVC)
591    foreach(_MPI_VARIABLE IN ITEMS COMPILE LINK)
592      # The Intel MPI wrappers on Windows prefix their output with some copyright boilerplate.
593      # To prevent possible problems, we discard this text before proceeding with any further matching.
594      string(REGEX REPLACE "^[^ ]+ for the Intel\\(R\\) MPI Library [^\n]+ for Windows\\*\nCopyright\\(C\\) [^\n]+, Intel Corporation\\. All rights reserved\\.\n\n" ""
595        MPI_${_MPI_VARIABLE}_CMDLINE "${MPI_${_MPI_VARIABLE}_CMDLINE}")
596      string(REGEX REPLACE "(^| )/" "\\1-" MPI_${_MPI_VARIABLE}_CMDLINE "${MPI_${_MPI_VARIABLE}_CMDLINE}")
597      string(REPLACE "-libpath:" "-LIBPATH:" MPI_${_MPI_VARIABLE}_CMDLINE "${MPI_${_MPI_VARIABLE}_CMDLINE}")
598    endforeach()
599  endif()
600
601  # For MSVC and cl-compatible compilers, the keyword /link indicates a point after which
602  # everything following is passed to the linker. In this case, we drop all prior information
603  # from the link line and treat any unknown extra flags as linker flags.
604  set(_MPI_FILTERED_LINK_INFORMATION FALSE)
605  if(MSVC)
606    if(MPI_LINK_CMDLINE MATCHES " -(link|LINK) ")
607      string(REGEX REPLACE ".+-(link|LINK) +" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}")
608      set(_MPI_FILTERED_LINK_INFORMATION TRUE)
609    endif()
610    string(REGEX REPLACE " +-(link|LINK) .+" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
611  endif()
612
613  if(UNIX)
614    # At this point, we obtained some output from a compiler wrapper that works.
615    # We'll now try to parse it into variables with meaning to us.
616    if("${LANG}" STREQUAL "Fortran")
617      # If MPICH (and derivates) didn't recognize the Fortran compiler include flag during configuration,
618      # they'll return a set of three commands, consisting out of a symlink command for mpif.h,
619      # the actual compiler command and deletion of the created symlink.
620      # Especially with M(VA)PICH-1, this appears to happen erroneously, and therefore we should translate
621      # this output into an additional include directory and then drop it from the output.
622      if("${MPI_COMPILE_CMDLINE}" MATCHES "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h")
623        get_filename_component(MPI_INCLUDE_DIRS_WORK "${CMAKE_MATCH_1}" DIRECTORY)
624        string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
625        string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}")
626        string(REGEX REPLACE "\nrm -f mpif.h$" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
627        string(REGEX REPLACE "\nrm -f mpif.h$" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}")
628      endif()
629    endif()
630
631    # If Intel MPI was configured for static linkage with -static_mpi, the wrapper will by default strip
632    # debug information from resulting binaries (see I_MPI_DEBUG_INFO_STRIP).
633    # Since we cannot process this information into CMake logic, we need to discard the resulting objcopy
634    # commands from the output.
635    string(REGEX REPLACE "(^|\n)objcopy[^\n]+(\n|$)" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
636    string(REGEX REPLACE "(^|\n)objcopy[^\n]+(\n|$)" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}")
637  endif()
638
639  # For Visual C++, extracting compiler options in a generic fashion isn't easy. However, no MPI implementation
640  # on Windows seems to require any specific ones, either.
641  if(NOT MSVC)
642    # Extract compile options from the compile command line.
643    string(REGEX MATCHALL "(^| )-f([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_OPTIONS "${MPI_COMPILE_CMDLINE}")
644
645    foreach(_MPI_COMPILE_OPTION IN LISTS MPI_ALL_COMPILE_OPTIONS)
646      string(REGEX REPLACE "^ " "" _MPI_COMPILE_OPTION "${_MPI_COMPILE_OPTION}")
647
648      # Ignore -fstack-protector directives: These occur on MPICH and MVAPICH when the libraries
649      # themselves were built with this flag. However, this flag is unrelated to using MPI, and
650      # we won't match the accompanying --param-ssp-size and -Wp,-D_FORTIFY_SOURCE flags and therefore
651      # produce inconsistent results with the regularly flags.
652      # Similarly, aliasing flags do not belong into our flag array.
653      # Also strip out `-framework` flags.
654      if(NOT "${_MPI_COMPILE_OPTION}" MATCHES "^-f((no-|)(stack-protector|strict-aliasing)|PI[CE]|pi[ce]|ramework)")
655        list(APPEND MPI_COMPILE_OPTIONS_WORK "${_MPI_COMPILE_OPTION}")
656      endif()
657    endforeach()
658  endif()
659
660  # For GNU-style compilers, it's possible to prefix includes and definitions with certain flags to pass them
661  # only to the preprocessor. For CMake purposes, we need to treat, but ignore such scopings.
662  # Note that we do not support spaces between the arguments, i.e. -Wp,-I -Wp,/opt/mympi will not be parsed
663  # correctly. This form does not seem to occur in any common MPI implementation, however.
664  if(NOT MSVC)
665    set(_MPI_PREPROCESSOR_FLAG_REGEX "(-Wp,|-Xpreprocessor )?")
666  else()
667    set(_MPI_PREPROCESSOR_FLAG_REGEX "")
668  endif()
669
670  # Same deal as above, for the definitions.
671  string(REGEX MATCHALL "(^| )${_MPI_PREPROCESSOR_FLAG_REGEX}-D *([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_DEFINITIONS "${MPI_COMPILE_CMDLINE}")
672
673  foreach(_MPI_COMPILE_DEFINITION IN LISTS MPI_ALL_COMPILE_DEFINITIONS)
674    string(REGEX REPLACE "^ ?${_MPI_PREPROCESSOR_FLAG_REGEX}-D *" "" _MPI_COMPILE_DEFINITION "${_MPI_COMPILE_DEFINITION}")
675    string(REPLACE "\"" "" _MPI_COMPILE_DEFINITION "${_MPI_COMPILE_DEFINITION}")
676    if(NOT "${_MPI_COMPILE_DEFINITION}" MATCHES "^_FORTIFY_SOURCE.*")
677      list(APPEND MPI_COMPILE_DEFINITIONS_WORK "${_MPI_COMPILE_DEFINITION}")
678    endif()
679  endforeach()
680
681  # Extract include paths from compile command line
682  string(REGEX MATCHALL "(^| )${_MPI_PREPROCESSOR_FLAG_REGEX}${CMAKE_INCLUDE_FLAG_${LANG}} *([^\" ]+|\"[^\"]+\")"
683    MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}")
684
685  # If extracting failed to work, we'll try using -showme:incdirs.
686  # Unlike before, we do this without the environment variables set up, but since only MPICH derivates are affected by any of them, and
687  # -showme:... is only supported by Open MPI and LAM/MPI, this isn't a concern.
688  if (NOT MPI_ALL_INCLUDE_PATHS)
689    _MPI_check_compiler(${LANG} "-showme:incdirs" MPI_INCDIRS_CMDLINE MPI_INCDIRS_COMPILER_RETURN)
690    if(MPI_INCDIRS_COMPILER_RETURN)
691      separate_arguments(MPI_ALL_INCLUDE_PATHS NATIVE_COMMAND "${MPI_INCDIRS_CMDLINE}")
692    endif()
693  endif()
694
695  foreach(_MPI_INCLUDE_PATH IN LISTS MPI_ALL_INCLUDE_PATHS)
696    string(REGEX REPLACE "^ ?${_MPI_PREPROCESSOR_FLAG_REGEX}${CMAKE_INCLUDE_FLAG_${LANG}} *" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}")
697    string(REPLACE "\"" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}")
698    string(REPLACE "'" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}")
699    get_filename_component(_MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}" REALPATH)
700    list(APPEND MPI_INCLUDE_DIRS_WORK "${_MPI_INCLUDE_PATH}")
701  endforeach()
702
703  # The next step are linker flags and library directories. Here, we first take the flags given in raw -L or -LIBPATH: syntax.
704  string(REGEX MATCHALL "(^| )${CMAKE_LIBRARY_PATH_FLAG} *([^\" ]+|\"[^\"]+\")" MPI_DIRECT_LINK_PATHS "${MPI_LINK_CMDLINE}")
705  foreach(_MPI_LPATH IN LISTS MPI_DIRECT_LINK_PATHS)
706    string(REGEX REPLACE "(^| )${CMAKE_LIBRARY_PATH_FLAG} *" "" _MPI_LPATH "${_MPI_LPATH}")
707    list(APPEND MPI_ALL_LINK_PATHS "${_MPI_LPATH}")
708  endforeach()
709
710  # If the link commandline hasn't been filtered (e.g. when using MSVC and /link), we need to extract the relevant parts first.
711  if(NOT _MPI_FILTERED_LINK_INFORMATION)
712    string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker +)([^\" ]+|\"[^\"]+\")" MPI_LINK_FLAGS "${MPI_LINK_CMDLINE}")
713
714    # In this case, we could also find some indirectly given linker paths, e.g. prefixed by -Xlinker or -Wl,
715    # Since syntaxes like -Wl,-L -Wl,/my/path/to/lib are also valid, we parse these paths by first removing -Wl, and -Xlinker
716    # from the list of filtered flags and then parse the remainder of the output.
717    string(REGEX REPLACE "(-Wl,|-Xlinker +)" "" MPI_LINK_FLAGS_RAW "${MPI_LINK_FLAGS}")
718
719    # Now we can parse the leftover output. Note that spaces can now be handled since the above example would reduce to
720    # -L /my/path/to/lib and can be extracted correctly.
721    string(REGEX MATCHALL "^(${CMAKE_LIBRARY_PATH_FLAG},? *|--library-path=)([^\" ]+|\"[^\"]+\")"
722      MPI_INDIRECT_LINK_PATHS "${MPI_LINK_FLAGS_RAW}")
723
724    foreach(_MPI_LPATH IN LISTS MPI_INDIRECT_LINK_PATHS)
725      string(REGEX REPLACE "^(${CMAKE_LIBRARY_PATH_FLAG},? *|--library-path=)" "" _MPI_LPATH "${_MPI_LPATH}")
726      list(APPEND MPI_ALL_LINK_PATHS "${_MPI_LPATH}")
727    endforeach()
728
729    # We need to remove the flags we extracted from the linker flag list now.
730    string(REGEX REPLACE "(^| )(-Wl,|-Xlinker +)(${CMAKE_LIBRARY_PATH_FLAG},? *(-Wl,|-Xlinker +)?|--library-path=)([^\" ]+|\"[^\"]+\")" ""
731      MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE}")
732
733    # Some MPI implementations pass on options they themselves were built with. Since -z,noexecstack is a common
734    # hardening, we should strip it. In general, the -z options should be undesirable.
735    string(REGEX REPLACE "(^| )-Wl,-z(,[^ ]+| +-Wl,[^ ]+)" "" MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE_FILTERED}")
736    string(REGEX REPLACE "(^| )-Xlinker +-z +-Xlinker +[^ ]+" "" MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE_FILTERED}")
737
738    # We only consider options of the form -Wl or -Xlinker:
739    string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker +)([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE_FILTERED}")
740
741    # As a next step, we assemble the linker flags extracted in a preliminary flags string
742    foreach(_MPI_LINK_FLAG IN LISTS MPI_ALL_LINK_FLAGS)
743      string(STRIP "${_MPI_LINK_FLAG}" _MPI_LINK_FLAG)
744      if (MPI_LINK_FLAGS_WORK)
745        string(APPEND MPI_LINK_FLAGS_WORK " ${_MPI_LINK_FLAG}")
746      else()
747        set(MPI_LINK_FLAGS_WORK "${_MPI_LINK_FLAG}")
748      endif()
749    endforeach()
750  else()
751    # In the filtered case, we obtain the link time flags by just stripping the library paths.
752    string(REGEX REPLACE "(^| )${CMAKE_LIBRARY_PATH_FLAG} *([^\" ]+|\"[^\"]+\")" "" MPI_LINK_CMDLINE_FILTERED "${MPI_LINK_CMDLINE}")
753  endif()
754
755  # If we failed to extract any linker paths, we'll try using the -showme:libdirs option with the MPI compiler.
756  # This will return a list of folders, not a set of flags!
757  if (NOT MPI_ALL_LINK_PATHS)
758    _MPI_check_compiler(${LANG} "-showme:libdirs" MPI_LIBDIRS_CMDLINE MPI_LIBDIRS_COMPILER_RETURN)
759    if(MPI_LIBDIRS_COMPILER_RETURN)
760      separate_arguments(MPI_ALL_LINK_PATHS NATIVE_COMMAND "${MPI_LIBDIRS_CMDLINE}")
761    endif()
762  endif()
763
764  # We need to remove potential quotes and convert the paths to CMake syntax while resolving them, too.
765  foreach(_MPI_LPATH IN LISTS MPI_ALL_LINK_PATHS)
766    string(REPLACE "\"" "" _MPI_LPATH "${_MPI_LPATH}")
767    get_filename_component(_MPI_LPATH "${_MPI_LPATH}" REALPATH)
768    list(APPEND MPI_LINK_DIRECTORIES_WORK "${_MPI_LPATH}")
769  endforeach()
770
771  # Extract the set of libraries to link against from the link command line
772  # This only makes sense if CMAKE_LINK_LIBRARY_FLAG is defined, i.e. a -lxxxx syntax is supported by the compiler.
773  if(CMAKE_LINK_LIBRARY_FLAG)
774    string(REGEX MATCHALL "(^| )${CMAKE_LINK_LIBRARY_FLAG}([^\" ]+|\"[^\"]+\")"
775      MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
776
777    foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES)
778      string(REGEX REPLACE "^ ?${CMAKE_LINK_LIBRARY_FLAG}" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
779      string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
780      list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}")
781    endforeach()
782  endif()
783
784  # Treat linker objects given by full path, for example static libraries, import libraries
785  # or shared libraries if there aren't any import libraries in use on the system.
786  # Note that we do not consider CMAKE_<TYPE>_LIBRARY_PREFIX intentionally here: The linker will for a given file
787  # decide how to link it based on file type, not based on a prefix like 'lib'.
788  set(_MPI_LIB_SUFFIX_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
789  if(DEFINED CMAKE_IMPORT_LIBRARY_SUFFIX)
790    if(NOT ("${CMAKE_IMPORT_LIBRARY_SUFFIX}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}"))
791      string(APPEND _MPI_SUFFIX_REGEX "|${CMAKE_IMPORT_LIBRARY_SUFFIX}")
792    endif()
793  else()
794    string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_SHARED_LIBRARY_SUFFIX}")
795  endif()
796  set(_MPI_LIB_NAME_REGEX "(([^\" ]+(${_MPI_LIB_SUFFIX_REGEX}))|(\"[^\"]+(${_MPI_LIB_SUFFIX_REGEX})\"))( +|$)")
797  string(REPLACE "." "\\." _MPI_LIB_NAME_REGEX "${_MPI_LIB_NAME_REGEX}")
798
799  string(REGEX MATCHALL "${_MPI_LIB_NAME_REGEX}" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
800  foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES)
801    string(REGEX REPLACE "^ +\"?|\"? +$" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
802    get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY)
803    if(NOT "${_MPI_LIB_PATH}" STREQUAL "")
804      list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}")
805    else()
806      list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}")
807    endif()
808  endforeach()
809
810  # Save the explicitly given link directories
811  set(MPI_LINK_DIRECTORIES_LEFTOVER "${MPI_LINK_DIRECTORIES_WORK}")
812
813  # An MPI compiler wrapper could have its MPI libraries in the implicitly
814  # linked directories of the compiler itself.
815  if(DEFINED CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES)
816    list(APPEND MPI_LINK_DIRECTORIES_WORK "${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}")
817  endif()
818
819  # Determine full path names for all of the libraries that one needs
820  # to link against in an MPI program
821  unset(MPI_PLAIN_LIB_NAMES_WORK)
822  foreach(_MPI_LIB_NAME IN LISTS MPI_LIB_NAMES_WORK)
823    get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB_NAME}" NAME_WE)
824    list(APPEND MPI_PLAIN_LIB_NAMES_WORK "${_MPI_PLAIN_LIB_NAME}")
825    find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
826      NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
827      HINTS ${MPI_LINK_DIRECTORIES_WORK}
828      DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
829    )
830    mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
831    # Remove the directory from the remainder list.
832    if(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
833      get_filename_component(_MPI_TAKEN_DIRECTORY "${MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY}" DIRECTORY)
834      list(REMOVE_ITEM MPI_LINK_DIRECTORIES_LEFTOVER "${_MPI_TAKEN_DIRECTORY}")
835    endif()
836  endforeach()
837
838  # Add the link directories given explicitly that we haven't used back as linker directories.
839  if(NOT WIN32)
840    foreach(_MPI_LINK_DIRECTORY IN LISTS MPI_LINK_DIRECTORIES_LEFTOVER)
841      file(TO_NATIVE_PATH "${_MPI_LINK_DIRECTORY}" _MPI_LINK_DIRECTORY_ACTUAL)
842      string(FIND "${_MPI_LINK_DIRECTORY_ACTUAL}" " " _MPI_LINK_DIRECTORY_CONTAINS_SPACE)
843      if(NOT _MPI_LINK_DIRECTORY_CONTAINS_SPACE EQUAL -1)
844        set(_MPI_LINK_DIRECTORY_ACTUAL "\"${_MPI_LINK_DIRECTORY_ACTUAL}\"")
845      endif()
846      if(MPI_LINK_FLAGS_WORK)
847        string(APPEND MPI_LINK_FLAGS_WORK " ${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
848      else()
849        set(MPI_LINK_FLAGS_WORK "${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
850      endif()
851    endforeach()
852  endif()
853
854  # Deal with the libraries given with full path next
855  unset(MPI_DIRECT_LIB_NAMES_WORK)
856  foreach(_MPI_LIB_FULLPATH IN LISTS MPI_LIB_FULLPATHS_WORK)
857    get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB_FULLPATH}" NAME_WE)
858    list(APPEND MPI_DIRECT_LIB_NAMES_WORK "${_MPI_PLAIN_LIB_NAME}")
859    set(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY "${_MPI_LIB_FULLPATH}" CACHE FILEPATH "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI")
860    mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
861  endforeach()
862  # Directly linked objects should be linked first in case some generic linker flags are needed for them.
863  if(MPI_DIRECT_LIB_NAMES_WORK)
864    set(MPI_PLAIN_LIB_NAMES_WORK "${MPI_DIRECT_LIB_NAMES_WORK};${MPI_PLAIN_LIB_NAMES_WORK}")
865  endif()
866
867  # MPI might require pthread to work. The above mechanism wouldn't detect it, but we need to
868  # link it in that case. -lpthread is covered by the normal library treatment on the other hand.
869  if("${MPI_COMPILE_CMDLINE}" MATCHES "-pthread")
870    list(APPEND MPI_COMPILE_OPTIONS_WORK "-pthread")
871    if(MPI_LINK_FLAGS_WORK)
872      string(APPEND MPI_LINK_FLAGS_WORK " -pthread")
873    else()
874      set(MPI_LINK_FLAGS_WORK "-pthread")
875    endif()
876  endif()
877
878  if(MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS)
879    list(APPEND MPI_COMPILE_DEFINITIONS_WORK "${MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS}")
880  endif()
881  if(MPI_${LANG}_EXTRA_COMPILE_OPTIONS)
882    list(APPEND MPI_COMPILE_OPTIONS_WORK "${MPI_${LANG}_EXTRA_COMPILE_OPTIONS}")
883  endif()
884  if(MPI_${LANG}_EXTRA_LIB_NAMES)
885    list(APPEND MPI_PLAIN_LIB_NAMES_WORK "${MPI_${LANG}_EXTRA_LIB_NAMES}")
886  endif()
887
888  # If we found MPI, set up all of the appropriate cache entries
889  if(NOT MPI_${LANG}_COMPILE_OPTIONS)
890    set(MPI_${LANG}_COMPILE_OPTIONS          ${MPI_COMPILE_OPTIONS_WORK}     CACHE STRING "MPI ${LANG} compilation options"            FORCE)
891  endif()
892  if(NOT MPI_${LANG}_COMPILE_DEFINITIONS)
893    set(MPI_${LANG}_COMPILE_DEFINITIONS      ${MPI_COMPILE_DEFINITIONS_WORK} CACHE STRING "MPI ${LANG} compilation definitions"        FORCE)
894  endif()
895  if(NOT MPI_${LANG}_COMPILER_INCLUDE_DIRS)
896    set(MPI_${LANG}_COMPILER_INCLUDE_DIRS    ${MPI_INCLUDE_DIRS_WORK}        CACHE STRING "MPI ${LANG} compiler wrapper include directories" FORCE)
897  endif()
898  if(NOT MPI_${LANG}_LINK_FLAGS)
899    set(MPI_${LANG}_LINK_FLAGS               ${MPI_LINK_FLAGS_WORK}          CACHE STRING "MPI ${LANG} linker flags"                   FORCE)
900  endif()
901  if(NOT MPI_${LANG}_LIB_NAMES)
902    set(MPI_${LANG}_LIB_NAMES                ${MPI_PLAIN_LIB_NAMES_WORK}     CACHE STRING "MPI ${LANG} libraries to link against"      FORCE)
903  endif()
904  set(MPI_${LANG}_WRAPPER_FOUND TRUE PARENT_SCOPE)
905endfunction()
906
907function(_MPI_guess_settings LANG)
908  set(MPI_GUESS_FOUND FALSE)
909  # Currently only MSMPI and MPICH2 on Windows are supported, so we can skip this search if we're not targeting that.
910  if(WIN32)
911    # MSMPI
912
913    # The environment variables MSMPI_INC and MSMPILIB32/64 are the only ways of locating the MSMPI_SDK,
914    # which is installed separately from the runtime. Thus it's possible to have mpiexec but not MPI headers
915    # or import libraries and vice versa.
916    if(NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MSMPI")
917      # We first attempt to locate the msmpi.lib. Should be find it, we'll assume that the MPI present is indeed
918      # Microsoft MPI.
919      if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
920        file(TO_CMAKE_PATH "$ENV{MSMPI_LIB64}" MPI_MSMPI_LIB_PATH)
921        file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x64" MPI_MSMPI_INC_PATH_EXTRA)
922      else()
923        file(TO_CMAKE_PATH "$ENV{MSMPI_LIB32}" MPI_MSMPI_LIB_PATH)
924        file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x86" MPI_MSMPI_INC_PATH_EXTRA)
925      endif()
926
927      find_library(MPI_msmpi_LIBRARY
928        NAMES msmpi
929        HINTS ${MPI_MSMPI_LIB_PATH}
930        DOC "Location of the msmpi library for Microsoft MPI")
931      mark_as_advanced(MPI_msmpi_LIBRARY)
932
933      if(MPI_msmpi_LIBRARY)
934        # Next, we attempt to locate the MPI header. Note that for Fortran we know that mpif.h is a way
935        # MSMPI can be used and therefore that header has to be present.
936        if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
937          get_filename_component(MPI_MSMPI_INC_DIR "$ENV{MSMPI_INC}" REALPATH)
938          set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_MSMPI_INC_DIR}" CACHE STRING "MPI ${LANG} additional include directories" FORCE)
939          unset(MPI_MSMPI_INC_DIR)
940        endif()
941
942        # For MSMPI, one can compile the MPI module by building the mpi.f90 shipped with the MSMPI SDK,
943        # thus it might be present or provided by the user. Figuring out which is supported is done later on.
944        # The PGI Fortran compiler for instance ships a prebuilt set of modules in its own include folder.
945        # Should a user be employing PGI or have built its own set and provided it via cache variables, the
946        # splitting routine would have located the module files.
947
948        # For C and C++, we're done here (MSMPI does not ship the MPI-2 C++ bindings) - however, for Fortran
949        # we need some extra library to glue Fortran support together:
950        # MSMPI ships 2-4 Fortran libraries, each for different Fortran compiler behaviors. The library names
951        # ending with a c are using the cdecl calling convention, whereas those ending with an s are for Fortran
952        # implementations using stdcall. Therefore, the 64-bit MSMPI only ships those ending in 'c', whereas the 32-bit
953        # has both variants available.
954        # The second difference is the last but one letter, if it's an e(nd), the length of a string argument is
955        # passed by the Fortran compiler after all other arguments on the parameter list, if it's an m(ixed),
956        # it's passed immediately after the string address.
957
958        # To summarize:
959        #   - msmpifec: CHARACTER length passed after the parameter list and using cdecl calling convention
960        #   - msmpifmc: CHARACTER length passed directly after string address and using cdecl calling convention
961        #   - msmpifes: CHARACTER length passed after the parameter list and using stdcall calling convention
962        #   - msmpifms: CHARACTER length passed directly after string address and using stdcall calling convention
963        # 32-bit MSMPI ships all four libraries, 64-bit MSMPI ships only the first two.
964
965        # As is, Intel Fortran and PGI Fortran both use the 'ec' variant of the calling convention, whereas
966        # the old Compaq Visual Fortran compiler defaulted to the 'ms' version. It's possible to make Intel Fortran
967        # use the CVF calling convention using /iface:cvf, but we assume - and this is also assumed in FortranCInterface -
968        # this isn't the case. It's also possible to make CVF use the 'ec' variant, using /iface=(cref,nomixed_str_len_arg).
969
970        # Our strategy is now to locate all libraries, but enter msmpifec into the LIB_NAMES array.
971        # Should this not be adequate it's a straightforward way for a user to change the LIB_NAMES array and
972        # have his library found. Still, this should not be necessary outside of exceptional cases, as reasoned.
973        if ("${LANG}" STREQUAL "Fortran")
974          set(MPI_MSMPI_CALLINGCONVS c)
975          if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
976            list(APPEND MPI_MSMPI_CALLINGCONVS s)
977          endif()
978          foreach(mpistrlenpos IN ITEMS e m)
979            foreach(mpicallingconv IN LISTS MPI_MSMPI_CALLINGCONVS)
980              find_library(MPI_msmpif${mpistrlenpos}${mpicallingconv}_LIBRARY
981                NAMES msmpif${mpistrlenpos}${mpicallingconv}
982                HINTS "${MPI_MSMPI_LIB_PATH}"
983                DOC "Location of the msmpi${mpistrlenpos}${mpicallingconv} library for Microsoft MPI")
984              mark_as_advanced(MPI_msmpif${mpistrlenpos}${mpicallingconv}_LIBRARY)
985            endforeach()
986          endforeach()
987          if(NOT MPI_${LANG}_LIB_NAMES)
988            set(MPI_${LANG}_LIB_NAMES "msmpi;msmpifec" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
989          endif()
990
991          # At this point we're *not* done. MSMPI requires an additional include file for Fortran giving the value
992          # of MPI_AINT. This file is called mpifptr.h located in the x64 and x86 subfolders, respectively.
993          find_path(MPI_mpifptr_INCLUDE_DIR
994            NAMES "mpifptr.h"
995            HINTS "${MPI_MSMPI_INC_PATH_EXTRA}"
996            DOC "Location of the mpifptr.h extra header for Microsoft MPI")
997          if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
998            set(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS "mpifptr" CACHE STRING "MPI ${LANG} additional include directory variables, given in the form MPI_<name>_INCLUDE_DIR." FORCE)
999          endif()
1000          mark_as_advanced(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS MPI_mpifptr_INCLUDE_DIR)
1001        else()
1002          if(NOT MPI_${LANG}_LIB_NAMES)
1003            set(MPI_${LANG}_LIB_NAMES "msmpi" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
1004          endif()
1005        endif()
1006        mark_as_advanced(MPI_${LANG}_LIB_NAMES)
1007        set(MPI_GUESS_FOUND TRUE)
1008
1009        if(_MPIEXEC_NOT_GIVEN)
1010          unset(MPIEXEC_EXECUTABLE CACHE)
1011        endif()
1012
1013        find_program(MPIEXEC_EXECUTABLE
1014          NAMES mpiexec
1015          HINTS $ENV{MSMPI_BIN} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin"
1016          DOC "Executable for running MPI programs.")
1017      endif()
1018    endif()
1019
1020    # At this point there's not many MPIs that we could still consider.
1021    # OpenMPI 1.6.x and below supported Windows, but these ship compiler wrappers that still work.
1022    # The only other relevant MPI implementation without a wrapper is MPICH2, which had Windows support in 1.4.1p1 and older.
1023    if(NOT MPI_GUESS_FOUND AND (NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MPICH2"))
1024      set(MPI_MPICH_PREFIX_PATHS
1025        "$ENV{ProgramW6432}/MPICH2/lib"
1026        "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/../lib"
1027        "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]/lib"
1028      )
1029
1030      # All of C, C++ and Fortran will need mpi.lib, so we'll look for this first
1031      find_library(MPI_mpi_LIBRARY
1032        NAMES mpi
1033        HINTS ${MPI_MPICH_PREFIX_PATHS})
1034      mark_as_advanced(MPI_mpi_LIBRARY)
1035      # If we found mpi.lib, we detect the rest of MPICH2
1036      if(MPI_mpi_LIBRARY)
1037        set(MPI_MPICH_LIB_NAMES "mpi")
1038        # If MPI-2 C++ bindings are requested, we need to locate cxx.lib as well.
1039        # Otherwise, MPICH_SKIP_MPICXX will be defined and these bindings aren't needed.
1040        if("${LANG}" STREQUAL "CXX" AND NOT MPI_CXX_SKIP_MPICXX)
1041          find_library(MPI_cxx_LIBRARY
1042            NAMES cxx
1043            HINTS ${MPI_MPICH_PREFIX_PATHS})
1044          mark_as_advanced(MPI_cxx_LIBRARY)
1045          list(APPEND MPI_MPICH_LIB_NAMES "cxx")
1046        # For Fortran, MPICH2 provides three different libraries:
1047        #   fmpich2.lib which uses uppercase symbols and cdecl,
1048        #   fmpich2s.lib which uses uppercase symbols and stdcall (32-bit only),
1049        #   fmpich2g.lib which uses lowercase symbols with double underscores and cdecl.
1050        # fmpich2s.lib would be useful for Compaq Visual Fortran, fmpich2g.lib has to be used with GNU g77 and is also
1051        # provided in the form of an .a archive for MinGW and Cygwin. From our perspective, fmpich2.lib is the only one
1052        # we need to try, and if it doesn't work with the given Fortran compiler we'd find out later on during validation
1053        elseif("${LANG}" STREQUAL "Fortran")
1054          find_library(MPI_fmpich2_LIBRARY
1055            NAMES fmpich2
1056            HINTS ${MPI_MPICH_PREFIX_PATHS})
1057          find_library(MPI_fmpich2s_LIBRARY
1058            NAMES fmpich2s
1059            HINTS ${MPI_MPICH_PREFIX_PATHS})
1060          find_library(MPI_fmpich2g_LIBRARY
1061            NAMES fmpich2g
1062            HINTS ${MPI_MPICH_PREFIX_PATHS})
1063          mark_as_advanced(MPI_fmpich2_LIBRARY MPI_fmpich2s_LIBRARY MPI_fmpich2g_LIBRARY)
1064          list(APPEND MPI_MPICH_LIB_NAMES "fmpich2")
1065        endif()
1066
1067        if(NOT MPI_${LANG}_LIB_NAMES)
1068          set(MPI_${LANG}_LIB_NAMES "${MPI_MPICH_LIB_NAMES}" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
1069        endif()
1070        unset(MPI_MPICH_LIB_NAMES)
1071
1072        if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1073          # For MPICH2, the include folder would be in ../include relative to the library folder.
1074          get_filename_component(MPI_MPICH_ROOT_DIR "${MPI_mpi_LIBRARY}" DIRECTORY)
1075          get_filename_component(MPI_MPICH_ROOT_DIR "${MPI_MPICH_ROOT_DIR}" DIRECTORY)
1076          if(IS_DIRECTORY "${MPI_MPICH_ROOT_DIR}/include")
1077            set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_MPICH_ROOT_DIR}/include" CACHE STRING "MPI ${LANG} additional include directory variables, given in the form MPI_<name>_INCLUDE_DIR." FORCE)
1078          endif()
1079          unset(MPI_MPICH_ROOT_DIR)
1080        endif()
1081        set(MPI_GUESS_FOUND TRUE)
1082
1083        if(_MPIEXEC_NOT_GIVEN)
1084          unset(MPIEXEC_EXECUTABLE CACHE)
1085        endif()
1086
1087        find_program(MPIEXEC_EXECUTABLE
1088          NAMES ${_MPIEXEC_NAMES}
1089          HINTS "$ENV{ProgramW6432}/MPICH2/bin"
1090                "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]"
1091                "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]/bin"
1092          DOC "Executable for running MPI programs.")
1093      endif()
1094      unset(MPI_MPICH_PREFIX_PATHS)
1095    endif()
1096  endif()
1097  set(MPI_${LANG}_GUESS_FOUND "${MPI_GUESS_FOUND}" PARENT_SCOPE)
1098endfunction()
1099
1100function(_MPI_adjust_compile_definitions LANG)
1101  if("${LANG}" STREQUAL "CXX")
1102    # To disable the C++ bindings, we need to pass some definitions since the mpi.h header has to deal with both C and C++
1103    # bindings in MPI-2.
1104    if(MPI_CXX_SKIP_MPICXX AND NOT MPI_${LANG}_COMPILE_DEFINITIONS MATCHES "SKIP_MPICXX")
1105      # MPICH_SKIP_MPICXX is being used in MPICH and derivatives like MVAPICH or Intel MPI
1106      # OMPI_SKIP_MPICXX is being used in Open MPI
1107      # _MPICC_H is being used for IBM Platform MPI
1108      list(APPEND MPI_${LANG}_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX" "OMPI_SKIP_MPICXX" "_MPICC_H")
1109      set(MPI_${LANG}_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}" CACHE STRING "MPI ${LANG} compilation definitions" FORCE)
1110    endif()
1111  endif()
1112endfunction()
1113
1114macro(_MPI_assemble_libraries LANG)
1115  set(MPI_${LANG}_LIBRARIES "")
1116  # Only for libraries do we need to check whether the compiler's linking stage is separate.
1117  if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}" OR NOT MPI_${LANG}_WORKS_IMPLICIT)
1118    foreach(mpilib IN LISTS MPI_${LANG}_LIB_NAMES)
1119      list(APPEND MPI_${LANG}_LIBRARIES ${MPI_${mpilib}_LIBRARY})
1120    endforeach()
1121  endif()
1122endmacro()
1123
1124macro(_MPI_assemble_include_dirs LANG)
1125  set(MPI_${LANG}_INCLUDE_DIRS
1126    ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1127    ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1128    )
1129  if("${LANG}" MATCHES "(C|CXX)")
1130    if(MPI_${LANG}_HEADER_DIR)
1131      list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
1132    endif()
1133  else() # Fortran
1134    if(MPI_${LANG}_F77_HEADER_DIR)
1135      list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_F77_HEADER_DIR}")
1136    endif()
1137    if(MPI_${LANG}_MODULE_DIR)
1138      list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_MODULE_DIR}")
1139    endif()
1140  endif()
1141  if(MPI_${LANG}_INCLUDE_DIRS)
1142    list(REMOVE_DUPLICATES MPI_${LANG}_INCLUDE_DIRS)
1143  endif()
1144endmacro()
1145
1146macro(_MPI_split_include_dirs LANG)
1147  # Backwards compatibility: Search INCLUDE_PATH if given.
1148  if(MPI_${LANG}_INCLUDE_PATH)
1149    list(APPEND MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_INCLUDE_PATH}")
1150  endif()
1151
1152  # We try to find the headers/modules among those paths (and system paths)
1153  # For C/C++, we just need to have a look for mpi.h.
1154  if("${LANG}" MATCHES "(C|CXX)")
1155    find_path(MPI_${LANG}_HEADER_DIR "mpi.h"
1156      HINTS
1157        ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1158        ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1159    )
1160    mark_as_advanced(MPI_${LANG}_HEADER_DIR)
1161    if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1162      list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
1163    endif()
1164
1165  # Fortran is more complicated here: An implementation could provide
1166  # any of the Fortran 77/90/2008 APIs for MPI. For example, MSMPI
1167  # only provides Fortran 77 and - if mpi.f90 is built - potentially
1168  # a Fortran 90 module.
1169  elseif("${LANG}" STREQUAL "Fortran")
1170    find_path(MPI_${LANG}_F77_HEADER_DIR "mpif.h"
1171      HINTS
1172        ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1173        ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1174    )
1175    find_path(MPI_${LANG}_MODULE_DIR
1176      NAMES "mpi.mod" "mpi_f08.mod"
1177      HINTS
1178        ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1179        ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1180    )
1181    if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1182      list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS
1183        "${MPI_${LANG}_F77_HEADER_DIR}"
1184        "${MPI_${LANG}_MODULE_DIR}"
1185      )
1186    endif()
1187    mark_as_advanced(MPI_${LANG}_F77_HEADER_DIR MPI_${LANG}_MODULE_DIR)
1188  endif()
1189
1190  # Remove duplicates and default system directories from the list.
1191  if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1192    list(REMOVE_DUPLICATES MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1193    foreach(MPI_IMPLICIT_INC_DIR IN LISTS CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES)
1194      list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_IMPLICIT_INC_DIR})
1195    endforeach()
1196  endif()
1197
1198  set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories" FORCE)
1199endmacro()
1200
1201macro(_MPI_create_imported_target LANG)
1202  if(NOT TARGET MPI::MPI_${LANG})
1203    add_library(MPI::MPI_${LANG} INTERFACE IMPORTED)
1204  endif()
1205
1206  # When this is consumed for compiling CUDA, use '-Xcompiler' to wrap '-pthread' and '-fexceptions'.
1207  string(REPLACE "-pthread" "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler >-pthread"
1208    _MPI_${LANG}_COMPILE_OPTIONS "${MPI_${LANG}_COMPILE_OPTIONS}")
1209  string(REPLACE "-fexceptions" "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler >-fexceptions"
1210    _MPI_${LANG}_COMPILE_OPTIONS "${_MPI_${LANG}_COMPILE_OPTIONS}")
1211  set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${_MPI_${LANG}_COMPILE_OPTIONS}")
1212  unset(_MPI_${LANG}_COMPILE_OPTIONS)
1213
1214  set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}")
1215
1216  if(MPI_${LANG}_LINK_FLAGS)
1217    string(REPLACE "," "$<COMMA>" _MPI_${LANG}_LINK_FLAGS "${MPI_${LANG}_LINK_FLAGS}")
1218    string(PREPEND _MPI_${LANG}_LINK_FLAGS "$<HOST_LINK:SHELL:")
1219    string(APPEND _MPI_${LANG}_LINK_FLAGS ">")
1220    set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_OPTIONS "${_MPI_${LANG}_LINK_FLAGS}")
1221  endif()
1222  # If the compiler links MPI implicitly, no libraries will be found as they're contained within
1223  # CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES already.
1224  if(MPI_${LANG}_LIBRARIES)
1225    set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_LIBRARIES "${MPI_${LANG}_LIBRARIES}")
1226  endif()
1227  # Given the new design of FindMPI, INCLUDE_DIRS will always be located, even under implicit linking.
1228  set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MPI_${LANG}_INCLUDE_DIRS}")
1229endmacro()
1230
1231function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY SUPPRESS_ERRORS)
1232  set(WORK_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI")
1233  set(SRC_DIR "${CMAKE_ROOT}/Modules/FindMPI")
1234  set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI/${MPI_TEST_FILE_NAME}_${LANG}.bin")
1235  unset(MPI_TEST_COMPILE_DEFINITIONS)
1236  if("${LANG}" STREQUAL "Fortran")
1237    if("${MODE}" STREQUAL "F90_MODULE")
1238      set(MPI_Fortran_INCLUDE_LINE "use mpi\n      implicit none")
1239    elseif("${MODE}" STREQUAL "F08_MODULE")
1240      set(MPI_Fortran_INCLUDE_LINE "use mpi_f08\n      implicit none")
1241    else() # F77 header
1242      set(MPI_Fortran_INCLUDE_LINE "implicit none\n      include 'mpif.h'")
1243    endif()
1244    configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.f90.in" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90" @ONLY)
1245    set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90")
1246  elseif("${LANG}" STREQUAL "CXX")
1247    configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.c" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp" COPYONLY)
1248    set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp")
1249    if("${MODE}" STREQUAL "TEST_MPICXX")
1250      set(MPI_TEST_COMPILE_DEFINITIONS TEST_MPI_MPICXX)
1251    endif()
1252  else() # C
1253    set(MPI_TEST_SOURCE_FILE "${SRC_DIR}/${MPI_TEST_FILE_NAME}.c")
1254  endif()
1255  if(RUN_BINARY)
1256    try_run(MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
1257     "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
1258      COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
1259      LINK_LIBRARIES MPI::MPI_${LANG}
1260      RUN_OUTPUT_VARIABLE MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
1261      COMPILE_OUTPUT_VARIABLE _MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT)
1262    set(MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} "${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}" PARENT_SCOPE)
1263  else()
1264    try_compile(MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
1265      "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
1266      COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
1267      LINK_LIBRARIES MPI::MPI_${LANG}
1268      COPY_FILE "${BIN_FILE}"
1269      OUTPUT_VARIABLE _MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT)
1270  endif()
1271  if(NOT SUPPRESS_ERRORS)
1272    if(NOT MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
1273      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
1274          "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE} failed to compile with the following output:\n${_MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT}\n\n")
1275    elseif(DEFINED MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} AND MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
1276        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
1277          "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE} failed to run with the following output:\n${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}\n\n")
1278    endif()
1279  endif()
1280endfunction()
1281
1282macro(_MPI_check_lang_works LANG SUPPRESS_ERRORS)
1283  # For Fortran we may have by the MPI-3 standard an implementation that provides:
1284  #   - the mpi_f08 module
1285  #   - *both*, the mpi module and 'mpif.h'
1286  # Since older MPI standards (MPI-1) did not define anything but 'mpif.h', we need to check all three individually.
1287  if( NOT MPI_${LANG}_WORKS )
1288    if("${LANG}" STREQUAL "Fortran")
1289      set(MPI_Fortran_INTEGER_LINE "(kind=MPI_INTEGER_KIND)")
1290      _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER FALSE ${SUPPRESS_ERRORS})
1291      _MPI_try_staged_settings(${LANG} test_mpi F90_MODULE FALSE ${SUPPRESS_ERRORS})
1292      _MPI_try_staged_settings(${LANG} test_mpi F08_MODULE FALSE ${SUPPRESS_ERRORS})
1293
1294      set(MPI_${LANG}_WORKS FALSE)
1295
1296      foreach(mpimethod IN ITEMS F77_HEADER F08_MODULE F90_MODULE)
1297        if(MPI_RESULT_${LANG}_test_mpi_${mpimethod})
1298          set(MPI_${LANG}_WORKS TRUE)
1299          set(MPI_${LANG}_HAVE_${mpimethod} TRUE)
1300        else()
1301          set(MPI_${LANG}_HAVE_${mpimethod} FALSE)
1302        endif()
1303      endforeach()
1304      # MPI-1 versions had no MPI_INTGER_KIND defined, so we need to try without it.
1305      # However, MPI-1 also did not define the Fortran 90 and 08 modules, so we only try the F77 header.
1306      unset(MPI_Fortran_INTEGER_LINE)
1307      if(NOT MPI_${LANG}_WORKS)
1308        _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER_NOKIND FALSE ${SUPPRESS_ERRORS})
1309        if(MPI_RESULT_${LANG}_test_mpi_F77_HEADER_NOKIND)
1310          set(MPI_${LANG}_WORKS TRUE)
1311          set(MPI_${LANG}_HAVE_F77_HEADER TRUE)
1312        endif()
1313      endif()
1314    else()
1315      _MPI_try_staged_settings(${LANG} test_mpi normal FALSE ${SUPPRESS_ERRORS})
1316      # If 'test_mpi' built correctly, we've found valid MPI settings. There might not be MPI-2 C++ support, but there can't
1317      # be MPI-2 C++ support without the C bindings being present, so checking for them is sufficient.
1318      set(MPI_${LANG}_WORKS "${MPI_RESULT_${LANG}_test_mpi_normal}")
1319    endif()
1320  endif()
1321endmacro()
1322
1323# Some systems install various MPI implementations in separate folders in some MPI prefix
1324# This macro enumerates all such subfolders and adds them to the list of hints that will be searched.
1325macro(MPI_search_mpi_prefix_folder PREFIX_FOLDER)
1326  if(EXISTS "${PREFIX_FOLDER}")
1327    file(GLOB _MPI_folder_children RELATIVE "${PREFIX_FOLDER}" "${PREFIX_FOLDER}/*")
1328    foreach(_MPI_folder_child IN LISTS _MPI_folder_children)
1329      if(IS_DIRECTORY "${PREFIX_FOLDER}/${_MPI_folder_child}")
1330        list(APPEND MPI_HINT_DIRS "${PREFIX_FOLDER}/${_MPI_folder_child}")
1331      endif()
1332    endforeach()
1333  endif()
1334endmacro()
1335
1336set(MPI_HINT_DIRS ${MPI_HOME} $ENV{MPI_HOME} $ENV{I_MPI_ROOT})
1337if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux")
1338  # SUSE Linux Enterprise Server stores its MPI implementations under /usr/lib64/mpi/gcc/<name>
1339  # We enumerate the subfolders and append each as a prefix
1340  MPI_search_mpi_prefix_folder("/usr/lib64/mpi/gcc")
1341elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "FreeBSD")
1342  # FreeBSD ships mpich under the normal system paths - but available openmpi implementations
1343  # will be found in /usr/local/mpi/<name>
1344  MPI_search_mpi_prefix_folder("/usr/local/mpi")
1345endif()
1346
1347# Most MPI distributions have some form of mpiexec or mpirun which gives us something we can look for.
1348# The MPI standard does not mandate the existence of either, but instead only makes requirements if a distribution
1349# ships an mpiexec program (mpirun executables are not regulated by the standard).
1350
1351# We defer searching for mpiexec binaries belonging to guesses until later. By doing so, mismatches between mpiexec
1352# and the MPI we found should be reduced.
1353if(NOT MPIEXEC_EXECUTABLE)
1354  set(_MPIEXEC_NOT_GIVEN TRUE)
1355else()
1356  set(_MPIEXEC_NOT_GIVEN FALSE)
1357endif()
1358
1359find_program(MPIEXEC_EXECUTABLE
1360  NAMES ${_MPIEXEC_NAMES}
1361  PATH_SUFFIXES bin sbin
1362  HINTS ${MPI_HINT_DIRS}
1363  DOC "Executable for running MPI programs.")
1364
1365# call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin).
1366# This gives us a fairly reliable base directory to search for /bin /lib and /include from.
1367get_filename_component(_MPI_BASE_DIR "${MPIEXEC_EXECUTABLE}" PATH)
1368get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH)
1369
1370# According to the MPI standard, section 8.8 -n is a guaranteed, and the only guaranteed way to
1371# launch an MPI process using mpiexec if such a program exists.
1372set(MPIEXEC_NUMPROC_FLAG "-n"  CACHE STRING "Flag used by MPI to specify the number of processes for mpiexec; the next option will be the number of processes.")
1373set(MPIEXEC_PREFLAGS     ""    CACHE STRING "These flags will be directly before the executable that is being run by mpiexec.")
1374set(MPIEXEC_POSTFLAGS    ""    CACHE STRING "These flags will be placed after all flags passed to mpiexec.")
1375
1376# Set the number of processes to the physical processor count
1377cmake_host_system_information(RESULT _MPIEXEC_NUMPROCS QUERY NUMBER_OF_PHYSICAL_CORES)
1378set(MPIEXEC_MAX_NUMPROCS "${_MPIEXEC_NUMPROCS}" CACHE STRING "Maximum number of processors available to run MPI applications.")
1379unset(_MPIEXEC_NUMPROCS)
1380mark_as_advanced(MPIEXEC_EXECUTABLE MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS)
1381
1382#=============================================================================
1383# Backward compatibility input hacks.  Propagate the FindMPI hints to C and
1384# CXX if the respective new versions are not defined.  Translate the old
1385# MPI_LIBRARY and MPI_EXTRA_LIBRARY to respective MPI_${LANG}_LIBRARIES.
1386#
1387# Once we find the new variables, we translate them back into their old
1388# equivalents below.
1389if(NOT MPI_IGNORE_LEGACY_VARIABLES)
1390  foreach (LANG IN ITEMS C CXX)
1391    # Old input variables.
1392    set(_MPI_OLD_INPUT_VARS COMPILER COMPILE_FLAGS INCLUDE_PATH LINK_FLAGS)
1393
1394    # Set new vars based on their old equivalents, if the new versions are not already set.
1395    foreach (var ${_MPI_OLD_INPUT_VARS})
1396      if (NOT MPI_${LANG}_${var} AND MPI_${var})
1397        set(MPI_${LANG}_${var} "${MPI_${var}}")
1398      endif()
1399    endforeach()
1400
1401    # Chop the old compile flags into options and definitions
1402
1403    unset(MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS)
1404    unset(MPI_${LANG}_EXTRA_COMPILE_OPTIONS)
1405    if(MPI_${LANG}_COMPILE_FLAGS)
1406      separate_arguments(MPI_SEPARATE_FLAGS NATIVE_COMMAND "${MPI_${LANG}_COMPILE_FLAGS}")
1407      foreach(_MPI_FLAG IN LISTS MPI_SEPARATE_FLAGS)
1408        if("${_MPI_FLAG}" MATCHES "^ *-D([^ ]+)")
1409          list(APPEND MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS "${CMAKE_MATCH_1}")
1410        else()
1411          list(APPEND MPI_${LANG}_EXTRA_COMPILE_OPTIONS "${_MPI_FLAG}")
1412        endif()
1413      endforeach()
1414      unset(MPI_SEPARATE_FLAGS)
1415    endif()
1416
1417    # If a list of libraries was given, we'll split it into new-style cache variables
1418    unset(MPI_${LANG}_EXTRA_LIB_NAMES)
1419    if(NOT MPI_${LANG}_LIB_NAMES)
1420      foreach(_MPI_LIB IN LISTS MPI_${LANG}_LIBRARIES MPI_LIBRARY MPI_EXTRA_LIBRARY)
1421        if(_MPI_LIB)
1422          get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB}" NAME_WE)
1423          get_filename_component(_MPI_LIB_NAME "${_MPI_LIB}" NAME)
1424          get_filename_component(_MPI_LIB_DIR "${_MPI_LIB}" DIRECTORY)
1425          list(APPEND MPI_${LANG}_EXTRA_LIB_NAMES "${_MPI_PLAIN_LIB_NAME}")
1426          find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
1427            NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
1428            HINTS ${_MPI_LIB_DIR} $ENV{MPI_LIB}
1429            DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
1430          )
1431          mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
1432        endif()
1433      endforeach()
1434    endif()
1435  endforeach()
1436endif()
1437#=============================================================================
1438
1439unset(MPI_VERSION)
1440unset(MPI_VERSION_MAJOR)
1441unset(MPI_VERSION_MINOR)
1442
1443unset(_MPI_MIN_VERSION)
1444
1445# If the user specified a library name we assume they prefer that library over a wrapper. If not, they can disable skipping manually.
1446if(NOT DEFINED MPI_SKIP_COMPILER_WRAPPER AND MPI_GUESS_LIBRARY_NAME)
1447  set(MPI_SKIP_COMPILER_WRAPPER TRUE)
1448endif()
1449
1450# This loop finds the compilers and sends them off for interrogation.
1451foreach(LANG IN ITEMS C CXX Fortran)
1452  if(CMAKE_${LANG}_COMPILER_LOADED)
1453    if(NOT MPI_FIND_COMPONENTS)
1454      set(_MPI_FIND_${LANG} TRUE)
1455    elseif( ${LANG} IN_LIST MPI_FIND_COMPONENTS)
1456      set(_MPI_FIND_${LANG} TRUE)
1457    elseif( ${LANG} STREQUAL CXX AND NOT MPI_CXX_SKIP_MPICXX AND MPICXX IN_LIST MPI_FIND_COMPONENTS )
1458      set(_MPI_FIND_${LANG} TRUE)
1459    else()
1460      set(_MPI_FIND_${LANG} FALSE)
1461    endif()
1462  else()
1463    set(_MPI_FIND_${LANG} FALSE)
1464    if(${LANG} IN_LIST MPI_FIND_COMPONENTS)
1465      string(APPEND _MPI_FAIL_REASON "MPI component '${LANG}' was requested, but language ${LANG} is not enabled.  ")
1466    endif()
1467  endif()
1468  if(_MPI_FIND_${LANG})
1469    if( ${LANG} STREQUAL CXX AND NOT MPICXX IN_LIST MPI_FIND_COMPONENTS )
1470      option(MPI_CXX_SKIP_MPICXX "If true, the MPI-2 C++ bindings are disabled using definitions." FALSE)
1471      mark_as_advanced(MPI_CXX_SKIP_MPICXX)
1472    endif()
1473    _MPI_adjust_compile_definitions(${LANG})
1474    if(NOT (MPI_${LANG}_LIB_NAMES AND (MPI_${LANG}_INCLUDE_PATH OR MPI_${LANG}_INCLUDE_DIRS OR MPI_${LANG}_COMPILER_INCLUDE_DIRS)))
1475      set(MPI_${LANG}_TRIED_IMPLICIT FALSE)
1476      set(MPI_${LANG}_WORKS_IMPLICIT FALSE)
1477      if(NOT MPI_${LANG}_COMPILER AND NOT MPI_ASSUME_NO_BUILTIN_MPI)
1478        # Should the imported targets be empty, we effectively try whether the compiler supports MPI on its own, which is the case on e.g.
1479        # Cray PrgEnv.
1480        _MPI_create_imported_target(${LANG})
1481        _MPI_check_lang_works(${LANG} TRUE)
1482
1483        # If the compiler can build MPI code on its own, it functions as an MPI compiler and we'll set the variable to point to it.
1484        if(MPI_${LANG}_WORKS)
1485          set(MPI_${LANG}_COMPILER "${CMAKE_${LANG}_COMPILER}" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE)
1486          set(MPI_${LANG}_WORKS_IMPLICIT TRUE)
1487        endif()
1488        set(MPI_${LANG}_TRIED_IMPLICIT TRUE)
1489      endif()
1490
1491      if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}" OR NOT MPI_${LANG}_WORKS)
1492        set(MPI_${LANG}_WRAPPER_FOUND FALSE)
1493        set(MPI_PINNED_COMPILER FALSE)
1494
1495        if(NOT MPI_SKIP_COMPILER_WRAPPER)
1496          if(MPI_${LANG}_COMPILER)
1497            # If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
1498            if (NOT IS_ABSOLUTE "${MPI_${LANG}_COMPILER}")
1499              # Get rid of our default list of names and just search for the name the user wants.
1500              set(_MPI_${LANG}_COMPILER_NAMES "${MPI_${LANG}_COMPILER}")
1501              unset(MPI_${LANG}_COMPILER CACHE)
1502            endif()
1503            # If the user specifies a compiler, we don't want to try to search libraries either.
1504            set(MPI_PINNED_COMPILER TRUE)
1505          endif()
1506
1507          # If we have an MPI base directory, we'll try all compiler names in that one first.
1508          # This should prevent mixing different MPI environments
1509          if(_MPI_BASE_DIR)
1510            find_program(MPI_${LANG}_COMPILER
1511              NAMES  ${_MPI_${LANG}_COMPILER_NAMES}
1512              PATH_SUFFIXES bin sbin
1513              HINTS  ${_MPI_BASE_DIR}
1514              NO_DEFAULT_PATH
1515              DOC    "MPI compiler for ${LANG}"
1516            )
1517          endif()
1518
1519          # If the base directory did not help (for example because the mpiexec isn't in the same directory as the compilers),
1520          # we shall try searching in the default paths.
1521          find_program(MPI_${LANG}_COMPILER
1522            NAMES  ${_MPI_${LANG}_COMPILER_NAMES}
1523            PATH_SUFFIXES bin sbin
1524            DOC    "MPI compiler for ${LANG}"
1525          )
1526
1527          if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
1528            set(MPI_PINNED_COMPILER TRUE)
1529
1530            # If we haven't made the implicit compiler test yet, perform it now.
1531            if(NOT MPI_${LANG}_TRIED_IMPLICIT)
1532              _MPI_create_imported_target(${LANG})
1533              _MPI_check_lang_works(${LANG} TRUE)
1534            endif()
1535
1536            # Should the MPI compiler not work implicitly for MPI, still interrogate it.
1537            # Otherwise, MPI compilers for which CMake has separate linking stages, e.g. Intel MPI on Windows where link.exe is being used
1538            # directly during linkage instead of CMAKE_<LANG>_COMPILER will not work.
1539            if(NOT MPI_${LANG}_WORKS)
1540              set(MPI_${LANG}_WORKS_IMPLICIT FALSE)
1541              _MPI_interrogate_compiler(${LANG})
1542            else()
1543              set(MPI_${LANG}_WORKS_IMPLICIT TRUE)
1544            endif()
1545          elseif(MPI_${LANG}_COMPILER)
1546            _MPI_interrogate_compiler(${LANG})
1547          endif()
1548        endif()
1549
1550        # We are on a Cray, environment identfier: PE_ENV is set (CRAY), and
1551        # have NOT found an mpic++-like compiler wrapper (previous block),
1552        # and we do NOT use the Cray cc/CC compiler wrappers as CC/CXX CMake
1553        # compiler.
1554        # So as a last resort, we now interrogate cc/CC/ftn for MPI flags.
1555        if(DEFINED ENV{PE_ENV} AND NOT "${MPI_${LANG}_COMPILER}")
1556          set(MPI_PINNED_COMPILER TRUE)
1557          find_program(MPI_${LANG}_COMPILER
1558            NAMES  ${_MPI_Cray_${LANG}_COMPILER_NAMES}
1559            PATH_SUFFIXES bin sbin
1560            DOC    "MPI compiler for ${LANG}"
1561          )
1562
1563          # If we haven't made the implicit compiler test yet, perform it now.
1564          if(NOT MPI_${LANG}_TRIED_IMPLICIT)
1565            _MPI_create_imported_target(${LANG})
1566            _MPI_check_lang_works(${LANG} TRUE)
1567          endif()
1568
1569          set(MPI_${LANG}_WORKS_IMPLICIT TRUE)
1570          _MPI_interrogate_compiler(${LANG})
1571        endif()
1572
1573        if(NOT MPI_PINNED_COMPILER AND NOT MPI_${LANG}_WRAPPER_FOUND)
1574          # If MPI_PINNED_COMPILER wasn't given, and the MPI compiler we potentially found didn't work, we withdraw it.
1575          set(MPI_${LANG}_COMPILER "MPI_${LANG}_COMPILER-NOTFOUND" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE)
1576
1577          if(LANG STREQUAL "C")
1578            set(_MPI_PKG "mpi-c")
1579          elseif(LANG STREQUAL "CXX")
1580            set(_MPI_PKG "mpi-cxx")
1581          elseif(LANG STREQUAL "Fortran")
1582            set(_MPI_PKG "mpi-fort")
1583          else()
1584            set(_MPI_PKG "")
1585          endif()
1586          if(_MPI_PKG AND PKG_CONFIG_FOUND)
1587            pkg_check_modules("MPI_${LANG}_PKG" "${_MPI_PKG}")
1588            if("${MPI_${LANG}_PKG_FOUND}")
1589              set(MPI_${LANG}_COMPILE_OPTIONS  ${MPI_${LANG}_PKG_CFLAGS}        CACHE STRING "MPI ${LANG} compilation options"       FORCE)
1590              set(MPI_${LANG}_INCLUDE_PATH     ${MPI_${LANG}_PKG_INCLUDE_DIRS}  CACHE STRING "MPI ${LANG} include directories"       FORCE)
1591              set(MPI_${LANG}_LINK_FLAGS       ${MPI_${LANG}_PKG_LDFLAGS}       CACHE STRING "MPI ${LANG} linker flags"              FORCE)
1592              set(MPI_${LANG}_LIB_NAMES        ${MPI_${LANG}_PKG_LIBRARIES}     CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
1593              foreach(_MPI_LIB IN LISTS MPI_${LANG}_LIB_NAMES)
1594                if(_MPI_LIB)
1595                  get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB}" NAME_WE)
1596                  get_filename_component(_MPI_LIB_NAME "${_MPI_LIB}" NAME)
1597                  get_filename_component(_MPI_LIB_DIR "${_MPI_LIB}" DIRECTORY)
1598                  find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
1599                    NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
1600                    HINTS ${_MPI_LIB_DIR}
1601                    DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
1602                  )
1603                  mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
1604                endif()
1605              endforeach()
1606            endif()
1607          endif()
1608
1609          if(NOT MPI_SKIP_GUESSING AND NOT "${MPI_${LANG}_PKG_FOUND}")
1610            # 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
1611            # settings for C. An MPI distribution that is in this situation would be IBM Platform MPI.
1612            if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND)
1613              set(MPI_${LANG}_COMPILE_OPTIONS          ${MPI_C_COMPILE_OPTIONS}     CACHE STRING "MPI ${LANG} compilation options"           )
1614              set(MPI_${LANG}_COMPILE_DEFINITIONS      ${MPI_C_COMPILE_DEFINITIONS} CACHE STRING "MPI ${LANG} compilation definitions"       )
1615              set(MPI_${LANG}_COMPILER_INCLUDE_DIRS    ${MPI_C_INCLUDE_DIRS}        CACHE STRING "MPI ${LANG} compiler wrapper include directories")
1616              set(MPI_${LANG}_LINK_FLAGS               ${MPI_C_LINK_FLAGS}          CACHE STRING "MPI ${LANG} linker flags"                  )
1617              set(MPI_${LANG}_LIB_NAMES                ${MPI_C_LIB_NAMES}           CACHE STRING "MPI ${LANG} libraries to link against"     )
1618            else()
1619              _MPI_guess_settings(${LANG})
1620            endif()
1621          endif()
1622        endif()
1623      endif()
1624    endif()
1625
1626    if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
1627      _MPI_split_include_dirs(${LANG})
1628      _MPI_assemble_include_dirs(${LANG})
1629    else()
1630      set(MPI_${LANG}_INCLUDE_DIRS "")
1631    endif()
1632    _MPI_assemble_libraries(${LANG})
1633
1634    # We always create imported targets even if they're empty
1635    _MPI_create_imported_target(${LANG})
1636
1637    if(NOT MPI_${LANG}_WORKS)
1638      _MPI_check_lang_works(${LANG} FALSE)
1639    endif()
1640
1641    # Next, we'll initialize the MPI variables that have not been previously set.
1642    set(MPI_${LANG}_COMPILE_OPTIONS          "" CACHE STRING "MPI ${LANG} compilation flags"             )
1643    set(MPI_${LANG}_COMPILE_DEFINITIONS      "" CACHE STRING "MPI ${LANG} compilation definitions"       )
1644    set(MPI_${LANG}_COMPILER_INCLUDE_DIRS    "" CACHE STRING "MPI ${LANG} compiler wrapper include directories")
1645    set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS  "" CACHE STRING "MPI ${LANG} additional include directories")
1646    set(MPI_${LANG}_LINK_FLAGS               "" CACHE STRING "MPI ${LANG} linker flags"                  )
1647    if(NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER)
1648      set(MPI_${LANG}_LIB_NAMES                "" CACHE STRING "MPI ${LANG} libraries to link against"   )
1649    endif()
1650    mark_as_advanced(
1651      MPI_${LANG}_COMPILE_OPTIONS
1652      MPI_${LANG}_COMPILE_DEFINITIONS
1653      MPI_${LANG}_LINK_FLAGS
1654      MPI_${LANG}_LIB_NAMES
1655      MPI_${LANG}_COMPILER_INCLUDE_DIRS
1656      MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS
1657      MPI_${LANG}_COMPILER
1658      )
1659
1660    # If we've found MPI, then we'll perform additional analysis: Determine the MPI version, MPI library version, supported
1661    # MPI APIs (i.e. MPI-2 C++ bindings). For Fortran we also need to find specific parameters if we're under MPI-3.
1662    if(MPI_${LANG}_WORKS)
1663      if("${LANG}" STREQUAL "CXX" AND NOT DEFINED MPI_MPICXX_FOUND)
1664        if(NOT MPI_CXX_SKIP_MPICXX AND NOT MPI_CXX_VALIDATE_SKIP_MPICXX)
1665          _MPI_try_staged_settings(${LANG} test_mpi MPICXX FALSE FALSE)
1666          if(MPI_RESULT_${LANG}_test_mpi_MPICXX)
1667            set(MPI_MPICXX_FOUND TRUE)
1668          else()
1669            set(MPI_MPICXX_FOUND FALSE)
1670          endif()
1671        else()
1672          set(MPI_MPICXX_FOUND FALSE)
1673        endif()
1674      endif()
1675
1676      # At this point, we know the bindings present but not the MPI version or anything else.
1677      if(NOT DEFINED MPI_${LANG}_VERSION)
1678        unset(MPI_${LANG}_VERSION_MAJOR)
1679        unset(MPI_${LANG}_VERSION_MINOR)
1680      endif()
1681      set(MPI_BIN_FOLDER ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI)
1682
1683      # For Fortran, we'll want to use the most modern MPI binding to test capabilities other than the
1684      # Fortran parameters, since those depend on the method of consumption.
1685      # For C++, we can always use the C bindings, and should do so, since the C++ bindings do not exist in MPI-3
1686      # whereas the C bindings do, and the C++ bindings never offered any feature advantage over their C counterparts.
1687      if("${LANG}" STREQUAL "Fortran")
1688        if(MPI_${LANG}_HAVE_F08_MODULE)
1689          set(MPI_${LANG}_HIGHEST_METHOD F08_MODULE)
1690        elseif(MPI_${LANG}_HAVE_F90_MODULE)
1691          set(MPI_${LANG}_HIGHEST_METHOD F90_MODULE)
1692        else()
1693          set(MPI_${LANG}_HIGHEST_METHOD F77_HEADER)
1694        endif()
1695
1696        # Another difference between C and Fortran is that we can't use the preprocessor to determine whether MPI_VERSION
1697        # and MPI_SUBVERSION are provided. These defines did not exist in MPI 1.0 and 1.1 and therefore might not
1698        # exist. For C/C++, test_mpi.c will handle the MPI_VERSION extraction, but for Fortran, we need mpiver.f90.
1699        if(NOT DEFINED MPI_${LANG}_VERSION)
1700          _MPI_try_staged_settings(${LANG} mpiver ${MPI_${LANG}_HIGHEST_METHOD} FALSE FALSE)
1701          if(MPI_RESULT_${LANG}_mpiver_${MPI_${LANG}_HIGHEST_METHOD})
1702            file(STRINGS ${MPI_BIN_FOLDER}/mpiver_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER")
1703            if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*")
1704              set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}")
1705              set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}")
1706              set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}")
1707            endif()
1708          endif()
1709        endif()
1710
1711        # Finally, we want to find out which capabilities a given interface supports, compare the MPI-3 standard.
1712        # This is determined by interface specific parameters MPI_SUBARRAYS_SUPPORTED and MPI_ASYNC_PROTECTS_NONBLOCKING
1713        # and might vary between the different methods of consumption.
1714        if(MPI_DETERMINE_Fortran_CAPABILITIES AND NOT MPI_Fortran_CAPABILITIES_DETERMINED)
1715          foreach(mpimethod IN ITEMS F08_MODULE F90_MODULE F77_HEADER)
1716            if(MPI_${LANG}_HAVE_${mpimethod})
1717              set(MPI_${LANG}_${mpimethod}_SUBARRAYS FALSE)
1718              set(MPI_${LANG}_${mpimethod}_ASYNCPROT FALSE)
1719              _MPI_try_staged_settings(${LANG} fortranparam_mpi ${mpimethod} TRUE FALSE)
1720              if(MPI_RESULT_${LANG}_fortranparam_mpi_${mpimethod} AND
1721                NOT "${MPI_RUN_RESULT_${LANG}_fortranparam_mpi_${mpimethod}}" STREQUAL "FAILED_TO_RUN")
1722                if("${MPI_RUN_OUTPUT_${LANG}_fortranparam_mpi_${mpimethod}}" MATCHES
1723                  ".*INFO:SUBARRAYS\\[ *([TF]) *\\]-ASYNCPROT\\[ *([TF]) *\\].*")
1724                  if("${CMAKE_MATCH_1}" STREQUAL "T")
1725                    set(MPI_${LANG}_${mpimethod}_SUBARRAYS TRUE)
1726                  endif()
1727                  if("${CMAKE_MATCH_2}" STREQUAL "T")
1728                    set(MPI_${LANG}_${mpimethod}_ASYNCPROT TRUE)
1729                  endif()
1730                endif()
1731              endif()
1732            endif()
1733          endforeach()
1734          set(MPI_Fortran_CAPABILITIES_DETERMINED TRUE)
1735        endif()
1736      else()
1737        set(MPI_${LANG}_HIGHEST_METHOD normal)
1738
1739        # By the MPI-2 standard, MPI_VERSION and MPI_SUBVERSION are valid for both C and C++ bindings.
1740        if(NOT DEFINED MPI_${LANG}_VERSION)
1741          file(STRINGS ${MPI_BIN_FOLDER}/test_mpi_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER")
1742          if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*")
1743            set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}")
1744            set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}")
1745            set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}")
1746          endif()
1747        endif()
1748      endif()
1749
1750      unset(MPI_BIN_FOLDER)
1751
1752      # At this point, we have dealt with determining the MPI version and parameters for each Fortran method available.
1753      # The one remaining issue is to determine which MPI library is installed.
1754      # Determining the version and vendor of the MPI library is only possible via MPI_Get_library_version() at runtime,
1755      # and therefore we cannot do this while cross-compiling (a user may still define MPI_<lang>_LIBRARY_VERSION_STRING
1756      # themselves and we'll attempt splitting it, which is equivalent to provide the try_run output).
1757      # It's also worth noting that the installed version string can depend on the language, or on the system the binary
1758      # runs on if MPI is not statically linked.
1759      if(MPI_DETERMINE_LIBRARY_VERSION AND NOT MPI_${LANG}_LIBRARY_VERSION_STRING)
1760        _MPI_try_staged_settings(${LANG} libver_mpi ${MPI_${LANG}_HIGHEST_METHOD} TRUE FALSE)
1761        if(MPI_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD} AND
1762          "${MPI_RUN_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}" EQUAL "0")
1763          string(STRIP "${MPI_RUN_OUTPUT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}"
1764            MPI_${LANG}_LIBRARY_VERSION_STRING)
1765        else()
1766          set(MPI_${LANG}_LIBRARY_VERSION_STRING "NOTFOUND")
1767        endif()
1768      endif()
1769    endif()
1770
1771    set(MPI_${LANG}_FIND_QUIETLY ${MPI_FIND_QUIETLY})
1772    set(MPI_${LANG}_FIND_VERSION ${MPI_FIND_VERSION})
1773    set(MPI_${LANG}_FIND_VERSION_EXACT ${MPI_FIND_VERSION_EXACT})
1774
1775    unset(MPI_${LANG}_REQUIRED_VARS)
1776    if (NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
1777      foreach(mpilibname IN LISTS MPI_${LANG}_LIB_NAMES)
1778        list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${mpilibname}_LIBRARY")
1779      endforeach()
1780      list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_LIB_NAMES")
1781      if("${LANG}" STREQUAL "Fortran")
1782        # For Fortran we only need one of the module or header directories to have *some* support for MPI.
1783        if(NOT MPI_${LANG}_MODULE_DIR)
1784          list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_F77_HEADER_DIR")
1785        endif()
1786        if(NOT MPI_${LANG}_F77_HEADER_DIR)
1787          list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_MODULE_DIR")
1788        endif()
1789      else()
1790        list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_HEADER_DIR")
1791      endif()
1792      if(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
1793        foreach(mpiincvar IN LISTS MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
1794          list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${mpiincvar}_INCLUDE_DIR")
1795        endforeach()
1796      endif()
1797      # Append the works variable now. If the settings did not work, this will show up properly.
1798      list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
1799    else()
1800      # If the compiler worked implicitly, use its path as output.
1801      # Should the compiler variable be set, we also require it to work.
1802      list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_COMPILER")
1803      if(MPI_${LANG}_COMPILER)
1804        list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
1805      endif()
1806    endif()
1807    find_package_handle_standard_args(MPI_${LANG} NAME_MISMATCHED
1808      REQUIRED_VARS ${MPI_${LANG}_REQUIRED_VARS}
1809      VERSION_VAR MPI_${LANG}_VERSION)
1810
1811    if(DEFINED MPI_${LANG}_VERSION)
1812      if(NOT _MPI_MIN_VERSION OR _MPI_MIN_VERSION VERSION_GREATER MPI_${LANG}_VERSION)
1813        set(_MPI_MIN_VERSION MPI_${LANG}_VERSION)
1814      endif()
1815    endif()
1816  endif()
1817endforeach()
1818
1819unset(_MPI_REQ_VARS)
1820foreach(LANG IN ITEMS C CXX Fortran)
1821  if((NOT MPI_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST MPI_FIND_COMPONENTS)
1822    list(APPEND _MPI_REQ_VARS "MPI_${LANG}_FOUND")
1823  endif()
1824endforeach()
1825
1826if(MPICXX IN_LIST MPI_FIND_COMPONENTS)
1827  list(APPEND _MPI_REQ_VARS "MPI_MPICXX_FOUND")
1828endif()
1829
1830find_package_handle_standard_args(MPI
1831    REQUIRED_VARS ${_MPI_REQ_VARS}
1832    VERSION_VAR ${_MPI_MIN_VERSION}
1833    REASON_FAILURE_MESSAGE "${_MPI_FAIL_REASON}"
1834    HANDLE_COMPONENTS)
1835
1836#=============================================================================
1837# More backward compatibility stuff
1838
1839# For compatibility reasons, we also define MPIEXEC
1840set(MPIEXEC "${MPIEXEC_EXECUTABLE}")
1841
1842# Copy over MPI_<LANG>_INCLUDE_PATH from the assembled INCLUDE_DIRS.
1843foreach(LANG IN ITEMS C CXX Fortran)
1844  if(MPI_${LANG}_FOUND)
1845    set(MPI_${LANG}_INCLUDE_PATH "${MPI_${LANG}_INCLUDE_DIRS}")
1846    unset(MPI_${LANG}_COMPILE_FLAGS)
1847    if(MPI_${LANG}_COMPILE_OPTIONS)
1848      list(JOIN MPI_${LANG}_COMPILE_OPTIONS " " MPI_${LANG}_COMPILE_FLAGS)
1849    endif()
1850    if(MPI_${LANG}_COMPILE_DEFINITIONS)
1851      foreach(_MPI_DEF IN LISTS MPI_${LANG}_COMPILE_DEFINITIONS)
1852        string(APPEND MPI_${LANG}_COMPILE_FLAGS " -D${_MPI_DEF}")
1853      endforeach()
1854    endif()
1855  endif()
1856endforeach()
1857
1858# Bare MPI sans ${LANG} vars are set to CXX then C, depending on what was found.
1859# This mimics the behavior of the old language-oblivious FindMPI.
1860set(_MPI_OLD_VARS COMPILER INCLUDE_PATH COMPILE_FLAGS LINK_FLAGS LIBRARIES)
1861if (MPI_CXX_FOUND)
1862  foreach (var ${_MPI_OLD_VARS})
1863    set(MPI_${var} ${MPI_CXX_${var}})
1864  endforeach()
1865elseif (MPI_C_FOUND)
1866  foreach (var ${_MPI_OLD_VARS})
1867    set(MPI_${var} ${MPI_C_${var}})
1868  endforeach()
1869endif()
1870
1871# Chop MPI_LIBRARIES into the old-style MPI_LIBRARY and MPI_EXTRA_LIBRARY, and set them in cache.
1872if (MPI_LIBRARIES)
1873  list(GET MPI_LIBRARIES 0 MPI_LIBRARY_WORK)
1874  set(MPI_LIBRARY "${MPI_LIBRARY_WORK}")
1875  unset(MPI_LIBRARY_WORK)
1876else()
1877  set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND")
1878endif()
1879
1880list(LENGTH MPI_LIBRARIES MPI_NUMLIBS)
1881if (MPI_NUMLIBS GREATER 1)
1882  set(MPI_EXTRA_LIBRARY_WORK "${MPI_LIBRARIES}")
1883  list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0)
1884  set(MPI_EXTRA_LIBRARY "${MPI_EXTRA_LIBRARY_WORK}")
1885  unset(MPI_EXTRA_LIBRARY_WORK)
1886else()
1887  set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND")
1888endif()
1889set(MPI_IGNORE_LEGACY_VARIABLES TRUE)
1890#=============================================================================
1891
1892# unset these vars to cleanup namespace
1893unset(_MPI_OLD_VARS)
1894unset(_MPI_PREFIX_PATH)
1895unset(_MPI_BASE_DIR)
1896foreach (lang C CXX Fortran)
1897  unset(_MPI_${LANG}_COMPILER_NAMES)
1898endforeach()
1899
1900cmake_policy(POP)
1901