bca0c105ef2bd1e543d80ea718ceb3d1349436d4
[platform/upstream/cmake.git] / Modules / FindMPI.cmake
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:
5 FindMPI
6 -------
7
8 Find a Message Passing Interface (MPI) implementation.
9
10 The Message Passing Interface (MPI) is a library used to write
11 high-performance distributed-memory parallel applications, and is
12 typically deployed on a cluster.  MPI is a standard interface (defined
13 by 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
19 Variables for using MPI
20 ^^^^^^^^^^^^^^^^^^^^^^^
21
22 The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``.
23 Each of these controls the various MPI languages to search for.
24 The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the
25 MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API
26 that was removed again in MPI-3.
27
28 Depending 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
38 This module will set the following variables per language in your
39 project, 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
63 The 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
74 If possible, the MPI version will be determined by this module. The facilities to detect the MPI version
75 were 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
84 Note that there's no variable for the C bindings being accessible through ``mpi.h``, since the MPI standards
85 always have required this binding to work in both C and C++ code.
86
87 For 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
101 Variables for locating MPI
102 ^^^^^^^^^^^^^^^^^^^^^^^^^^
103
104 This module performs a four step search for an MPI implementation:
105
106 1. Search for ``MPIEXEC_EXECUTABLE`` and, if found, use its base directory.
107 2. 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.
109 3. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
110 4. 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
113 For 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
124 For 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
139 In 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
146 Each 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
156 Additionally, 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
163 If the find procedure fails for a variable ``MPI_<lang>_WORKS``, then the settings detected by or passed to
164 the module did not work and even a simple MPI test program failed to compile.
165
166 If all of these parameters were not sufficient to find the right MPI implementation, a user may
167 disable the entire autodetection process by specifying both a list of libraries in ``MPI_<lang>_LIBRARIES``
168 and a list of include directories in ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``.
169 Any other variable may be set in addition to these two. The module will then validate the MPI settings and store the
170 settings in the cache.
171
172 Cache variables for MPI
173 ^^^^^^^^^^^^^^^^^^^^^^^
174
175 The variable ``MPI_<lang>_INCLUDE_DIRS`` will be assembled from the following variables.
176 For C and CXX:
177
178 ``MPI_<lang>_HEADER_DIR``
179   Location of the ``mpi.h`` header on disk.
180
181 For 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
188 For 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
197 The 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
204 Usage of mpiexec
205 ^^^^^^^^^^^^^^^^
206
207 When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically
208 use 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
215 where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to
216 pass to the MPI program.
217
218 Advanced variables for using MPI
219 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
220
221 The 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.
224 Consider the special considerations for the behavior of :command:`try_run` during cross compilation.
225 Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems.
226 You should only enable these detections if you absolutely need the information.
227
228 If 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
241 Backward Compatibility
242 ^^^^^^^^^^^^^^^^^^^^^^
243
244 .. deprecated:: 3.10
245
246 For backward compatibility with older versions of FindMPI, these
247 variables 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
255 In new projects, please use the ``MPI_<lang>_XXX`` equivalents.
256 Additionally, 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
266 cmake_policy(PUSH)
267 cmake_policy(SET CMP0057 NEW) # if IN_LIST
268
269 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
270 find_package(PkgConfig QUIET)
271
272 # Generic compiler names
273 set(_MPI_C_GENERIC_COMPILER_NAMES          mpicc    mpcc      mpicc_r mpcc_r)
274 set(_MPI_CXX_GENERIC_COMPILER_NAMES        mpicxx   mpiCC     mpcxx   mpCC    mpic++   mpc++
275                                            mpicxx_r mpiCC_r   mpcxx_r mpCC_r  mpic++_r mpc++_r)
276 set(_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
282 set(_MPI_Fujitsu_C_COMPILER_NAMES        mpifccpx mpifcc)
283 set(_MPI_Fujitsu_CXX_COMPILER_NAMES      mpiFCCpx mpiFCC)
284 set(_MPI_Fujitsu_Fortran_COMPILER_NAMES  mpifrtpx mpifrt)
285
286 # GNU compiler names
287 set(_MPI_GNU_C_COMPILER_NAMES              mpigcc mpgcc mpigcc_r mpgcc_r)
288 set(_MPI_GNU_CXX_COMPILER_NAMES            mpig++ mpg++ mpig++_r mpg++_r mpigxx)
289 set(_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
293 if(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)
311 else()
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)
321 endif()
322
323 # PGI compiler names
324 set(_MPI_PGI_C_COMPILER_NAMES              mpipgicc mpipgcc mppgcc)
325 set(_MPI_PGI_CXX_COMPILER_NAMES            mpipgic++ mpipgCC mppgCC)
326 set(_MPI_PGI_Fortran_COMPILER_NAMES        mpipgifort mpipgf95 mpipgf90 mppgf95 mppgf90 mpipgf77 mppgf77)
327
328 # XLC MPI Compiler names
329 set(_MPI_XL_C_COMPILER_NAMES               mpxlc      mpxlc_r    mpixlc     mpixlc_r)
330 set(_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)
332 set(_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
338 set(_MPI_Cray_C_COMPILER_NAMES             cc)
339 set(_MPI_Cray_CXX_COMPILER_NAMES           CC)
340 set(_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.
349 foreach (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)
363 endforeach()
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.
370 set(_MPIEXEC_NAMES_BASE                   mpiexec mpiexec.hydra mpiexec.mpd mpirun lamexec srun)
371
372 unset(_MPIEXEC_NAMES)
373 foreach(_MPIEXEC_NAME IN LISTS _MPIEXEC_NAMES_BASE)
374   list(APPEND _MPIEXEC_NAMES "${_MPIEXEC_NAME}${MPI_EXECUTABLE_SUFFIX}")
375 endforeach()
376 unset(_MPIEXEC_NAMES_BASE)
377
378 function (_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)
406 endfunction()
407
408 macro(_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()
415 endmacro()
416
417 macro(_MPI_env_unset_ifnot VAR)
418   if(NOT _MPI_${VAR}_WAS_SET)
419     unset(ENV{${VAR}})
420   endif()
421 endmacro()
422
423 function (_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       # also match flags starting with "-l:" here
779       string(REGEX REPLACE "^ ?${CMAKE_LINK_LIBRARY_FLAG}(:lib|:)?" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
780       string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
781       list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}")
782     endforeach()
783   endif()
784
785   # Treat linker objects given by full path, for example static libraries, import libraries
786   # or shared libraries if there aren't any import libraries in use on the system.
787   # Note that we do not consider CMAKE_<TYPE>_LIBRARY_PREFIX intentionally here: The linker will for a given file
788   # decide how to link it based on file type, not based on a prefix like 'lib'.
789   set(_MPI_LIB_SUFFIX_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
790   if(DEFINED CMAKE_IMPORT_LIBRARY_SUFFIX)
791     if(NOT ("${CMAKE_IMPORT_LIBRARY_SUFFIX}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}"))
792       string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_IMPORT_LIBRARY_SUFFIX}")
793     endif()
794   else()
795     string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_SHARED_LIBRARY_SUFFIX}")
796   endif()
797   set(_MPI_LIB_NAME_REGEX "(([^\" ]+(${_MPI_LIB_SUFFIX_REGEX}))|(\"[^\"]+(${_MPI_LIB_SUFFIX_REGEX})\"))( +|$)")
798   string(REPLACE "." "\\." _MPI_LIB_NAME_REGEX "${_MPI_LIB_NAME_REGEX}")
799
800   string(REGEX MATCHALL "${_MPI_LIB_NAME_REGEX}" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
801   foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES)
802     # Do not match "-l:" flags
803     string(REGEX MATCH "^ ?${CMAKE_LINK_LIBRARY_FLAG}:" _MPI_LIB_NAME_TEST "${_MPI_LIB_NAME}")
804     if(_MPI_LIB_NAME_TEST STREQUAL "")
805       string(REGEX REPLACE "^ +\"?|\"? +$" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
806       get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY)
807       if(NOT "${_MPI_LIB_PATH}" STREQUAL "")
808         list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}")
809       else()
810         list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}")
811       endif()
812     endif()
813   endforeach()
814
815   # Save the explicitly given link directories
816   set(MPI_LINK_DIRECTORIES_LEFTOVER "${MPI_LINK_DIRECTORIES_WORK}")
817
818   # An MPI compiler wrapper could have its MPI libraries in the implicitly
819   # linked directories of the compiler itself.
820   if(DEFINED CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES)
821     list(APPEND MPI_LINK_DIRECTORIES_WORK "${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}")
822   endif()
823
824   # Determine full path names for all of the libraries that one needs
825   # to link against in an MPI program
826   unset(MPI_PLAIN_LIB_NAMES_WORK)
827   foreach(_MPI_LIB_NAME IN LISTS MPI_LIB_NAMES_WORK)
828     get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB_NAME}" NAME_WE)
829     list(APPEND MPI_PLAIN_LIB_NAMES_WORK "${_MPI_PLAIN_LIB_NAME}")
830     find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
831       NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
832       HINTS ${MPI_LINK_DIRECTORIES_WORK}
833       DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
834     )
835     mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
836     # Remove the directory from the remainder list.
837     if(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
838       get_filename_component(_MPI_TAKEN_DIRECTORY "${MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY}" DIRECTORY)
839       list(REMOVE_ITEM MPI_LINK_DIRECTORIES_LEFTOVER "${_MPI_TAKEN_DIRECTORY}")
840     endif()
841   endforeach()
842
843   # Add the link directories given explicitly that we haven't used back as linker directories.
844   if(NOT WIN32)
845     foreach(_MPI_LINK_DIRECTORY IN LISTS MPI_LINK_DIRECTORIES_LEFTOVER)
846       file(TO_NATIVE_PATH "${_MPI_LINK_DIRECTORY}" _MPI_LINK_DIRECTORY_ACTUAL)
847       string(FIND "${_MPI_LINK_DIRECTORY_ACTUAL}" " " _MPI_LINK_DIRECTORY_CONTAINS_SPACE)
848       if(NOT _MPI_LINK_DIRECTORY_CONTAINS_SPACE EQUAL -1)
849         set(_MPI_LINK_DIRECTORY_ACTUAL "\"${_MPI_LINK_DIRECTORY_ACTUAL}\"")
850       endif()
851       if(MPI_LINK_FLAGS_WORK)
852         string(APPEND MPI_LINK_FLAGS_WORK " ${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
853       else()
854         set(MPI_LINK_FLAGS_WORK "${CMAKE_LIBRARY_PATH_FLAG}${_MPI_LINK_DIRECTORY_ACTUAL}")
855       endif()
856     endforeach()
857   endif()
858
859   # Deal with the libraries given with full path next
860   unset(MPI_DIRECT_LIB_NAMES_WORK)
861   foreach(_MPI_LIB_FULLPATH IN LISTS MPI_LIB_FULLPATHS_WORK)
862     get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB_FULLPATH}" NAME_WE)
863     list(APPEND MPI_DIRECT_LIB_NAMES_WORK "${_MPI_PLAIN_LIB_NAME}")
864     set(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY "${_MPI_LIB_FULLPATH}" CACHE FILEPATH "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI")
865     mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
866   endforeach()
867   # Directly linked objects should be linked first in case some generic linker flags are needed for them.
868   if(MPI_DIRECT_LIB_NAMES_WORK)
869     set(MPI_PLAIN_LIB_NAMES_WORK "${MPI_DIRECT_LIB_NAMES_WORK};${MPI_PLAIN_LIB_NAMES_WORK}")
870   endif()
871
872   # MPI might require pthread to work. The above mechanism wouldn't detect it, but we need to
873   # link it in that case. -lpthread is covered by the normal library treatment on the other hand.
874   if("${MPI_COMPILE_CMDLINE}" MATCHES "-pthread")
875     list(APPEND MPI_COMPILE_OPTIONS_WORK "-pthread")
876     if(MPI_LINK_FLAGS_WORK)
877       string(APPEND MPI_LINK_FLAGS_WORK " -pthread")
878     else()
879       set(MPI_LINK_FLAGS_WORK "-pthread")
880     endif()
881   endif()
882
883   if(MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS)
884     list(APPEND MPI_COMPILE_DEFINITIONS_WORK "${MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS}")
885   endif()
886   if(MPI_${LANG}_EXTRA_COMPILE_OPTIONS)
887     list(APPEND MPI_COMPILE_OPTIONS_WORK "${MPI_${LANG}_EXTRA_COMPILE_OPTIONS}")
888   endif()
889   if(MPI_${LANG}_EXTRA_LIB_NAMES)
890     list(APPEND MPI_PLAIN_LIB_NAMES_WORK "${MPI_${LANG}_EXTRA_LIB_NAMES}")
891   endif()
892
893   # If we found MPI, set up all of the appropriate cache entries
894   if(NOT MPI_${LANG}_COMPILE_OPTIONS)
895     set(MPI_${LANG}_COMPILE_OPTIONS          ${MPI_COMPILE_OPTIONS_WORK}     CACHE STRING "MPI ${LANG} compilation options"            FORCE)
896   endif()
897   if(NOT MPI_${LANG}_COMPILE_DEFINITIONS)
898     set(MPI_${LANG}_COMPILE_DEFINITIONS      ${MPI_COMPILE_DEFINITIONS_WORK} CACHE STRING "MPI ${LANG} compilation definitions"        FORCE)
899   endif()
900   if(NOT MPI_${LANG}_COMPILER_INCLUDE_DIRS)
901     set(MPI_${LANG}_COMPILER_INCLUDE_DIRS    ${MPI_INCLUDE_DIRS_WORK}        CACHE STRING "MPI ${LANG} compiler wrapper include directories" FORCE)
902   endif()
903   if(NOT MPI_${LANG}_LINK_FLAGS)
904     set(MPI_${LANG}_LINK_FLAGS               ${MPI_LINK_FLAGS_WORK}          CACHE STRING "MPI ${LANG} linker flags"                   FORCE)
905   endif()
906   if(NOT MPI_${LANG}_LIB_NAMES)
907     set(MPI_${LANG}_LIB_NAMES                ${MPI_PLAIN_LIB_NAMES_WORK}     CACHE STRING "MPI ${LANG} libraries to link against"      FORCE)
908   endif()
909   set(MPI_${LANG}_WRAPPER_FOUND TRUE PARENT_SCOPE)
910 endfunction()
911
912 function(_MPI_guess_settings LANG)
913   set(MPI_GUESS_FOUND FALSE)
914   # Currently only MSMPI and MPICH2 on Windows are supported, so we can skip this search if we're not targeting that.
915   if(WIN32)
916     # MSMPI
917
918     # The environment variables MSMPI_INC and MSMPILIB32/64 are the only ways of locating the MSMPI_SDK,
919     # which is installed separately from the runtime. Thus it's possible to have mpiexec but not MPI headers
920     # or import libraries and vice versa.
921     if(NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MSMPI")
922       # We first attempt to locate the msmpi.lib. Should be find it, we'll assume that the MPI present is indeed
923       # Microsoft MPI.
924       if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
925         file(TO_CMAKE_PATH "$ENV{MSMPI_LIB64}" MPI_MSMPI_LIB_PATH)
926         file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x64" MPI_MSMPI_INC_PATH_EXTRA)
927       else()
928         file(TO_CMAKE_PATH "$ENV{MSMPI_LIB32}" MPI_MSMPI_LIB_PATH)
929         file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x86" MPI_MSMPI_INC_PATH_EXTRA)
930       endif()
931
932       find_library(MPI_msmpi_LIBRARY
933         NAMES msmpi
934         HINTS ${MPI_MSMPI_LIB_PATH}
935         DOC "Location of the msmpi library for Microsoft MPI")
936       mark_as_advanced(MPI_msmpi_LIBRARY)
937
938       if(MPI_msmpi_LIBRARY)
939         # Next, we attempt to locate the MPI header. Note that for Fortran we know that mpif.h is a way
940         # MSMPI can be used and therefore that header has to be present.
941         if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
942           get_filename_component(MPI_MSMPI_INC_DIR "$ENV{MSMPI_INC}" REALPATH)
943           set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_MSMPI_INC_DIR}" CACHE STRING "MPI ${LANG} additional include directories" FORCE)
944           unset(MPI_MSMPI_INC_DIR)
945         endif()
946
947         # For MSMPI, one can compile the MPI module by building the mpi.f90 shipped with the MSMPI SDK,
948         # thus it might be present or provided by the user. Figuring out which is supported is done later on.
949         # The PGI Fortran compiler for instance ships a prebuilt set of modules in its own include folder.
950         # Should a user be employing PGI or have built its own set and provided it via cache variables, the
951         # splitting routine would have located the module files.
952
953         # For C and C++, we're done here (MSMPI does not ship the MPI-2 C++ bindings) - however, for Fortran
954         # we need some extra library to glue Fortran support together:
955         # MSMPI ships 2-4 Fortran libraries, each for different Fortran compiler behaviors. The library names
956         # ending with a c are using the cdecl calling convention, whereas those ending with an s are for Fortran
957         # implementations using stdcall. Therefore, the 64-bit MSMPI only ships those ending in 'c', whereas the 32-bit
958         # has both variants available.
959         # The second difference is the last but one letter, if it's an e(nd), the length of a string argument is
960         # passed by the Fortran compiler after all other arguments on the parameter list, if it's an m(ixed),
961         # it's passed immediately after the string address.
962
963         # To summarize:
964         #   - msmpifec: CHARACTER length passed after the parameter list and using cdecl calling convention
965         #   - msmpifmc: CHARACTER length passed directly after string address and using cdecl calling convention
966         #   - msmpifes: CHARACTER length passed after the parameter list and using stdcall calling convention
967         #   - msmpifms: CHARACTER length passed directly after string address and using stdcall calling convention
968         # 32-bit MSMPI ships all four libraries, 64-bit MSMPI ships only the first two.
969
970         # As is, Intel Fortran and PGI Fortran both use the 'ec' variant of the calling convention, whereas
971         # the old Compaq Visual Fortran compiler defaulted to the 'ms' version. It's possible to make Intel Fortran
972         # use the CVF calling convention using /iface:cvf, but we assume - and this is also assumed in FortranCInterface -
973         # this isn't the case. It's also possible to make CVF use the 'ec' variant, using /iface=(cref,nomixed_str_len_arg).
974
975         # Our strategy is now to locate all libraries, but enter msmpifec into the LIB_NAMES array.
976         # Should this not be adequate it's a straightforward way for a user to change the LIB_NAMES array and
977         # have his library found. Still, this should not be necessary outside of exceptional cases, as reasoned.
978         if ("${LANG}" STREQUAL "Fortran")
979           set(MPI_MSMPI_CALLINGCONVS c)
980           if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
981             list(APPEND MPI_MSMPI_CALLINGCONVS s)
982           endif()
983           foreach(mpistrlenpos IN ITEMS e m)
984             foreach(mpicallingconv IN LISTS MPI_MSMPI_CALLINGCONVS)
985               find_library(MPI_msmpif${mpistrlenpos}${mpicallingconv}_LIBRARY
986                 NAMES msmpif${mpistrlenpos}${mpicallingconv}
987                 HINTS "${MPI_MSMPI_LIB_PATH}"
988                 DOC "Location of the msmpi${mpistrlenpos}${mpicallingconv} library for Microsoft MPI")
989               mark_as_advanced(MPI_msmpif${mpistrlenpos}${mpicallingconv}_LIBRARY)
990             endforeach()
991           endforeach()
992           if(NOT MPI_${LANG}_LIB_NAMES)
993             set(MPI_${LANG}_LIB_NAMES "msmpi;msmpifec" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
994           endif()
995
996           # At this point we're *not* done. MSMPI requires an additional include file for Fortran giving the value
997           # of MPI_AINT. This file is called mpifptr.h located in the x64 and x86 subfolders, respectively.
998           find_path(MPI_mpifptr_INCLUDE_DIR
999             NAMES "mpifptr.h"
1000             HINTS "${MPI_MSMPI_INC_PATH_EXTRA}"
1001             DOC "Location of the mpifptr.h extra header for Microsoft MPI")
1002           if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
1003             set(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS "mpifptr" CACHE STRING "MPI ${LANG} additional include directory variables, given in the form MPI_<name>_INCLUDE_DIR." FORCE)
1004           endif()
1005           mark_as_advanced(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS MPI_mpifptr_INCLUDE_DIR)
1006         else()
1007           if(NOT MPI_${LANG}_LIB_NAMES)
1008             set(MPI_${LANG}_LIB_NAMES "msmpi" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
1009           endif()
1010         endif()
1011         mark_as_advanced(MPI_${LANG}_LIB_NAMES)
1012         set(MPI_GUESS_FOUND TRUE)
1013
1014         if(_MPIEXEC_NOT_GIVEN)
1015           unset(MPIEXEC_EXECUTABLE CACHE)
1016         endif()
1017
1018         find_program(MPIEXEC_EXECUTABLE
1019           NAMES mpiexec
1020           HINTS $ENV{MSMPI_BIN} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin"
1021           DOC "Executable for running MPI programs.")
1022       endif()
1023     endif()
1024
1025     # At this point there's not many MPIs that we could still consider.
1026     # OpenMPI 1.6.x and below supported Windows, but these ship compiler wrappers that still work.
1027     # The only other relevant MPI implementation without a wrapper is MPICH2, which had Windows support in 1.4.1p1 and older.
1028     if(NOT MPI_GUESS_FOUND AND (NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MPICH2"))
1029       set(MPI_MPICH_PREFIX_PATHS
1030         "$ENV{ProgramW6432}/MPICH2/lib"
1031         "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/../lib"
1032         "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]/lib"
1033       )
1034
1035       # All of C, C++ and Fortran will need mpi.lib, so we'll look for this first
1036       find_library(MPI_mpi_LIBRARY
1037         NAMES mpi
1038         HINTS ${MPI_MPICH_PREFIX_PATHS})
1039       mark_as_advanced(MPI_mpi_LIBRARY)
1040       # If we found mpi.lib, we detect the rest of MPICH2
1041       if(MPI_mpi_LIBRARY)
1042         set(MPI_MPICH_LIB_NAMES "mpi")
1043         # If MPI-2 C++ bindings are requested, we need to locate cxx.lib as well.
1044         # Otherwise, MPICH_SKIP_MPICXX will be defined and these bindings aren't needed.
1045         if("${LANG}" STREQUAL "CXX" AND NOT MPI_CXX_SKIP_MPICXX)
1046           find_library(MPI_cxx_LIBRARY
1047             NAMES cxx
1048             HINTS ${MPI_MPICH_PREFIX_PATHS})
1049           mark_as_advanced(MPI_cxx_LIBRARY)
1050           list(APPEND MPI_MPICH_LIB_NAMES "cxx")
1051         # For Fortran, MPICH2 provides three different libraries:
1052         #   fmpich2.lib which uses uppercase symbols and cdecl,
1053         #   fmpich2s.lib which uses uppercase symbols and stdcall (32-bit only),
1054         #   fmpich2g.lib which uses lowercase symbols with double underscores and cdecl.
1055         # fmpich2s.lib would be useful for Compaq Visual Fortran, fmpich2g.lib has to be used with GNU g77 and is also
1056         # provided in the form of an .a archive for MinGW and Cygwin. From our perspective, fmpich2.lib is the only one
1057         # we need to try, and if it doesn't work with the given Fortran compiler we'd find out later on during validation
1058         elseif("${LANG}" STREQUAL "Fortran")
1059           find_library(MPI_fmpich2_LIBRARY
1060             NAMES fmpich2
1061             HINTS ${MPI_MPICH_PREFIX_PATHS})
1062           find_library(MPI_fmpich2s_LIBRARY
1063             NAMES fmpich2s
1064             HINTS ${MPI_MPICH_PREFIX_PATHS})
1065           find_library(MPI_fmpich2g_LIBRARY
1066             NAMES fmpich2g
1067             HINTS ${MPI_MPICH_PREFIX_PATHS})
1068           mark_as_advanced(MPI_fmpich2_LIBRARY MPI_fmpich2s_LIBRARY MPI_fmpich2g_LIBRARY)
1069           list(APPEND MPI_MPICH_LIB_NAMES "fmpich2")
1070         endif()
1071
1072         if(NOT MPI_${LANG}_LIB_NAMES)
1073           set(MPI_${LANG}_LIB_NAMES "${MPI_MPICH_LIB_NAMES}" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
1074         endif()
1075         unset(MPI_MPICH_LIB_NAMES)
1076
1077         if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1078           # For MPICH2, the include folder would be in ../include relative to the library folder.
1079           get_filename_component(MPI_MPICH_ROOT_DIR "${MPI_mpi_LIBRARY}" DIRECTORY)
1080           get_filename_component(MPI_MPICH_ROOT_DIR "${MPI_MPICH_ROOT_DIR}" DIRECTORY)
1081           if(IS_DIRECTORY "${MPI_MPICH_ROOT_DIR}/include")
1082             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)
1083           endif()
1084           unset(MPI_MPICH_ROOT_DIR)
1085         endif()
1086         set(MPI_GUESS_FOUND TRUE)
1087
1088         if(_MPIEXEC_NOT_GIVEN)
1089           unset(MPIEXEC_EXECUTABLE CACHE)
1090         endif()
1091
1092         find_program(MPIEXEC_EXECUTABLE
1093           NAMES ${_MPIEXEC_NAMES}
1094           HINTS "$ENV{ProgramW6432}/MPICH2/bin"
1095                 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]"
1096                 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]/bin"
1097           DOC "Executable for running MPI programs.")
1098       endif()
1099       unset(MPI_MPICH_PREFIX_PATHS)
1100     endif()
1101   endif()
1102   set(MPI_${LANG}_GUESS_FOUND "${MPI_GUESS_FOUND}" PARENT_SCOPE)
1103 endfunction()
1104
1105 function(_MPI_adjust_compile_definitions LANG)
1106   if("${LANG}" STREQUAL "CXX")
1107     # To disable the C++ bindings, we need to pass some definitions since the mpi.h header has to deal with both C and C++
1108     # bindings in MPI-2.
1109     if(MPI_CXX_SKIP_MPICXX AND NOT MPI_${LANG}_COMPILE_DEFINITIONS MATCHES "SKIP_MPICXX")
1110       # MPICH_SKIP_MPICXX is being used in MPICH and derivatives like MVAPICH or Intel MPI
1111       # OMPI_SKIP_MPICXX is being used in Open MPI
1112       # _MPICC_H is being used for IBM Platform MPI
1113       list(APPEND MPI_${LANG}_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX" "OMPI_SKIP_MPICXX" "_MPICC_H")
1114       set(MPI_${LANG}_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}" CACHE STRING "MPI ${LANG} compilation definitions" FORCE)
1115     endif()
1116   endif()
1117 endfunction()
1118
1119 macro(_MPI_assemble_libraries LANG)
1120   set(MPI_${LANG}_LIBRARIES "")
1121   # Only for libraries do we need to check whether the compiler's linking stage is separate.
1122   if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}" OR NOT MPI_${LANG}_WORKS_IMPLICIT)
1123     foreach(mpilib IN LISTS MPI_${LANG}_LIB_NAMES)
1124       list(APPEND MPI_${LANG}_LIBRARIES ${MPI_${mpilib}_LIBRARY})
1125     endforeach()
1126   endif()
1127 endmacro()
1128
1129 macro(_MPI_assemble_include_dirs LANG)
1130   set(MPI_${LANG}_INCLUDE_DIRS
1131     ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1132     ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1133     )
1134   if("${LANG}" MATCHES "(C|CXX)")
1135     if(MPI_${LANG}_HEADER_DIR)
1136       list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
1137     endif()
1138   else() # Fortran
1139     if(MPI_${LANG}_F77_HEADER_DIR)
1140       list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_F77_HEADER_DIR}")
1141     endif()
1142     if(MPI_${LANG}_MODULE_DIR)
1143       list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_MODULE_DIR}")
1144     endif()
1145   endif()
1146   if(MPI_${LANG}_INCLUDE_DIRS)
1147     list(REMOVE_DUPLICATES MPI_${LANG}_INCLUDE_DIRS)
1148   endif()
1149 endmacro()
1150
1151 macro(_MPI_split_include_dirs LANG)
1152   # Backwards compatibility: Search INCLUDE_PATH if given.
1153   if(MPI_${LANG}_INCLUDE_PATH)
1154     list(APPEND MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_INCLUDE_PATH}")
1155   endif()
1156
1157   # We try to find the headers/modules among those paths (and system paths)
1158   # For C/C++, we just need to have a look for mpi.h.
1159   if("${LANG}" MATCHES "(C|CXX)")
1160     find_path(MPI_${LANG}_HEADER_DIR "mpi.h"
1161       HINTS
1162         ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1163         ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1164     )
1165     mark_as_advanced(MPI_${LANG}_HEADER_DIR)
1166     if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1167       list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
1168     endif()
1169
1170   # Fortran is more complicated here: An implementation could provide
1171   # any of the Fortran 77/90/2008 APIs for MPI. For example, MSMPI
1172   # only provides Fortran 77 and - if mpi.f90 is built - potentially
1173   # a Fortran 90 module.
1174   elseif("${LANG}" STREQUAL "Fortran")
1175     find_path(MPI_${LANG}_F77_HEADER_DIR "mpif.h"
1176       HINTS
1177         ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1178         ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1179     )
1180     find_path(MPI_${LANG}_MODULE_DIR
1181       NAMES "mpi.mod" "mpi_f08.mod"
1182       HINTS
1183         ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
1184         ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
1185     )
1186     if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1187       list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS
1188         "${MPI_${LANG}_F77_HEADER_DIR}"
1189         "${MPI_${LANG}_MODULE_DIR}"
1190       )
1191     endif()
1192     mark_as_advanced(MPI_${LANG}_F77_HEADER_DIR MPI_${LANG}_MODULE_DIR)
1193   endif()
1194
1195   # Remove duplicates and default system directories from the list.
1196   if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1197     list(REMOVE_DUPLICATES MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
1198     foreach(MPI_IMPLICIT_INC_DIR IN LISTS CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES)
1199       list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_IMPLICIT_INC_DIR})
1200     endforeach()
1201   endif()
1202
1203   set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories" FORCE)
1204 endmacro()
1205
1206 macro(_MPI_create_imported_target LANG)
1207   if(NOT TARGET MPI::MPI_${LANG})
1208     add_library(MPI::MPI_${LANG} INTERFACE IMPORTED)
1209   endif()
1210
1211   # When this is consumed for compiling CUDA, use '-Xcompiler' to wrap '-pthread' and '-fexceptions'.
1212   string(REPLACE "-pthread" "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler >-pthread"
1213     _MPI_${LANG}_COMPILE_OPTIONS "${MPI_${LANG}_COMPILE_OPTIONS}")
1214   string(REPLACE "-fexceptions" "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler >-fexceptions"
1215     _MPI_${LANG}_COMPILE_OPTIONS "${_MPI_${LANG}_COMPILE_OPTIONS}")
1216   set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${_MPI_${LANG}_COMPILE_OPTIONS}")
1217   unset(_MPI_${LANG}_COMPILE_OPTIONS)
1218
1219   set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}")
1220
1221   if(MPI_${LANG}_LINK_FLAGS)
1222     string(REPLACE "," "$<COMMA>" _MPI_${LANG}_LINK_FLAGS "${MPI_${LANG}_LINK_FLAGS}")
1223     string(PREPEND _MPI_${LANG}_LINK_FLAGS "$<HOST_LINK:SHELL:")
1224     string(APPEND _MPI_${LANG}_LINK_FLAGS ">")
1225     set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_OPTIONS "${_MPI_${LANG}_LINK_FLAGS}")
1226   endif()
1227   # If the compiler links MPI implicitly, no libraries will be found as they're contained within
1228   # CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES already.
1229   if(MPI_${LANG}_LIBRARIES)
1230     set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_LIBRARIES "${MPI_${LANG}_LIBRARIES}")
1231   endif()
1232   # Given the new design of FindMPI, INCLUDE_DIRS will always be located, even under implicit linking.
1233   set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MPI_${LANG}_INCLUDE_DIRS}")
1234 endmacro()
1235
1236 function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY SUPPRESS_ERRORS)
1237   set(WORK_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI")
1238   set(SRC_DIR "${CMAKE_ROOT}/Modules/FindMPI")
1239   set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI/${MPI_TEST_FILE_NAME}_${LANG}.bin")
1240   unset(MPI_TEST_COMPILE_DEFINITIONS)
1241   if("${LANG}" STREQUAL "Fortran")
1242     if("${MODE}" STREQUAL "F90_MODULE")
1243       set(MPI_Fortran_INCLUDE_LINE "use mpi\n      implicit none")
1244     elseif("${MODE}" STREQUAL "F08_MODULE")
1245       set(MPI_Fortran_INCLUDE_LINE "use mpi_f08\n      implicit none")
1246     else() # F77 header
1247       set(MPI_Fortran_INCLUDE_LINE "implicit none\n      include 'mpif.h'")
1248     endif()
1249     configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.f90.in" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90" @ONLY)
1250     set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90")
1251   elseif("${LANG}" STREQUAL "CXX")
1252     configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.c" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp" COPYONLY)
1253     set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp")
1254     if("${MODE}" STREQUAL "TEST_MPICXX")
1255       set(MPI_TEST_COMPILE_DEFINITIONS TEST_MPI_MPICXX)
1256     endif()
1257   else() # C
1258     set(MPI_TEST_SOURCE_FILE "${SRC_DIR}/${MPI_TEST_FILE_NAME}.c")
1259   endif()
1260   if(RUN_BINARY)
1261     try_run(MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
1262      "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
1263       COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
1264       LINK_LIBRARIES MPI::MPI_${LANG}
1265       RUN_OUTPUT_VARIABLE MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
1266       COMPILE_OUTPUT_VARIABLE _MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT)
1267     set(MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} "${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}" PARENT_SCOPE)
1268   else()
1269     try_compile(MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
1270       "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
1271       COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
1272       LINK_LIBRARIES MPI::MPI_${LANG}
1273       COPY_FILE "${BIN_FILE}"
1274       OUTPUT_VARIABLE _MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT)
1275   endif()
1276   if(NOT SUPPRESS_ERRORS)
1277     if(NOT MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
1278       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
1279           "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")
1280     elseif(DEFINED MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} AND MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
1281         file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
1282           "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")
1283     endif()
1284   endif()
1285 endfunction()
1286
1287 macro(_MPI_check_lang_works LANG SUPPRESS_ERRORS)
1288   # For Fortran we may have by the MPI-3 standard an implementation that provides:
1289   #   - the mpi_f08 module
1290   #   - *both*, the mpi module and 'mpif.h'
1291   # Since older MPI standards (MPI-1) did not define anything but 'mpif.h', we need to check all three individually.
1292   if( NOT MPI_${LANG}_WORKS )
1293     if("${LANG}" STREQUAL "Fortran")
1294       set(MPI_Fortran_INTEGER_LINE "(kind=MPI_INTEGER_KIND)")
1295       _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER FALSE ${SUPPRESS_ERRORS})
1296       _MPI_try_staged_settings(${LANG} test_mpi F90_MODULE FALSE ${SUPPRESS_ERRORS})
1297       _MPI_try_staged_settings(${LANG} test_mpi F08_MODULE FALSE ${SUPPRESS_ERRORS})
1298
1299       set(MPI_${LANG}_WORKS FALSE)
1300
1301       foreach(mpimethod IN ITEMS F77_HEADER F08_MODULE F90_MODULE)
1302         if(MPI_RESULT_${LANG}_test_mpi_${mpimethod})
1303           set(MPI_${LANG}_WORKS TRUE)
1304           set(MPI_${LANG}_HAVE_${mpimethod} TRUE)
1305         else()
1306           set(MPI_${LANG}_HAVE_${mpimethod} FALSE)
1307         endif()
1308       endforeach()
1309       # MPI-1 versions had no MPI_INTGER_KIND defined, so we need to try without it.
1310       # However, MPI-1 also did not define the Fortran 90 and 08 modules, so we only try the F77 header.
1311       unset(MPI_Fortran_INTEGER_LINE)
1312       if(NOT MPI_${LANG}_WORKS)
1313         _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER_NOKIND FALSE ${SUPPRESS_ERRORS})
1314         if(MPI_RESULT_${LANG}_test_mpi_F77_HEADER_NOKIND)
1315           set(MPI_${LANG}_WORKS TRUE)
1316           set(MPI_${LANG}_HAVE_F77_HEADER TRUE)
1317         endif()
1318       endif()
1319     else()
1320       _MPI_try_staged_settings(${LANG} test_mpi normal FALSE ${SUPPRESS_ERRORS})
1321       # If 'test_mpi' built correctly, we've found valid MPI settings. There might not be MPI-2 C++ support, but there can't
1322       # be MPI-2 C++ support without the C bindings being present, so checking for them is sufficient.
1323       set(MPI_${LANG}_WORKS "${MPI_RESULT_${LANG}_test_mpi_normal}")
1324     endif()
1325   endif()
1326 endmacro()
1327
1328 # Some systems install various MPI implementations in separate folders in some MPI prefix
1329 # This macro enumerates all such subfolders and adds them to the list of hints that will be searched.
1330 macro(MPI_search_mpi_prefix_folder PREFIX_FOLDER)
1331   if(EXISTS "${PREFIX_FOLDER}")
1332     file(GLOB _MPI_folder_children RELATIVE "${PREFIX_FOLDER}" "${PREFIX_FOLDER}/*")
1333     foreach(_MPI_folder_child IN LISTS _MPI_folder_children)
1334       if(IS_DIRECTORY "${PREFIX_FOLDER}/${_MPI_folder_child}")
1335         list(APPEND MPI_HINT_DIRS "${PREFIX_FOLDER}/${_MPI_folder_child}")
1336       endif()
1337     endforeach()
1338   endif()
1339 endmacro()
1340
1341 set(MPI_HINT_DIRS ${MPI_HOME} $ENV{MPI_HOME} $ENV{I_MPI_ROOT})
1342 if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux")
1343   # SUSE Linux Enterprise Server stores its MPI implementations under /usr/lib64/mpi/gcc/<name>
1344   # We enumerate the subfolders and append each as a prefix
1345   MPI_search_mpi_prefix_folder("/usr/lib64/mpi/gcc")
1346 elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "FreeBSD")
1347   # FreeBSD ships mpich under the normal system paths - but available openmpi implementations
1348   # will be found in /usr/local/mpi/<name>
1349   MPI_search_mpi_prefix_folder("/usr/local/mpi")
1350 endif()
1351
1352 # Most MPI distributions have some form of mpiexec or mpirun which gives us something we can look for.
1353 # The MPI standard does not mandate the existence of either, but instead only makes requirements if a distribution
1354 # ships an mpiexec program (mpirun executables are not regulated by the standard).
1355
1356 # We defer searching for mpiexec binaries belonging to guesses until later. By doing so, mismatches between mpiexec
1357 # and the MPI we found should be reduced.
1358 if(NOT MPIEXEC_EXECUTABLE)
1359   set(_MPIEXEC_NOT_GIVEN TRUE)
1360 else()
1361   set(_MPIEXEC_NOT_GIVEN FALSE)
1362 endif()
1363
1364 find_program(MPIEXEC_EXECUTABLE
1365   NAMES ${_MPIEXEC_NAMES}
1366   PATH_SUFFIXES bin sbin
1367   HINTS ${MPI_HINT_DIRS}
1368   DOC "Executable for running MPI programs.")
1369
1370 # call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin).
1371 # This gives us a fairly reliable base directory to search for /bin /lib and /include from.
1372 get_filename_component(_MPI_BASE_DIR "${MPIEXEC_EXECUTABLE}" PATH)
1373 get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH)
1374
1375 # According to the MPI standard, section 8.8 -n is a guaranteed, and the only guaranteed way to
1376 # launch an MPI process using mpiexec if such a program exists.
1377 set(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.")
1378 set(MPIEXEC_PREFLAGS     ""    CACHE STRING "These flags will be directly before the executable that is being run by mpiexec.")
1379 set(MPIEXEC_POSTFLAGS    ""    CACHE STRING "These flags will be placed after all flags passed to mpiexec.")
1380
1381 # Set the number of processes to the physical processor count
1382 cmake_host_system_information(RESULT _MPIEXEC_NUMPROCS QUERY NUMBER_OF_PHYSICAL_CORES)
1383 set(MPIEXEC_MAX_NUMPROCS "${_MPIEXEC_NUMPROCS}" CACHE STRING "Maximum number of processors available to run MPI applications.")
1384 unset(_MPIEXEC_NUMPROCS)
1385 mark_as_advanced(MPIEXEC_EXECUTABLE MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS)
1386
1387 #=============================================================================
1388 # Backward compatibility input hacks.  Propagate the FindMPI hints to C and
1389 # CXX if the respective new versions are not defined.  Translate the old
1390 # MPI_LIBRARY and MPI_EXTRA_LIBRARY to respective MPI_${LANG}_LIBRARIES.
1391 #
1392 # Once we find the new variables, we translate them back into their old
1393 # equivalents below.
1394 if(NOT MPI_IGNORE_LEGACY_VARIABLES)
1395   foreach (LANG IN ITEMS C CXX)
1396     # Old input variables.
1397     set(_MPI_OLD_INPUT_VARS COMPILER COMPILE_FLAGS INCLUDE_PATH LINK_FLAGS)
1398
1399     # Set new vars based on their old equivalents, if the new versions are not already set.
1400     foreach (var ${_MPI_OLD_INPUT_VARS})
1401       if (NOT MPI_${LANG}_${var} AND MPI_${var})
1402         set(MPI_${LANG}_${var} "${MPI_${var}}")
1403       endif()
1404     endforeach()
1405
1406     # Chop the old compile flags into options and definitions
1407
1408     unset(MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS)
1409     unset(MPI_${LANG}_EXTRA_COMPILE_OPTIONS)
1410     if(MPI_${LANG}_COMPILE_FLAGS)
1411       separate_arguments(MPI_SEPARATE_FLAGS NATIVE_COMMAND "${MPI_${LANG}_COMPILE_FLAGS}")
1412       foreach(_MPI_FLAG IN LISTS MPI_SEPARATE_FLAGS)
1413         if("${_MPI_FLAG}" MATCHES "^ *-D([^ ]+)")
1414           list(APPEND MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS "${CMAKE_MATCH_1}")
1415         else()
1416           list(APPEND MPI_${LANG}_EXTRA_COMPILE_OPTIONS "${_MPI_FLAG}")
1417         endif()
1418       endforeach()
1419       unset(MPI_SEPARATE_FLAGS)
1420     endif()
1421
1422     # If a list of libraries was given, we'll split it into new-style cache variables
1423     unset(MPI_${LANG}_EXTRA_LIB_NAMES)
1424     if(NOT MPI_${LANG}_LIB_NAMES)
1425       foreach(_MPI_LIB IN LISTS MPI_${LANG}_LIBRARIES MPI_LIBRARY MPI_EXTRA_LIBRARY)
1426         if(_MPI_LIB)
1427           get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB}" NAME_WE)
1428           get_filename_component(_MPI_LIB_NAME "${_MPI_LIB}" NAME)
1429           get_filename_component(_MPI_LIB_DIR "${_MPI_LIB}" DIRECTORY)
1430           list(APPEND MPI_${LANG}_EXTRA_LIB_NAMES "${_MPI_PLAIN_LIB_NAME}")
1431           find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
1432             NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
1433             HINTS ${_MPI_LIB_DIR} $ENV{MPI_LIB}
1434             DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
1435           )
1436           mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
1437         endif()
1438       endforeach()
1439     endif()
1440   endforeach()
1441 endif()
1442 #=============================================================================
1443
1444 unset(MPI_VERSION)
1445 unset(MPI_VERSION_MAJOR)
1446 unset(MPI_VERSION_MINOR)
1447
1448 unset(_MPI_MIN_VERSION)
1449
1450 # If the user specified a library name we assume they prefer that library over a wrapper. If not, they can disable skipping manually.
1451 if(NOT DEFINED MPI_SKIP_COMPILER_WRAPPER AND MPI_GUESS_LIBRARY_NAME)
1452   set(MPI_SKIP_COMPILER_WRAPPER TRUE)
1453 endif()
1454
1455 # This loop finds the compilers and sends them off for interrogation.
1456 foreach(LANG IN ITEMS C CXX Fortran)
1457   if(CMAKE_${LANG}_COMPILER_LOADED)
1458     if(NOT MPI_FIND_COMPONENTS)
1459       set(_MPI_FIND_${LANG} TRUE)
1460     elseif( LANG IN_LIST MPI_FIND_COMPONENTS)
1461       set(_MPI_FIND_${LANG} TRUE)
1462     elseif( "${LANG}" STREQUAL "CXX" AND NOT MPI_CXX_SKIP_MPICXX AND MPICXX IN_LIST MPI_FIND_COMPONENTS )
1463       set(_MPI_FIND_${LANG} TRUE)
1464     else()
1465       set(_MPI_FIND_${LANG} FALSE)
1466     endif()
1467   else()
1468     set(_MPI_FIND_${LANG} FALSE)
1469     if(LANG IN_LIST MPI_FIND_COMPONENTS)
1470       string(APPEND _MPI_FAIL_REASON "MPI component '${LANG}' was requested, but language ${LANG} is not enabled.  ")
1471     endif()
1472   endif()
1473   if(_MPI_FIND_${LANG})
1474     if( "${LANG}" STREQUAL "CXX" AND NOT MPICXX IN_LIST MPI_FIND_COMPONENTS )
1475       option(MPI_CXX_SKIP_MPICXX "If true, the MPI-2 C++ bindings are disabled using definitions." FALSE)
1476       mark_as_advanced(MPI_CXX_SKIP_MPICXX)
1477     endif()
1478     _MPI_adjust_compile_definitions(${LANG})
1479     if(NOT (MPI_${LANG}_LIB_NAMES AND (MPI_${LANG}_INCLUDE_PATH OR MPI_${LANG}_INCLUDE_DIRS OR MPI_${LANG}_COMPILER_INCLUDE_DIRS)))
1480       set(MPI_${LANG}_TRIED_IMPLICIT FALSE)
1481       set(MPI_${LANG}_WORKS_IMPLICIT FALSE)
1482       if(NOT MPI_${LANG}_COMPILER AND NOT MPI_ASSUME_NO_BUILTIN_MPI)
1483         # Should the imported targets be empty, we effectively try whether the compiler supports MPI on its own, which is the case on e.g.
1484         # Cray PrgEnv.
1485         _MPI_create_imported_target(${LANG})
1486         _MPI_check_lang_works(${LANG} TRUE)
1487
1488         # 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.
1489         if(MPI_${LANG}_WORKS)
1490           set(MPI_${LANG}_COMPILER "${CMAKE_${LANG}_COMPILER}" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE)
1491           set(MPI_${LANG}_WORKS_IMPLICIT TRUE)
1492         endif()
1493         set(MPI_${LANG}_TRIED_IMPLICIT TRUE)
1494       endif()
1495
1496       if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}" OR NOT MPI_${LANG}_WORKS)
1497         set(MPI_${LANG}_WRAPPER_FOUND FALSE)
1498         set(MPI_PINNED_COMPILER FALSE)
1499
1500         if(NOT MPI_SKIP_COMPILER_WRAPPER)
1501           if(MPI_${LANG}_COMPILER)
1502             # If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
1503             if (NOT IS_ABSOLUTE "${MPI_${LANG}_COMPILER}")
1504               # Get rid of our default list of names and just search for the name the user wants.
1505               set(_MPI_${LANG}_COMPILER_NAMES "${MPI_${LANG}_COMPILER}")
1506               unset(MPI_${LANG}_COMPILER CACHE)
1507             endif()
1508             # If the user specifies a compiler, we don't want to try to search libraries either.
1509             set(MPI_PINNED_COMPILER TRUE)
1510           endif()
1511
1512           # If we have an MPI base directory, we'll try all compiler names in that one first.
1513           # This should prevent mixing different MPI environments
1514           if(_MPI_BASE_DIR)
1515             find_program(MPI_${LANG}_COMPILER
1516               NAMES  ${_MPI_${LANG}_COMPILER_NAMES}
1517               PATH_SUFFIXES bin sbin
1518               HINTS  ${_MPI_BASE_DIR}
1519               NO_DEFAULT_PATH
1520               DOC    "MPI compiler for ${LANG}"
1521             )
1522           endif()
1523
1524           # If the base directory did not help (for example because the mpiexec isn't in the same directory as the compilers),
1525           # we shall try searching in the default paths.
1526           find_program(MPI_${LANG}_COMPILER
1527             NAMES  ${_MPI_${LANG}_COMPILER_NAMES}
1528             PATH_SUFFIXES bin sbin
1529             DOC    "MPI compiler for ${LANG}"
1530           )
1531
1532           if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
1533             set(MPI_PINNED_COMPILER TRUE)
1534
1535             # If we haven't made the implicit compiler test yet, perform it now.
1536             if(NOT MPI_${LANG}_TRIED_IMPLICIT)
1537               _MPI_create_imported_target(${LANG})
1538               _MPI_check_lang_works(${LANG} TRUE)
1539             endif()
1540
1541             # Should the MPI compiler not work implicitly for MPI, still interrogate it.
1542             # Otherwise, MPI compilers for which CMake has separate linking stages, e.g. Intel MPI on Windows where link.exe is being used
1543             # directly during linkage instead of CMAKE_<LANG>_COMPILER will not work.
1544             if(NOT MPI_${LANG}_WORKS)
1545               set(MPI_${LANG}_WORKS_IMPLICIT FALSE)
1546               _MPI_interrogate_compiler(${LANG})
1547             else()
1548               set(MPI_${LANG}_WORKS_IMPLICIT TRUE)
1549             endif()
1550           elseif(MPI_${LANG}_COMPILER)
1551             _MPI_interrogate_compiler(${LANG})
1552           endif()
1553         endif()
1554
1555         # We are on a Cray, environment identfier: PE_ENV is set (CRAY), and
1556         # have NOT found an mpic++-like compiler wrapper (previous block),
1557         # and we do NOT use the Cray cc/CC compiler wrappers as CC/CXX CMake
1558         # compiler.
1559         # So as a last resort, we now interrogate cc/CC/ftn for MPI flags.
1560         if(DEFINED ENV{PE_ENV} AND NOT "${MPI_${LANG}_COMPILER}")
1561           set(MPI_PINNED_COMPILER TRUE)
1562           find_program(MPI_${LANG}_COMPILER
1563             NAMES  ${_MPI_Cray_${LANG}_COMPILER_NAMES}
1564             PATH_SUFFIXES bin sbin
1565             DOC    "MPI compiler for ${LANG}"
1566           )
1567
1568           # If we haven't made the implicit compiler test yet, perform it now.
1569           if(NOT MPI_${LANG}_TRIED_IMPLICIT)
1570             _MPI_create_imported_target(${LANG})
1571             _MPI_check_lang_works(${LANG} TRUE)
1572           endif()
1573
1574           set(MPI_${LANG}_WORKS_IMPLICIT TRUE)
1575           _MPI_interrogate_compiler(${LANG})
1576         endif()
1577
1578         if(NOT MPI_PINNED_COMPILER AND NOT MPI_${LANG}_WRAPPER_FOUND)
1579           # If MPI_PINNED_COMPILER wasn't given, and the MPI compiler we potentially found didn't work, we withdraw it.
1580           set(MPI_${LANG}_COMPILER "MPI_${LANG}_COMPILER-NOTFOUND" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE)
1581
1582           if(LANG STREQUAL "C")
1583             set(_MPI_PKG "mpi-c")
1584           elseif(LANG STREQUAL "CXX")
1585             set(_MPI_PKG "mpi-cxx")
1586           elseif(LANG STREQUAL "Fortran")
1587             set(_MPI_PKG "mpi-fort")
1588           else()
1589             set(_MPI_PKG "")
1590           endif()
1591           if(_MPI_PKG AND PKG_CONFIG_FOUND)
1592             pkg_check_modules("MPI_${LANG}_PKG" "${_MPI_PKG}")
1593             if("${MPI_${LANG}_PKG_FOUND}")
1594               set(MPI_${LANG}_COMPILE_OPTIONS  ${MPI_${LANG}_PKG_CFLAGS}        CACHE STRING "MPI ${LANG} compilation options"       FORCE)
1595               set(MPI_${LANG}_INCLUDE_PATH     ${MPI_${LANG}_PKG_INCLUDE_DIRS}  CACHE STRING "MPI ${LANG} include directories"       FORCE)
1596               set(MPI_${LANG}_LINK_FLAGS       ${MPI_${LANG}_PKG_LDFLAGS}       CACHE STRING "MPI ${LANG} linker flags"              FORCE)
1597               set(MPI_${LANG}_LIB_NAMES        ${MPI_${LANG}_PKG_LIBRARIES}     CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
1598               foreach(_MPI_LIB IN LISTS MPI_${LANG}_LIB_NAMES)
1599                 if(_MPI_LIB)
1600                   get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB}" NAME_WE)
1601                   get_filename_component(_MPI_LIB_NAME "${_MPI_LIB}" NAME)
1602                   get_filename_component(_MPI_LIB_DIR "${_MPI_LIB}" DIRECTORY)
1603                   find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
1604                     NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
1605                     HINTS ${_MPI_LIB_DIR}
1606                     DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
1607                   )
1608                   mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
1609                 endif()
1610               endforeach()
1611             endif()
1612           endif()
1613
1614           if(NOT MPI_SKIP_GUESSING AND NOT "${MPI_${LANG}_PKG_FOUND}")
1615             # 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
1616             # settings for C. An MPI distribution that is in this situation would be IBM Platform MPI.
1617             if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND)
1618               set(MPI_${LANG}_COMPILE_OPTIONS          ${MPI_C_COMPILE_OPTIONS}     CACHE STRING "MPI ${LANG} compilation options"           )
1619               set(MPI_${LANG}_COMPILE_DEFINITIONS      ${MPI_C_COMPILE_DEFINITIONS} CACHE STRING "MPI ${LANG} compilation definitions"       )
1620               set(MPI_${LANG}_COMPILER_INCLUDE_DIRS    ${MPI_C_INCLUDE_DIRS}        CACHE STRING "MPI ${LANG} compiler wrapper include directories")
1621               set(MPI_${LANG}_LINK_FLAGS               ${MPI_C_LINK_FLAGS}          CACHE STRING "MPI ${LANG} linker flags"                  )
1622               set(MPI_${LANG}_LIB_NAMES                ${MPI_C_LIB_NAMES}           CACHE STRING "MPI ${LANG} libraries to link against"     )
1623             else()
1624               _MPI_guess_settings(${LANG})
1625             endif()
1626           endif()
1627         endif()
1628       endif()
1629     endif()
1630
1631     if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
1632       _MPI_split_include_dirs(${LANG})
1633       _MPI_assemble_include_dirs(${LANG})
1634     else()
1635       set(MPI_${LANG}_INCLUDE_DIRS "")
1636     endif()
1637     _MPI_assemble_libraries(${LANG})
1638
1639     # We always create imported targets even if they're empty
1640     _MPI_create_imported_target(${LANG})
1641
1642     if(NOT MPI_${LANG}_WORKS)
1643       _MPI_check_lang_works(${LANG} FALSE)
1644     endif()
1645
1646     # Next, we'll initialize the MPI variables that have not been previously set.
1647     set(MPI_${LANG}_COMPILE_OPTIONS          "" CACHE STRING "MPI ${LANG} compilation flags"             )
1648     set(MPI_${LANG}_COMPILE_DEFINITIONS      "" CACHE STRING "MPI ${LANG} compilation definitions"       )
1649     set(MPI_${LANG}_COMPILER_INCLUDE_DIRS    "" CACHE STRING "MPI ${LANG} compiler wrapper include directories")
1650     set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS  "" CACHE STRING "MPI ${LANG} additional include directories")
1651     set(MPI_${LANG}_LINK_FLAGS               "" CACHE STRING "MPI ${LANG} linker flags"                  )
1652     if(NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER)
1653       set(MPI_${LANG}_LIB_NAMES                "" CACHE STRING "MPI ${LANG} libraries to link against"   )
1654     endif()
1655     mark_as_advanced(
1656       MPI_${LANG}_COMPILE_OPTIONS
1657       MPI_${LANG}_COMPILE_DEFINITIONS
1658       MPI_${LANG}_LINK_FLAGS
1659       MPI_${LANG}_LIB_NAMES
1660       MPI_${LANG}_COMPILER_INCLUDE_DIRS
1661       MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS
1662       MPI_${LANG}_COMPILER
1663       )
1664
1665     # If we've found MPI, then we'll perform additional analysis: Determine the MPI version, MPI library version, supported
1666     # MPI APIs (i.e. MPI-2 C++ bindings). For Fortran we also need to find specific parameters if we're under MPI-3.
1667     if(MPI_${LANG}_WORKS)
1668       if("${LANG}" STREQUAL "CXX" AND NOT DEFINED MPI_MPICXX_FOUND)
1669         if(NOT MPI_CXX_SKIP_MPICXX AND NOT MPI_CXX_VALIDATE_SKIP_MPICXX)
1670           _MPI_try_staged_settings(${LANG} test_mpi MPICXX FALSE FALSE)
1671           if(MPI_RESULT_${LANG}_test_mpi_MPICXX)
1672             set(MPI_MPICXX_FOUND TRUE)
1673           else()
1674             set(MPI_MPICXX_FOUND FALSE)
1675           endif()
1676         else()
1677           set(MPI_MPICXX_FOUND FALSE)
1678         endif()
1679       endif()
1680
1681       # At this point, we know the bindings present but not the MPI version or anything else.
1682       if(NOT DEFINED MPI_${LANG}_VERSION)
1683         unset(MPI_${LANG}_VERSION_MAJOR)
1684         unset(MPI_${LANG}_VERSION_MINOR)
1685       endif()
1686       set(MPI_BIN_FOLDER ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI)
1687
1688       # For Fortran, we'll want to use the most modern MPI binding to test capabilities other than the
1689       # Fortran parameters, since those depend on the method of consumption.
1690       # For C++, we can always use the C bindings, and should do so, since the C++ bindings do not exist in MPI-3
1691       # whereas the C bindings do, and the C++ bindings never offered any feature advantage over their C counterparts.
1692       if("${LANG}" STREQUAL "Fortran")
1693         if(MPI_${LANG}_HAVE_F08_MODULE)
1694           set(MPI_${LANG}_HIGHEST_METHOD F08_MODULE)
1695         elseif(MPI_${LANG}_HAVE_F90_MODULE)
1696           set(MPI_${LANG}_HIGHEST_METHOD F90_MODULE)
1697         else()
1698           set(MPI_${LANG}_HIGHEST_METHOD F77_HEADER)
1699         endif()
1700
1701         # Another difference between C and Fortran is that we can't use the preprocessor to determine whether MPI_VERSION
1702         # and MPI_SUBVERSION are provided. These defines did not exist in MPI 1.0 and 1.1 and therefore might not
1703         # exist. For C/C++, test_mpi.c will handle the MPI_VERSION extraction, but for Fortran, we need mpiver.f90.
1704         if(NOT DEFINED MPI_${LANG}_VERSION)
1705           _MPI_try_staged_settings(${LANG} mpiver ${MPI_${LANG}_HIGHEST_METHOD} FALSE FALSE)
1706           if(MPI_RESULT_${LANG}_mpiver_${MPI_${LANG}_HIGHEST_METHOD})
1707             file(STRINGS ${MPI_BIN_FOLDER}/mpiver_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER")
1708             if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*")
1709               set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}")
1710               set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}")
1711               set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}")
1712             endif()
1713           endif()
1714         endif()
1715
1716         # Finally, we want to find out which capabilities a given interface supports, compare the MPI-3 standard.
1717         # This is determined by interface specific parameters MPI_SUBARRAYS_SUPPORTED and MPI_ASYNC_PROTECTS_NONBLOCKING
1718         # and might vary between the different methods of consumption.
1719         if(MPI_DETERMINE_Fortran_CAPABILITIES AND NOT MPI_Fortran_CAPABILITIES_DETERMINED)
1720           foreach(mpimethod IN ITEMS F08_MODULE F90_MODULE F77_HEADER)
1721             if(MPI_${LANG}_HAVE_${mpimethod})
1722               set(MPI_${LANG}_${mpimethod}_SUBARRAYS FALSE)
1723               set(MPI_${LANG}_${mpimethod}_ASYNCPROT FALSE)
1724               _MPI_try_staged_settings(${LANG} fortranparam_mpi ${mpimethod} TRUE FALSE)
1725               if(MPI_RESULT_${LANG}_fortranparam_mpi_${mpimethod} AND
1726                 NOT "${MPI_RUN_RESULT_${LANG}_fortranparam_mpi_${mpimethod}}" STREQUAL "FAILED_TO_RUN")
1727                 if("${MPI_RUN_OUTPUT_${LANG}_fortranparam_mpi_${mpimethod}}" MATCHES
1728                   ".*INFO:SUBARRAYS\\[ *([TF]) *\\]-ASYNCPROT\\[ *([TF]) *\\].*")
1729                   if("${CMAKE_MATCH_1}" STREQUAL "T")
1730                     set(MPI_${LANG}_${mpimethod}_SUBARRAYS TRUE)
1731                   endif()
1732                   if("${CMAKE_MATCH_2}" STREQUAL "T")
1733                     set(MPI_${LANG}_${mpimethod}_ASYNCPROT TRUE)
1734                   endif()
1735                 endif()
1736               endif()
1737             endif()
1738           endforeach()
1739           set(MPI_Fortran_CAPABILITIES_DETERMINED TRUE)
1740         endif()
1741       else()
1742         set(MPI_${LANG}_HIGHEST_METHOD normal)
1743
1744         # By the MPI-2 standard, MPI_VERSION and MPI_SUBVERSION are valid for both C and C++ bindings.
1745         if(NOT DEFINED MPI_${LANG}_VERSION)
1746           file(STRINGS ${MPI_BIN_FOLDER}/test_mpi_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER")
1747           if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*")
1748             set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}")
1749             set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}")
1750             set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}")
1751           endif()
1752         endif()
1753       endif()
1754
1755       unset(MPI_BIN_FOLDER)
1756
1757       # At this point, we have dealt with determining the MPI version and parameters for each Fortran method available.
1758       # The one remaining issue is to determine which MPI library is installed.
1759       # Determining the version and vendor of the MPI library is only possible via MPI_Get_library_version() at runtime,
1760       # and therefore we cannot do this while cross-compiling (a user may still define MPI_<lang>_LIBRARY_VERSION_STRING
1761       # themselves and we'll attempt splitting it, which is equivalent to provide the try_run output).
1762       # It's also worth noting that the installed version string can depend on the language, or on the system the binary
1763       # runs on if MPI is not statically linked.
1764       if(MPI_DETERMINE_LIBRARY_VERSION AND NOT MPI_${LANG}_LIBRARY_VERSION_STRING)
1765         _MPI_try_staged_settings(${LANG} libver_mpi ${MPI_${LANG}_HIGHEST_METHOD} TRUE FALSE)
1766         if(MPI_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD} AND
1767           "${MPI_RUN_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}" EQUAL "0")
1768           string(STRIP "${MPI_RUN_OUTPUT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}"
1769             MPI_${LANG}_LIBRARY_VERSION_STRING)
1770         else()
1771           set(MPI_${LANG}_LIBRARY_VERSION_STRING "NOTFOUND")
1772         endif()
1773       endif()
1774     endif()
1775
1776     set(MPI_${LANG}_FIND_QUIETLY ${MPI_FIND_QUIETLY})
1777     set(MPI_${LANG}_FIND_VERSION ${MPI_FIND_VERSION})
1778     set(MPI_${LANG}_FIND_VERSION_EXACT ${MPI_FIND_VERSION_EXACT})
1779
1780     unset(MPI_${LANG}_REQUIRED_VARS)
1781     if (NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
1782       foreach(mpilibname IN LISTS MPI_${LANG}_LIB_NAMES)
1783         list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${mpilibname}_LIBRARY")
1784       endforeach()
1785       list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_LIB_NAMES")
1786       if("${LANG}" STREQUAL "Fortran")
1787         # For Fortran we only need one of the module or header directories to have *some* support for MPI.
1788         if(NOT MPI_${LANG}_MODULE_DIR)
1789           list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_F77_HEADER_DIR")
1790         endif()
1791         if(NOT MPI_${LANG}_F77_HEADER_DIR)
1792           list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_MODULE_DIR")
1793         endif()
1794       else()
1795         list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_HEADER_DIR")
1796       endif()
1797       if(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
1798         foreach(mpiincvar IN LISTS MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
1799           list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${mpiincvar}_INCLUDE_DIR")
1800         endforeach()
1801       endif()
1802       # Append the works variable now. If the settings did not work, this will show up properly.
1803       list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
1804     else()
1805       # If the compiler worked implicitly, use its path as output.
1806       # Should the compiler variable be set, we also require it to work.
1807       list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_COMPILER")
1808       if(MPI_${LANG}_COMPILER)
1809         list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
1810       endif()
1811     endif()
1812     find_package_handle_standard_args(MPI_${LANG} NAME_MISMATCHED
1813       REQUIRED_VARS ${MPI_${LANG}_REQUIRED_VARS}
1814       VERSION_VAR MPI_${LANG}_VERSION)
1815
1816     if(DEFINED MPI_${LANG}_VERSION)
1817       if(NOT _MPI_MIN_VERSION OR _MPI_MIN_VERSION VERSION_GREATER MPI_${LANG}_VERSION)
1818         set(_MPI_MIN_VERSION MPI_${LANG}_VERSION)
1819       endif()
1820     endif()
1821   endif()
1822 endforeach()
1823
1824 unset(_MPI_REQ_VARS)
1825 foreach(LANG IN ITEMS C CXX Fortran)
1826   if((NOT MPI_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST MPI_FIND_COMPONENTS)
1827     list(APPEND _MPI_REQ_VARS "MPI_${LANG}_FOUND")
1828   endif()
1829 endforeach()
1830
1831 if(MPICXX IN_LIST MPI_FIND_COMPONENTS)
1832   list(APPEND _MPI_REQ_VARS "MPI_MPICXX_FOUND")
1833 endif()
1834
1835 find_package_handle_standard_args(MPI
1836     REQUIRED_VARS ${_MPI_REQ_VARS}
1837     VERSION_VAR ${_MPI_MIN_VERSION}
1838     REASON_FAILURE_MESSAGE "${_MPI_FAIL_REASON}"
1839     HANDLE_COMPONENTS)
1840
1841 #=============================================================================
1842 # More backward compatibility stuff
1843
1844 # For compatibility reasons, we also define MPIEXEC
1845 set(MPIEXEC "${MPIEXEC_EXECUTABLE}")
1846
1847 # Copy over MPI_<LANG>_INCLUDE_PATH from the assembled INCLUDE_DIRS.
1848 foreach(LANG IN ITEMS C CXX Fortran)
1849   if(MPI_${LANG}_FOUND)
1850     set(MPI_${LANG}_INCLUDE_PATH "${MPI_${LANG}_INCLUDE_DIRS}")
1851     unset(MPI_${LANG}_COMPILE_FLAGS)
1852     if(MPI_${LANG}_COMPILE_OPTIONS)
1853       list(JOIN MPI_${LANG}_COMPILE_OPTIONS " " MPI_${LANG}_COMPILE_FLAGS)
1854     endif()
1855     if(MPI_${LANG}_COMPILE_DEFINITIONS)
1856       foreach(_MPI_DEF IN LISTS MPI_${LANG}_COMPILE_DEFINITIONS)
1857         string(APPEND MPI_${LANG}_COMPILE_FLAGS " -D${_MPI_DEF}")
1858       endforeach()
1859     endif()
1860   endif()
1861 endforeach()
1862
1863 # Bare MPI sans ${LANG} vars are set to CXX then C, depending on what was found.
1864 # This mimics the behavior of the old language-oblivious FindMPI.
1865 set(_MPI_OLD_VARS COMPILER INCLUDE_PATH COMPILE_FLAGS LINK_FLAGS LIBRARIES)
1866 if (MPI_CXX_FOUND)
1867   foreach (var ${_MPI_OLD_VARS})
1868     set(MPI_${var} ${MPI_CXX_${var}})
1869   endforeach()
1870 elseif (MPI_C_FOUND)
1871   foreach (var ${_MPI_OLD_VARS})
1872     set(MPI_${var} ${MPI_C_${var}})
1873   endforeach()
1874 endif()
1875
1876 # Chop MPI_LIBRARIES into the old-style MPI_LIBRARY and MPI_EXTRA_LIBRARY, and set them in cache.
1877 if (MPI_LIBRARIES)
1878   list(GET MPI_LIBRARIES 0 MPI_LIBRARY_WORK)
1879   set(MPI_LIBRARY "${MPI_LIBRARY_WORK}")
1880   unset(MPI_LIBRARY_WORK)
1881 else()
1882   set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND")
1883 endif()
1884
1885 list(LENGTH MPI_LIBRARIES MPI_NUMLIBS)
1886 if (MPI_NUMLIBS GREATER 1)
1887   set(MPI_EXTRA_LIBRARY_WORK "${MPI_LIBRARIES}")
1888   list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0)
1889   set(MPI_EXTRA_LIBRARY "${MPI_EXTRA_LIBRARY_WORK}")
1890   unset(MPI_EXTRA_LIBRARY_WORK)
1891 else()
1892   set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND")
1893 endif()
1894 set(MPI_IGNORE_LEGACY_VARIABLES TRUE)
1895 #=============================================================================
1896
1897 # unset these vars to cleanup namespace
1898 unset(_MPI_OLD_VARS)
1899 unset(_MPI_PREFIX_PATH)
1900 unset(_MPI_BASE_DIR)
1901 foreach (lang C CXX Fortran)
1902   unset(_MPI_${LANG}_COMPILER_NAMES)
1903 endforeach()
1904
1905 cmake_policy(POP)