Take a look at the MPI section of the packaging guide for the finer points of how MPI wrappers are handled:
#1 is just what the build system outputs. In the build environment we set MPICH_CC, and it points to the Spack compiler wrappers, which are all the symlinks in subdirectories of lib/spack/env in your spack installation. All those symlinks point
to lib/spack/env/cc, which is the wrapper:
And it looks like we write the real compiler out for both the input and the output, which isn’t quite right. In the input, what’s really being invoked is the compiler wrapper. The files are really designed so that you can diff them and see what
the wrappers are adding.
Anyway, short story is that your mpicc ends up invoking our wrappers, which invoke the real compiler with some flags added for the uarch and RPATHs. It allows us to inject flags into many builds, and it makes it much harder for a build system
to accidentally include things from outside of the package’s dependencies. It will also hopefully in the future allow us to more easily do t-san, a-san, etc. builds, and to inject tools into builds.
I agree it’s confusing that the way we do this doesn’t end up printing the uarch flags on the compile line output by the build, but it’s a tradeoff for generality. If we sent the flags through the build system, packagers would need to do more
work to ensure that happens. You *can* pass flags that way:
But this is package-specific, and we don’t currently pass the uarch flags that way — they’re still done by the compiler wrappers.
-Todd