.. _install-configure-compilers-and-flags-label:

Specifying compilers and flags
==============================

Changing the compilers that Open MPI uses to build itself uses the
standard GNU Autoconf mechanism of setting special environment variables
either before invoking ``configure`` or on the ``configure`` command
line itself.

The following environment variables are recognized by ``configure``:

* ``CC``: C compiler to use
* ``CFLAGS``: Compile flags to pass to the C compiler
* ``CPPFLAGS``: Preprocessor flags to pass to the C compiler
* ``CXX``: C++ compiler to use
* ``CXXCFLAGS``: Compile flags to pass to the C++ compiler
* ``CXXCPPFLAGS``: Preprocessor flags to pass to the C++ compiler
* ``FC``: Fortran compiler to use
* ``FCFLAGS``: Compile flags to pass to the Fortran compiler
* ``LDFLAGS``: Linker flags to pass to all compilers
* ``LIBS``: Libraries to pass to all compilers (it is rarely
  necessary for users to need to specify additional ``LIBS``)
* ``PKG_CONFIG``: Path to the ``pkg-config`` utility

.. note:: Open MPI |ompi_ver| does not contain any C++ code.  The only
          tests that ``configure`` runs with the C++ compiler is for
          the purposes of determining an appropriate value for ``CXX``
          to use in the ``mpic++`` :ref:`wrapper compiler
          <label-quickstart-building-apps>`.  The ``CXXCFLAGS`` and
          ``CXXCPPFLAGS`` values are *only* used in these
          ``configure`` checks to ensure that the C++ compiler works.

For example, to build with a specific instance of ``gcc``, ``g++``,
and ``gfortran``:

.. code-block:: sh

   shell$ ./configure \
       CC=/opt/gcc-a.b.c/bin/gcc \
       CXX=/opt/gcc-a.b.c/bin/g++ \
       FC=/opt/gcc-a.b.c/bin/gfortran ...

Here's another example, this time showing building with the Intel
compiler suite:

.. code-block:: sh

   shell$ ./configure \
       CC=icc \
       CXX=icpc \
       FC=ifort ...

.. note:: The Open MPI community generally suggests using the above
   command line form for setting different compilers (vs. setting
   environment variables and then invoking ``./configure``).  The
   above form will save all variables and values in the ``config.log``
   file, which makes post-mortem analysis easier if problems occur.

Note that the flags you specify must be compatible across all the
compilers.  In particular, flags specified to one language compiler
must generate code that can be compiled and linked against code that
is generated by the other language compilers.  For example, on a 64
bit system where the compiler default is to build 32 bit executables:

.. code-block:: sh

   # Assuming the GNU compiler suite
   shell$ ./configure CFLAGS=-m64 ...

will produce 64 bit C objects, but 32 bit objects for Fortran.  These
codes will be incompatible with each other, and Open MPI will not build
successfully.  Instead, you must specify building 64 bit objects for
*all* languages:

.. code-block:: sh

   # Assuming the GNU compiler suite
   shell$ ./configure CFLAGS=-m64 FCFLAGS=-m64 ...

The above command line will pass ``-m64`` to all the compilers, and
therefore will produce 64 bit objects for all languages.

.. warning:: Note that setting ``CFLAGS`` (etc.) does *not* affect the
             flags used by the :ref:`wrapper compilers
             <label-quickstart-building-apps>`.  In the above, example, you may
             also need to add ``-m64`` to various ``--with-wrapper-FOO``
             options:

             .. code-block::

                shell$ ./configure CFLAGS=-m64 FCFLAGS=-m64 \
                     --with-wrapper-cflags=-m64 \
                     --with-wrapper-cxxflags=-m64 \
                     --with-wrapper-fcflags=-m64 ...

             Failure to do this will result in MPI applications
             failing to compile / link properly.

             See the :ref:`Customizing wrapper compiler behavior
             <label-customizing-wrapper-compiler>` section for more
             details.

Note that if you intend to compile Open MPI with a ``make`` other than
the default one in your ``PATH``, then you must either set the ``$MAKE``
environment variable before invoking Open MPI's ``configure`` script, or
pass ``MAKE=your_make_prog`` to configure.  For example:

.. code-block:: sh

   shell$ ./configure MAKE=/path/to/my/make ...

This could be the case, for instance, if you have a shell alias for
``make``, or you always type ``gmake`` out of habit.  Failure to tell
``configure`` which non-default ``make`` you will use to compile Open MPI
can result in undefined behavior (meaning: don't do that).

Note that you may also want to ensure that the value of
``LD_LIBRARY_PATH`` is set appropriately (or not at all) for your build
(or whatever environment variable is relevant for your operating
system).  For example, some users have been tripped up by setting to
use a non-default Fortran compiler via the ``FC`` environment variable,
but then failing to set ``LD_LIBRARY_PATH`` to include the directory
containing that non-default Fortran compiler's support libraries.
This causes Open MPI's ``configure`` script to fail when it tries to
compile / link / run simple Fortran programs.

It is required that the compilers specified be compile and link
compatible, meaning that object files created by one compiler must be
able to be linked with object files from the other compilers and
produce correctly functioning executables.

Statically linking to the libraries of Intel compiler suite
-----------------------------------------------------------

The Intel compiler suite, by default, dynamically links its runtime libraries
against the Open MPI binaries and libraries. This can cause problems if the
Intel compiler libraries are installed in non-standard locations. For example,
you might get errors like:

.. code-block::

   error while loading shared libraries: libimf.so: cannot open shared object file:
   No such file or directory

To avoid such problems, you can pass flags to Open MPI's configure
script that instruct the Intel compiler suite to statically link its
runtime libraries with Open MPI:

.. code-block::

   shell$ ./configure CC=icc CXX=icpc FC=ifort LDFLAGS=-Wc,-static-intel ...
