Headers need to use <mpi.h> instead of "mpi.h"
Created by: bangerth
We got a bug report for deal.II that in essence shows this error message:
In file included from /usr/local/include/ml_epetra_utils.h:42:0,
from /usr/local/include/ml_MultiLevelPreconditioner.h:86,
from ~/Downloads/dealii/source/lac/trilinos_precondition_ml.cc:33:
/usr/local/include/mpi.h:157:16: error: redefinition of ‘struct MPI_Status’
typedef struct MPI_Status {
^~~~~~~~~~
In file included from ~/Downloads/dealii/build/include/deal.II/base/config.h:328:0,
from ~/Downloads/dealii/include/deal.II/lac/trilinos_index_access.h:19,
from ~/Downloads/dealii/source/lac/trilinos_precondition_ml.cc:16:
/opt/intel/compilers_and_libraries/linux/mpi/include64/mpi.h:679:16: note: previous definition of ‘struct MPI_Status’
Note how the conflicting declarations come from /usr/local/include/mpi.h
and /opt/intel/compilers_and_libraries/linux/mpi/include64/mpi.h
.
The reason is that the user is compiling with the Intel compiler which, via a -I
flag, provides the mpi.h
in /opt/intel/compilers_and_libraries/linux/mpi/include64
. This resolves all instances of #include <mpi.h>
.
Maybe in a poor choice, the user installed both Trilinos and another MPI installation in /usr/local
, and so when a Trilinos header uses the double-quoted form #include "mpi.h"
, the compiler first looks into /usr/local/include
and only then into the paths listed via -I
. Normally that would do no harm since no mpi.h
is found, but now it is, and the conflict happens.
The problem is because we have this in ml_epetra_utils.h
:
ifdef ML_MPI
#ifndef EPETRA_MPI
#define EPETRA_MPI
#endif
#include "mpi.h" *****************
#endif
This should really be #include <mpi.h>
instead of the double-quoted form. I find other instances of this bug in the following files:
> grep '"mpi.h"' *h
Epetra_Time.h:#include "mpi.h"
MLAPI_Workspace.h:#include "mpi.h"
ml_epetra_utils.h:#include "mpi.h"
ml_smoother.h:#include "mpi.h"
These are all bugs waiting to happen.