From 71512f5682422008828921aa30ad7fddb2f07246 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Mon, 30 Dec 2024 23:42:16 +0100 Subject: [PATCH] mpich: gather in a single place env modifications needed by mpich derivatives (#48276) * mpich: gather in a single place env modifications needed by mpich derivatives MPICH, and its derivatives, share a lot of copy/paste code to setup the environment during the different stages of the package life-cycle. This commit gathers the common modifications in a single place (a mixin class), living in the Mpich package, and makes derivatives import, and reuse, it. * Fix docs for Python < 3.13 --- lib/spack/docs/packaging_guide.rst | 12 +-- .../builtin/packages/cray-mpich/package.py | 30 ++----- .../builtin/packages/cray-mvapich2/package.py | 30 ++----- .../repos/builtin/packages/mpich/package.py | 83 ++++++++++++------- .../repos/builtin/packages/mvapich/package.py | 48 ++--------- .../builtin/packages/mvapich2-gdr/package.py | 31 ++----- .../builtin/packages/mvapich2/package.py | 47 ++--------- .../builtin/packages/mvapich2x/package.py | 34 ++------ 8 files changed, 98 insertions(+), 217 deletions(-) diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst index b44bded2ba9..5879d213da0 100644 --- a/lib/spack/docs/packaging_guide.rst +++ b/lib/spack/docs/packaging_guide.rst @@ -4900,15 +4900,15 @@ If your package has a virtual dependency like ``mpi``, then referring to ``spec["mpi"]`` within ``install()`` will get you the concrete ``mpi`` implementation in your dependency DAG. That is a spec object just like the one passed to install, only the MPI implementations all set some -additional properties on it to help you out. E.g., in mvapich2, you'll +additional properties on it to help you out. E.g., in openmpi, you'll find this: -.. literalinclude:: _spack_root/var/spack/repos/builtin/packages/mvapich2/package.py - :pyobject: Mvapich2.setup_dependent_package +.. literalinclude:: _spack_root/var/spack/repos/builtin/packages/openmpi/package.py + :pyobject: Openmpi.setup_dependent_package -That code allows the mvapich2 package to associate an ``mpicc`` property -with the ``mvapich2`` node in the DAG, so that dependents can access it. -``openmpi`` and ``mpich`` do similar things. So, no matter what MPI +That code allows the ``openmpi`` package to associate an ``mpicc`` property +with the ``openmpi`` node in the DAG, so that dependents can access it. +``mvapich2`` and ``mpich`` do similar things. So, no matter what MPI you're using, spec["mpi"].mpicc gets you the location of the MPI compilers. This allows us to have a fairly simple polymorphic interface for information about virtual dependencies like MPI. diff --git a/var/spack/repos/builtin/packages/cray-mpich/package.py b/var/spack/repos/builtin/packages/cray-mpich/package.py index d0dd2005c90..ca66786066c 100644 --- a/var/spack/repos/builtin/packages/cray-mpich/package.py +++ b/var/spack/repos/builtin/packages/cray-mpich/package.py @@ -6,10 +6,11 @@ import os from spack.package import * +from spack.pkg.builtin.mpich import MpichEnvironmentModifications from spack.util.module_cmd import get_path_args_from_module_line, module -class CrayMpich(Package): +class CrayMpich(MpichEnvironmentModifications, Package): """Cray's MPICH is a high performance and widely portable implementation of the Message Passing Interface (MPI) standard.""" @@ -72,31 +73,18 @@ def external_prefix(self): def setup_run_environment(self, env): if self.spec.satisfies("+wrappers"): - env.set("MPICC", join_path(self.prefix.bin, "mpicc")) - env.set("MPICXX", join_path(self.prefix.bin, "mpicxx")) - env.set("MPIF77", join_path(self.prefix.bin, "mpif77")) - env.set("MPIF90", join_path(self.prefix.bin, "mpif90")) - elif spack_cc is not None: - env.set("MPICC", spack_cc) - env.set("MPICXX", spack_cxx) - env.set("MPIF77", spack_fc) - env.set("MPIF90", spack_fc) + self.setup_mpi_wrapper_variables(env) + return - def setup_dependent_build_environment(self, env, dependent_spec): - dependent_module = dependent_spec.package.module - env.set("MPICH_CC", dependent_module.spack_cc) - env.set("MPICH_CXX", dependent_module.spack_cxx) - env.set("MPICH_F77", dependent_module.spack_f77) - env.set("MPICH_F90", dependent_module.spack_fc) - env.set("MPICH_FC", dependent_module.spack_fc) + env.set("MPICC", self.compiler.cc) + env.set("MPICXX", self.compiler.cxx) + env.set("MPIFC", self.compiler.fc) + env.set("MPIF77", self.compiler.f77) def setup_dependent_package(self, module, dependent_spec): spec = self.spec if spec.satisfies("+wrappers"): - spec.mpicc = join_path(self.prefix.bin, "mpicc") - spec.mpicxx = join_path(self.prefix.bin, "mpicxx") - spec.mpifc = join_path(self.prefix.bin, "mpif90") - spec.mpif77 = join_path(self.prefix.bin, "mpif77") + MpichEnvironmentModifications.setup_dependent_package(self, module, dependent_spec) elif spack_cc is not None: spec.mpicc = spack_cc spec.mpicxx = spack_cxx diff --git a/var/spack/repos/builtin/packages/cray-mvapich2/package.py b/var/spack/repos/builtin/packages/cray-mvapich2/package.py index 6cf9b37615b..d01c3504952 100644 --- a/var/spack/repos/builtin/packages/cray-mvapich2/package.py +++ b/var/spack/repos/builtin/packages/cray-mvapich2/package.py @@ -4,9 +4,10 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) from spack.package import * +from spack.pkg.builtin.mpich import MpichEnvironmentModifications -class CrayMvapich2(Package): +class CrayMvapich2(MpichEnvironmentModifications, Package): """Cray/HPE packaging of MVAPICH2 for HPE Apollo systems""" homepage = "https://docs.nersc.gov/development/compilers/wrappers/" @@ -29,29 +30,10 @@ class CrayMvapich2(Package): requires("platform=linux", msg="Cray MVAPICH2 is only available on Cray") def setup_run_environment(self, env): - if spack_cc is None: - return - - env.set("MPICC", spack_cc) - env.set("MPICXX", spack_cxx) - env.set("MPIF77", spack_fc) - env.set("MPIF90", spack_fc) - - def setup_dependent_build_environment(self, env, dependent_spec): - dependent_module = dependent_spec.package.module - env.set("MPICH_CC", dependent_module.spack_cc) - env.set("MPICH_CXX", dependent_module.spack_cxx) - env.set("MPICH_F77", dependent_module.spack_f77) - env.set("MPICH_F90", dependent_module.spack_fc) - env.set("MPICH_FC", dependent_module.spack_fc) - - def setup_dependent_package(self, module, dependent_spec): - spec = self.spec - dependent_module = dependent_spec.package.module - spec.mpicc = dependent_module.spack_cc - spec.mpicxx = dependent_module.spack_cxx - spec.mpifc = dependent_module.spack_fc - spec.mpif77 = dependent_module.spack_f77 + env.set("MPICC", self.compiler.cc) + env.set("MPICXX", self.compiler.cxx) + env.set("MPIFC", self.compiler.fc) + env.set("MPIF77", self.compiler.f77) def install(self, spec, prefix): raise InstallError( diff --git a/var/spack/repos/builtin/packages/mpich/package.py b/var/spack/repos/builtin/packages/mpich/package.py index be6caf0050e..86a2b95656a 100644 --- a/var/spack/repos/builtin/packages/mpich/package.py +++ b/var/spack/repos/builtin/packages/mpich/package.py @@ -8,10 +8,58 @@ import sys import spack.compilers +import spack.package_base from spack.package import * -class Mpich(AutotoolsPackage, CudaPackage, ROCmPackage): +class MpichEnvironmentModifications(spack.package_base.PackageBase): + """Collects the environment modifications that are usually needed for the life-cycle of + MPICH, and derivatives. + """ + + def setup_dependent_build_environment(self, env, dependent_spec): + dependent_module = dependent_spec.package.module + for var_name, attr_name in ( + ("MPICH_CC", "spack_cc"), + ("MPICH_CXX", "spack_cxx"), + ("MPICH_FC", "spack_fc"), + ("MPICH_F90", "spack_fc"), + ("MPICH_F77", "spack_f77"), + ): + if not hasattr(dependent_module, attr_name): + continue + + env.set(var_name, getattr(dependent_module, attr_name)) + + def setup_build_environment(self, env): + env.unset("F90") + env.unset("F90FLAGS") + + def setup_run_environment(self, env): + self.setup_mpi_wrapper_variables(env) + + def setup_dependent_package(self, module, dependent_spec): + spec = self.spec + spec.mpicc = join_path(self.prefix.bin, "mpicc") + spec.mpicxx = join_path(self.prefix.bin, "mpicxx") + # Some derived packages define the "fortran" variant, most don't. Checking on the + # presence of ~fortran makes us default to add fortran wrappers if the variant is + # not declared. + if spec.satisfies("~fortran"): + return + spec.mpifc = join_path(self.prefix.bin, "mpif90") + spec.mpif77 = join_path(self.prefix.bin, "mpif77") + + def setup_mpi_wrapper_variables(self, env): + # Because MPI implementations provide compilers, they have to add to + # their run environments the code to make the compilers available. + env.set("MPICC", join_path(self.prefix.bin, "mpicc")) + env.set("MPICXX", join_path(self.prefix.bin, "mpicxx")) + env.set("MPIF77", join_path(self.prefix.bin, "mpif77")) + env.set("MPIF90", join_path(self.prefix.bin, "mpif90")) + + +class Mpich(MpichEnvironmentModifications, AutotoolsPackage, CudaPackage, ROCmPackage): """MPICH is a high performance and widely portable implementation of the Message Passing Interface (MPI) standard.""" @@ -448,39 +496,11 @@ def flag_handler(self, name, flags): return flags, None, None def setup_build_environment(self, env): - env.unset("F90") - env.unset("F90FLAGS") - + MpichEnvironmentModifications.setup_build_environment(self, env) if "pmi=cray" in self.spec: env.set("CRAY_PMI_INCLUDE_OPTS", "-I" + self.spec["cray-pmi"].headers.directories[0]) env.set("CRAY_PMI_POST_LINK_OPTS", "-L" + self.spec["cray-pmi"].libs.directories[0]) - def setup_run_environment(self, env): - # Because MPI implementations provide compilers, they have to add to - # their run environments the code to make the compilers available. - env.set("MPICC", join_path(self.prefix.bin, "mpicc")) - env.set("MPICXX", join_path(self.prefix.bin, "mpic++")) - env.set("MPIF77", join_path(self.prefix.bin, "mpif77")) - env.set("MPIF90", join_path(self.prefix.bin, "mpif90")) - - def setup_dependent_build_environment(self, env, dependent_spec): - dependent_module = dependent_spec.package.module - env.set("MPICH_CC", dependent_module.spack_cc) - env.set("MPICH_CXX", dependent_module.spack_cxx) - env.set("MPICH_F77", dependent_module.spack_f77) - env.set("MPICH_F90", dependent_module.spack_fc) - env.set("MPICH_FC", dependent_module.spack_fc) - - def setup_dependent_package(self, module, dependent_spec): - spec = self.spec - - spec.mpicc = join_path(self.prefix.bin, "mpicc") - spec.mpicxx = join_path(self.prefix.bin, "mpic++") - - if "+fortran" in spec: - spec.mpifc = join_path(self.prefix.bin, "mpif90") - spec.mpif77 = join_path(self.prefix.bin, "mpif77") - def autoreconf(self, spec, prefix): """Not needed usually, configure should be already there""" # If configure exists nothing needs to be done @@ -543,8 +563,7 @@ def configure_args(self): ) ) - if "~fortran" in spec: - config_args.append("--disable-fortran") + config_args.extend(self.enable_or_disable("fortran")) if "+slurm" in spec: config_args.append("--with-slurm=yes") diff --git a/var/spack/repos/builtin/packages/mvapich/package.py b/var/spack/repos/builtin/packages/mvapich/package.py index 88d33c626f1..e5624b287d5 100644 --- a/var/spack/repos/builtin/packages/mvapich/package.py +++ b/var/spack/repos/builtin/packages/mvapich/package.py @@ -8,9 +8,10 @@ import sys from spack.package import * +from spack.pkg.builtin.mpich import MpichEnvironmentModifications -class Mvapich(AutotoolsPackage): +class Mvapich(MpichEnvironmentModifications, AutotoolsPackage): """Mvapich is a High-Performance MPI Library for clusters with diverse networks (InfiniBand, Omni-Path, Ethernet/iWARP, and RoCE) and computing platforms (x86 (Intel and AMD), ARM and OpenPOWER)""" @@ -28,9 +29,9 @@ class Mvapich(AutotoolsPackage): # Prefer the latest stable release version("3.0", sha256="ee076c4e672d18d6bf8dd2250e4a91fa96aac1db2c788e4572b5513d86936efb") - depends_on("c", type="build") # generated - depends_on("cxx", type="build") # generated - depends_on("fortran", type="build") # generated + depends_on("c", type="build") + depends_on("cxx", type="build") + depends_on("fortran", type="build") provides("mpi") provides("mpi@:3.1") @@ -207,48 +208,15 @@ def flag_handler(self, name, flags): return (flags, None, None) - def setup_build_environment(self, env): - # mvapich2 configure fails when F90 and F90FLAGS are set - env.unset("F90") - env.unset("F90FLAGS") - def setup_run_environment(self, env): env.set("MPI_ROOT", self.prefix) - # Because MPI functions as a compiler, we need to treat it as one and # add its compiler paths to the run environment. - self.setup_compiler_environment(env) + self.setup_mpi_wrapper_variables(env) def setup_dependent_build_environment(self, env, dependent_spec): - self.setup_compiler_environment(env) - - # use the Spack compiler wrappers under MPI - dependent_module = dependent_spec.package.module - env.set("MPICH_CC", dependent_module.spack_cc) - env.set("MPICH_CXX", dependent_module.spack_cxx) - env.set("MPICH_F77", dependent_module.spack_f77) - env.set("MPICH_F90", dependent_module.spack_fc) - env.set("MPICH_FC", dependent_module.spack_fc) - - def setup_compiler_environment(self, env): - env.set("MPICC", join_path(self.prefix.bin, "mpicc")) - env.set("MPICXX", join_path(self.prefix.bin, "mpicxx")) - env.set("MPIF77", join_path(self.prefix.bin, "mpif77")) - env.set("MPIF90", join_path(self.prefix.bin, "mpif90")) - - def setup_dependent_package(self, module, dependent_spec): - self.spec.mpicc = join_path(self.prefix.bin, "mpicc") - self.spec.mpicxx = join_path(self.prefix.bin, "mpicxx") - self.spec.mpifc = join_path(self.prefix.bin, "mpif90") - self.spec.mpif77 = join_path(self.prefix.bin, "mpif77") - - @run_before("configure") - def die_without_fortran(self): - # Until we can pass variants such as +fortran through virtual - # dependencies depends_on('mpi'), require Fortran compiler to - # avoid delayed build errors in dependents. - if (self.compiler.f77 is None) or (self.compiler.fc is None): - raise InstallError("Mvapich2 requires both C and Fortran compilers!") + self.setup_mpi_wrapper_variables(env) + MpichEnvironmentModifications.setup_dependent_build_environment(self, env, dependent_spec) def configure_args(self): spec = self.spec diff --git a/var/spack/repos/builtin/packages/mvapich2-gdr/package.py b/var/spack/repos/builtin/packages/mvapich2-gdr/package.py index 6221e548dac..457194909ab 100755 --- a/var/spack/repos/builtin/packages/mvapich2-gdr/package.py +++ b/var/spack/repos/builtin/packages/mvapich2-gdr/package.py @@ -6,9 +6,10 @@ import sys from spack.package import * +from spack.pkg.builtin.mpich import MpichEnvironmentModifications -class Mvapich2Gdr(AutotoolsPackage): +class Mvapich2Gdr(MpichEnvironmentModifications, AutotoolsPackage): """MVAPICH2-GDR is an optimized version of the MVAPICH2 MPI library for GPU-enabled HPC and Deep Learning Applications. MVAPICH2-GDR is not installable from source and is only available through a binary mirror. @@ -146,11 +147,6 @@ def process_manager_options(self): ) return opts - def setup_build_environment(self, env): - # mvapich2 configure fails when F90 and F90FLAGS are set - env.unset("F90") - env.unset("F90FLAGS") - def setup_run_environment(self, env): if "pmi_version=pmi1" in self.spec: env.set("SLURM_MPI_TYPE", "pmi1") @@ -161,28 +157,11 @@ def setup_run_environment(self, env): # Because MPI functions as a compiler, we need to treat it as one and # add its compiler paths to the run environment. - self.setup_compiler_environment(env) + self.setup_mpi_wrapper_variables(env) def setup_dependent_build_environment(self, env, dependent_spec): - self.setup_compiler_environment(env) - dependent_module = dependent_spec.package.module - env.set("MPICH_CC", dependent_module.spack_cc) - env.set("MPICH_CXX", dependent_module.spack_cxx) - env.set("MPICH_F77", dependent_module.spack_f77) - env.set("MPICH_F90", dependent_module.spack_fc) - env.set("MPICH_FC", dependent_module.spack_fc) - - def setup_compiler_environment(self, env): - env.set("MPICC", join_path(self.prefix.bin, "mpicc")) - env.set("MPICXX", join_path(self.prefix.bin, "mpicxx")) - env.set("MPIF77", join_path(self.prefix.bin, "mpif77")) - env.set("MPIF90", join_path(self.prefix.bin, "mpif90")) - - def setup_dependent_package(self, module, dependent_spec): - self.spec.mpicc = join_path(self.prefix.bin, "mpicc") - self.spec.mpicxx = join_path(self.prefix.bin, "mpicxx") - self.spec.mpifc = join_path(self.prefix.bin, "mpif90") - self.spec.mpif77 = join_path(self.prefix.bin, "mpif77") + self.setup_mpi_wrapper_variables(env) + MpichEnvironmentModifications.setup_dependent_build_environment(self, env, dependent_spec) def configure_args(self): spec = self.spec diff --git a/var/spack/repos/builtin/packages/mvapich2/package.py b/var/spack/repos/builtin/packages/mvapich2/package.py index 63aad00a522..fd3ea5b0ceb 100644 --- a/var/spack/repos/builtin/packages/mvapich2/package.py +++ b/var/spack/repos/builtin/packages/mvapich2/package.py @@ -9,9 +9,10 @@ import spack.compilers from spack.package import * +from spack.pkg.builtin.mpich import MpichEnvironmentModifications -class Mvapich2(AutotoolsPackage): +class Mvapich2(MpichEnvironmentModifications, AutotoolsPackage): """Mvapich2 is a High-Performance MPI Library for clusters with diverse networks (InfiniBand, Omni-Path, Ethernet/iWARP, and RoCE) and computing platforms (x86 (Intel and AMD), ARM and OpenPOWER)""" @@ -40,9 +41,9 @@ class Mvapich2(AutotoolsPackage): version("2.2", sha256="791a6fc2b23de63b430b3e598bf05b1b25b82ba8bf7e0622fc81ba593b3bb131") version("2.1", sha256="49f3225ad17d2f3b6b127236a0abdc979ca8a3efb8d47ab4b6cd4f5252d05d29") - depends_on("c", type="build") # generated - depends_on("cxx", type="build") # generated - depends_on("fortran", type="build") # generated + depends_on("c", type="build") + depends_on("cxx", type="build") + depends_on("fortran", type="build") provides("mpi") provides("mpi@:3.1", when="@2.3:") @@ -358,11 +359,6 @@ def flag_handler(self, name, flags): return (flags, None, None) - def setup_build_environment(self, env): - # mvapich2 configure fails when F90 and F90FLAGS are set - env.unset("F90") - env.unset("F90FLAGS") - def setup_run_environment(self, env): if "process_managers=slurm" in self.spec: if "pmi_version=pmi1" in self.spec: @@ -373,40 +369,13 @@ def setup_run_environment(self, env): env.set("SLURM_MPI_TYPE", "pmix") env.set("MPI_ROOT", self.prefix) - # Because MPI functions as a compiler, we need to treat it as one and # add its compiler paths to the run environment. - self.setup_compiler_environment(env) + self.setup_mpi_wrapper_variables(env) def setup_dependent_build_environment(self, env, dependent_spec): - self.setup_compiler_environment(env) - # use the Spack compiler wrappers under MPI - dependent_module = dependent_spec.package.module - env.set("MPICH_CC", dependent_module.spack_cc) - env.set("MPICH_CXX", dependent_module.spack_cxx) - env.set("MPICH_F77", dependent_module.spack_f77) - env.set("MPICH_F90", dependent_module.spack_fc) - env.set("MPICH_FC", dependent_module.spack_fc) - - def setup_compiler_environment(self, env): - env.set("MPICC", join_path(self.prefix.bin, "mpicc")) - env.set("MPICXX", join_path(self.prefix.bin, "mpicxx")) - env.set("MPIF77", join_path(self.prefix.bin, "mpif77")) - env.set("MPIF90", join_path(self.prefix.bin, "mpif90")) - - def setup_dependent_package(self, module, dependent_spec): - self.spec.mpicc = join_path(self.prefix.bin, "mpicc") - self.spec.mpicxx = join_path(self.prefix.bin, "mpicxx") - self.spec.mpifc = join_path(self.prefix.bin, "mpif90") - self.spec.mpif77 = join_path(self.prefix.bin, "mpif77") - - @run_before("configure") - def die_without_fortran(self): - # Until we can pass variants such as +fortran through virtual - # dependencies depends_on('mpi'), require Fortran compiler to - # avoid delayed build errors in dependents. - if (self.compiler.f77 is None) or (self.compiler.fc is None): - raise InstallError("Mvapich2 requires both C and Fortran compilers!") + self.setup_mpi_wrapper_variables(env) + MpichEnvironmentModifications.setup_dependent_build_environment(self, env, dependent_spec) def configure_args(self): spec = self.spec diff --git a/var/spack/repos/builtin/packages/mvapich2x/package.py b/var/spack/repos/builtin/packages/mvapich2x/package.py index 660a2e5e057..8896c7687a5 100644 --- a/var/spack/repos/builtin/packages/mvapich2x/package.py +++ b/var/spack/repos/builtin/packages/mvapich2x/package.py @@ -6,9 +6,10 @@ import sys from spack.package import * +from spack.pkg.builtin.mpich import MpichEnvironmentModifications -class Mvapich2x(AutotoolsPackage): +class Mvapich2x(MpichEnvironmentModifications, AutotoolsPackage): """MVAPICH2-X is the advanced version of the MVAPICH2 MPI library with enhanced features (UMR, ODP, DC, Core-Direct, SHARP, XPMEM), OSU INAM (InifniBand Network Monitoring and Analysis),PGAS (OpenSHMEM, UPC, UPC++, @@ -198,11 +199,6 @@ def construct_cflags(self): cflags = cflags + "-I/opt/xpmem/include" return cflags - def setup_build_environment(self, env): - # mvapich2 configure fails when F90 and F90FLAGS are set - env.unset("F90") - env.unset("F90FLAGS") - def setup_run_environment(self, env): if "pmi_version=pmi1" in self.spec: env.set("SLURM_MPI_TYPE", "pmi1") @@ -213,31 +209,11 @@ def setup_run_environment(self, env): # Because MPI functions as a compiler, we need to treat it as one and # add its compiler paths to the run environment. - self.setup_compiler_environment(env) + self.setup_mpi_wrapper_variables(env) def setup_dependent_build_environment(self, env, dependent_spec): - self.setup_compiler_environment(env) - # use the Spack compiler wrappers under MPI - dependent_module = dependent_spec.package.module - env.set("MPICH_CC", dependent_module.spack_cc) - env.set("MPICH_CXX", dependent_module.spack_cxx) - env.set("MPICH_F77", dependent_module.spack_f77) - env.set("MPICH_F90", dependent_module.spack_fc) - env.set("MPICH_FC", dependent_module.spack_fc) - - def setup_compiler_environment(self, env): - # For Cray MPIs, the regular compiler wrappers *are* the MPI wrappers. - # Cray MPIs always have cray in the module name, e.g. "cray-mvapich" - env.set("MPICC", join_path(self.prefix.bin, "mpicc")) - env.set("MPICXX", join_path(self.prefix.bin, "mpicxx")) - env.set("MPIF77", join_path(self.prefix.bin, "mpif77")) - env.set("MPIF90", join_path(self.prefix.bin, "mpif90")) - - def setup_dependent_package(self, module, dependent_spec): - self.spec.mpicc = join_path(self.prefix.bin, "mpicc") - self.spec.mpicxx = join_path(self.prefix.bin, "mpicxx") - self.spec.mpifc = join_path(self.prefix.bin, "mpif90") - self.spec.mpif77 = join_path(self.prefix.bin, "mpif77") + self.setup_mpi_wrapper_variables(env) + MpichEnvironmentModifications.setup_dependent_build_environment(self, env, dependent_spec) def configure_args(self): spec = self.spec