aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsbronder <jsbronder@32389bae-6d03-0410-99cf-db05cde120eb>2009-01-14 02:15:21 +0000
committerjsbronder <jsbronder@32389bae-6d03-0410-99cf-db05cde120eb>2009-01-14 02:15:21 +0000
commit82d8c8febd94f7eecfe09a06270b50f6f97ec9f6 (patch)
tree89d3e3624809203c3d71e756322fa33c9c12eda7 /eclass/mpi.eclass
parentFinite state toolkit foma. Initial ebuild. (diff)
downloadsci-82d8c8febd94f7eecfe09a06270b50f6f97ec9f6.tar.gz
sci-82d8c8febd94f7eecfe09a06270b50f6f97ec9f6.tar.bz2
sci-82d8c8febd94f7eecfe09a06270b50f6f97ec9f6.zip
Update mpi.eclass. Major changes include simplyfing use and allowing non empi builds to still get some information. Also updated all related packages using this eclass.
git-svn-id: http://overlays.gentoo.org/svn/proj/science/overlay@1367 32389bae-6d03-0410-99cf-db05cde120eb
Diffstat (limited to 'eclass/mpi.eclass')
-rw-r--r--eclass/mpi.eclass636
1 files changed, 288 insertions, 348 deletions
diff --git a/eclass/mpi.eclass b/eclass/mpi.eclass
index 3692a0313..29d8629b1 100644
--- a/eclass/mpi.eclass
+++ b/eclass/mpi.eclass
@@ -2,351 +2,103 @@
# Distributed under the terms of the GNU General Public License v2
# $Header: $
-# Description: This eclass is used to allow for the separation of mpi
-# implementations and dependant programs/libraries in
-# /usr/lib/mpi/<implementation>.
-#
-# Author(s): Justin Bronder <jsbronder@gentoo.org>
-#
-# Basic idea is directly stolen from crossdev and hence really relies on using
-# sys-cluster/empi. EmergeMPI basically creates new categories, pulls in a
-# single MPI providing ebuild that uses this eclass and builds. This eclass
-# handles pushing the entire install to a save place, /usr/lib/mpi/<name>.
-# Packages that depend on MPI can also use this eclass to get installed to
-# the same place using the correct MPI implementation.
-
-# Currently only autotools-enabled packages are handled with any sort of
-# elegance, and dealing with the standard Makefile-style builds that
-# are typical in hpc probably can't be made much easier.
-
-# NOTE: If using this eclass to build an implementation, you need to define
-# MPI_ESELECT_FILE which is the path relative to FILESDIR where the eselect
-# definition file can be found.
-
-
-# FUNCTIONS, at least those that are worth caring about!
-
-# mpi_src_compile: For each implementation, set $S correctly and then run
-# through do_config and do_make. Finally restore $S
-
-# mpi_src_install: For each implementation, set $S correctly, run
-# do_make_install and restore $S.
-
-# mpi_pkg_deplist: Prints deps for mpi enabled packages. Basically if using
-# empi, then we dep on empi-enabled implementations,
-# otherwise, the dep is just on virtual/mpi
-
-# mpi_imp_deplist: Prints deps for mpi implementations. As empi guarantees
-# blockers cannot be installed at the same root, this deps
-# on eselect-mpi for empi builds. Otherwise, prints a list
-# of blockers (all other mpi implementations).
-
-# mpi_built_with: Get the ${PN} of the implementation that was used to get
-# mpicc etc.
-
-# get_mpi_dir: Given an implementation, returns the base directory to
-# that programs should install to. I.E. --prefix for
-# autoconf.
-
-# is_empi_build: Are we building with empi? [[ ${CATEGORY} == mpi-* ]] as
-# empi forces this just so we can do that.
-
-# FUNCTIONS, directly used by the above interesting ones.
-
-# mpi_set_env <imp>: For lack of a better name, just exports the following based
-# on the desired implementation: CC, CXX, F77, FC, PATH
-# Set $mpi_env to "mpi_none" to ensure that this function
-# is not called.
-
-# mpi_restore_env: Undo the above.
-
-# For the following functions and those that call them, I've used indirect
-# referencing to allow for a clean way to have both defaults and to allow
-# different actions to be taken per implementation. Preference is given first
-# to ${implementation}_${var}, then mpi_${var} and finally defaults will be
-# used. All variables also allow "mpi_none", which disables that action.
-#
-# *_conf_cmd: configure command, default: econf
-# *_conf_args: configure arguments, no default
-# HOWEVER, note that prefix, mandir, infodir and datadir are
-# set if ${S}/configure is executable. Pass "mpi_none" to
-# disable this.
-# *_make_cmd: make command, default emake
-# *_make_args: make arguments, no default
-# *_make_install_cmd: make install command, default emake
-# *_make_install_args: make install arguments, default 'DESTDIR=${D} install'
-
-
-
-# mpi_do_config: $S should be set correctly to some ${P}-${imp}. Changes to
-# that dir, calls mpi_set_env, $conf_cmd $conf_args, and
-# rcalls mpi_restore_env.
-
-# mpi_do_make: Same as above but for building.
-# mpi_do_make_install: Same as above but for installing.
-
-
-# Variables:
-# MPI_ESELECT_FILE: Name of the eselect file in ${FILESDIR}
-# MPI_NOEMPI_BLOCKERS: String of packages we should block against if not using
-# empi. See mpich2 and mpd.
-# MPI_EMPI_COMPAT: String of all base implementations that this package
-# works with. See __MPI_EMPI_COMPAT, this is a list of
-# [><=]${PN}-${PVR} put into DEPEND with ||.
-
-inherit multilib flag-o-matic
-
-__MPI_EMPI_COMPAT="
- >=openmpi-1.2.5-r1
- >=lam-mpi-7.1.4-r1
- >=openib-mvapich2-1.0.1-r1
- >=mpich2-1.0.8"
-MPI_ALL_IMPS="mpich mpich2 openmpi lam-mpi openib-mvapich2"
-
-MPI_EMPI_COMPAT="${MPI_EMPI_COMPAT:-${__MPI_EMPI_COMPAT}}"
-#TODO: doc
-mpi_pkg_deplist() {
- local i ver
- if [ -z "$(get_imp)" ]; then
- ver="virtual/mpi"
- for i in ${MPI_NOEMPI_BLOCKERS}; do
- ver="${ver} !${i}"
- done
- else
- for i in ${MPI_EMPI_COMPAT}; do
- ver="${ver} ${CATEGORY}/${i}"
- done
- ver="|| (${ver} ) app-admin/eselect-mpi"
- fi
- echo "${ver}"
-}
+inherit multilib
-mpi_imp_deplist() {
- local i ver
- if ! is_empi_imp_build; then
- for i in ${MPI_ALL_IMPS}; do
- [ "${i}" != "${PN}" ] && ver="${ver} !sys-cluster/${i}"
- done
- for i in ${MPI_NOEMPI_BLOCKERS}; do
- ver="${ver} !${i}"
- done
- else
- ver="app-admin/eselect-mpi"
- fi
- echo "${ver}"
-}
+# @ECLASS: mpi.eclass
+# @MAINTAINER:
+# Justin Bronder <jsbronder@gentoo.org>
+# @BLURB: Common functions for mpi-pkg.eclass and mpi-imp.eclass
-is_imp_build() { [[ ${MPI_ALL_IMPS} == *${PN}* ]]; }
-is_empi_build() { [[ ${CATEGORY} == mpi-* ]]; }
-is_empi_imp_build() { is_imp_build && is_empi_build; }
+# History: (Is there a standard for this?)
+# 2008-11-20 (jsbronder): Initial rewrite from old mpi.eclass
-get_imp() {
- [[ ${CATEGORY} == mpi-* ]] && echo "${CATEGORY}"
-}
+#####################
+# Private Variables #
+#####################
-get_mpi_dir() {
- if is_empi_build; then
- echo "/usr/$(get_libdir)/mpi/${MPI_IMP}"
- fi
-}
+# All known mpi implementations
+__MPI_ALL_IMPLEMENTATION_PNS="mpich mpich2 openmpi lam-mpi openib-mvapich2"
+# All mpi implentations that can be classed.
+__MPI_ALL_CLASSABLE_PNS="openmpi mpich2 lam-mpi"
-get_eselect_var() { echo "$(eselect mpi printvar ${MPI_IMP} ${1})"; }
-mpi_built_with() { echo "$(get_eselect_var MPI_BUILT_WITH)"; }
-# Internal use: Get out of messy functions if we're not using empi to build and
-# therefore avoid tons of file collisions.
-bail_if_not_empi() { [ -z "${MPI_IMP}" ] && return 0; }
-#TODO: There must be a better way?
-# Currently can be turned off with mpi_env="mpi_none"
-mpi_set_env() {
- local p
- [ -z "${MPI_IMP}" ] && return 0
- is_empi_imp_build && return 0
- [[ ${mpi_env} == mpi_none ]] && return 0
+###################################################################
+# Generic Functions that are used by Implementations and Packages #
+###################################################################
- p="$(get_mpi_dir)"
-
- oCC=$CC
- oCXX=$CXX
- oF77=$F77
- oFC=$FC
- oPATH=$PATH
- oLLP=${LD_LIBRARY_PATH}
- export CC=$(get_eselect_var MPI_CC)
- export CXX=$(get_eselect_var MPI_CXX)
- export F77=$(get_eselect_var MPI_F77)
- export FC=$(get_eselect_var MPI_F90)
- export PATH="$(get_eselect_var PATH):${PATH}"
- export LD_LIBRARY_PATH="$(get_eselect_var LD_LIBRARY_PATH):${LD_LIBRARY_PATH}"
-# Handled by the wrappers, at least it better be.
-# append-ldflags $(eselect mpi ldflags ${MPI_IMP})
-# append-flags $(eselect mpi cflags ${MPI_IMP})
-}
+# @ECLASS-VARIABLE: MPI_UNCLASSED_BLOCKERS
+# @DESCRIPTION: Packages that are blockers when not using a classed install.
-mpi_restore_env() {
- [ -z "${MPI_IMP}" ] && return 0
- is_empi_imp_build && return 0
- [[ ${mpi_env} == mpi_none ]] && return 0
-
- export CC=$oCC
- export CXX=$oCXX
- export F77=$oF77
- export FC=$oFC
- export PATH=$oPATH
- export LD_LIBRARY_PATH=$oLLP
+# @FUNCTION: mpi_classed
+# @USAGE:
+# @RETURN: True if this build is classed.
+mpi_classed() {
+ [[ ${CATEGORY} == mpi-* ]]
}
-
-# Here's what we try to get, in order.
-# ${IMP_BUILT_WITH}_${var}
-# mpi_${var}
-get_mpi_var() {
- local varname=${1}
- local t ret
-
- if is_imp_build; then
- t="${PN}_${varname}"
- elif is_empi_build; then
- t=$(mpi_built_with)
- t=${t%%-[0-9]*}
- t="${t}_${varname}"
- fi
- [ -n "${t}" ] && ret="${!t}"
-
- if [ -z "${ret}" ]; then
- t="mpi_${varname}"
- ret=${!t}
- fi
-
- if [ -z "${ret}" ]; then
- case ${varname} in
- conf_cmd)
- ret="econf"
- ;;
- make_cmd|make_install_cmd)
- ret="emake"
- ;;
- esac
- fi
- echo "${ret}"
+# @FUNCTION: mpi_class
+# @USAGE:
+# @RETURN: The name of the current class, or nothing if unclassed.
+mpi_class() {
+ mpi_classed && echo "${CATEGORY}"
}
-mpi_do_config() {
- local conf_cmd=$(get_mpi_var "conf_cmd")
- local conf_args=$(get_mpi_var "conf_args")
- local default_args rc d
-
- d="$(get_mpi_dir)"
- [[ "${conf_cmd}" == "mpi_none" ]] && return 0
- [[ -x ${S}/configure && -n "${MPI_IMP}" ]] \
- && default_args="--prefix=${d}/usr/
- --mandir=${d}/usr/share/man
- --infodir=${d}/usr/share/info
- --datadir=${d}/usr/share/
- --sysconfdir=/etc/${MPI_IMP}/
- --localstatedir=/var/lib/${MPI_IMP}"
- [[ "${conf_args}" == *mpi_none* ]] && default_args=""
-
- mpi_set_env
- ${conf_cmd} ${default_args} ${conf_args}; rc=$?
- mpi_restore_env
- return ${rc}
-}
-
-mpi_do_make() {
- local make_cmd=$(get_mpi_var "make_cmd")
- local make_args=$(get_mpi_var "make_args")
- local rc
-
- [[ "${make_cmd}" == "mpi_none" ]] && return 0
-
- mpi_set_env
- ${make_cmd} ${make_args}; rc=$?
- mpi_restore_env
- return ${rc}
-}
-
-
-mpi_do_make_install() {
- local make_cmd=$(get_mpi_var "make_install_cmd")
- local make_args=$(get_mpi_var "make_install_args")
- local default_args="DESTDIR=\"${D}\" install"
- local rc
-
- [[ "${make_cmd}" == "mpi_none" ]] && return 0
- [[ "${make_args}" == "mpi_none" ]] && default_args=""
-
- mpi_set_env
- ${make_cmd} ${default_args} ${make_args}; rc=$?
- mpi_restore_env
- return ${rc}
-}
-
-mpi_src_compile() {
- # Be nice and check at the earliest moment so the user doesn't watch
- # everything compile only to have the emerge blow up.
- if is_empi_imp_build && [ ! -f "${FILESDIR}"/${MPI_ESELECT_FILE} ]; then
- die "MPI_ESELECT_FILE is not defined/found. ${MPI_ESELECT_FILE}"
+# @FUNCTION: mpi_root
+# @USAGE:
+# @RETURN: The root path that packages should start installing to. In the end,
+# the majority of a package will will install to ${ROOT}$(mpi_root).
+mpi_root() {
+ if mpi_classed; then
+ echo "/usr/$(get_libdir)/mpi/$(mpi_class)/"
+ else
+ echo "/"
fi
-
- pushd "${S}" &>/dev/null
- mpi_do_config || die "mpi_src_compile: mpi_do_config failed."
- mpi_do_make || die "mpi_src_compile: mpi_do_make failed."
- popd &>/dev/null
}
-mpi_src_install() {
- pushd "${S}" &>/dev/null
- mpi_do_make_install \
- || die "mpi_src_install(${MPI_IMP}) mpi_do_make_install failed."
- popd &>/dev/null
-
- [ -z "${MPI_IMP}" ] && return 0
- if is_empi_imp_build; then
- mpi_add_eselect
+# @FUNCTION: mpi_econf_args
+# @USAGE:
+# @DESCRIPTION: If classed, returns a list of arguments for econf that sets the
+# default install locations correctly. Should be first in the list of arguments
+# to econf so that any unsuitable options can be overwritten.
+mpi_econf_args() {
+ if mpi_classed; then
+ local d=$(mpi_root)
+ local c=$(mpi_class)
+ local a="
+ --prefix=${d}usr
+ --mandir=${d}usr/share/man
+ --infodir=${d}usr/share/info
+ --datadir=${d}usr/share
+ --sysconfdir=/etc/${c}
+ --localstatedir=/var/lib/${c}"
+ echo "${a}"
fi
}
-mpi_pkg_setup() {
- # Make sure this eclass should be used.
- MPI_IMP=$(get_imp)
- [ -z "${MPI_IMP}" ] && return 0
-
- if [[ -z ${MPI_IMP} ]]; then
- die "Building without empi and bail_if_not_empi failed."
- fi
-
- if ! is_empi_imp_build; then
- einfo "mpi: Building against implementation ${MPI_IMP}."
- fi
-}
-
-mpi_add_eselect() {
- cp "${FILESDIR}"/${MPI_ESELECT_FILE} ${T}/${MPI_IMP}.eselect || die
- sed -i \
- -e "s|@ROOT@|$(get_mpi_dir)|g" \
- -e "s|@LIBDIR@|$(get_libdir)|g" \
- -e "s|@BUILT_WITH@|${PF}|g" \
- ${T}/${MPI_IMP}.eselect
-
- eselect mpi add "${T}"/${MPI_IMP}.eselect
-}
-
-
-
-# Handles all the mpi_{do,new} functions below.
-# Not handled because there is no good way:
-# doconfd doenvd domo doinitd
-mpi_do() {
+# @FUNCTION: _mpi_do
+# @USAGE: $1 - Standard ebuild command to replicate.
+# @DESCRIPTION: Large wrapping class for all of the {do,new}* commands that need
+# to respect the new root to install to. Works with unclassed builds as well.
+# Currently supports:
+# @CODE
+# dobin newbin dodoc newdoc
+# doexe newexe dohtml dolib
+# dolib.a newlib.a dolib.so newlib.so
+# dosbin newsbin doman newman
+# doinfo dodir dohard doins
+# dosym
+# @CODE
+
+_mpi_do() {
local rc prefix
local cmd=${1}
local ran=1
local slash=/
- local mdir="$(get_mpi_dir)/"
+ local mdir="$(mpi_root)"
- if ! is_empi_build; then
+ if ! mpi_classed; then
$*
return ${?}
fi
@@ -357,7 +109,7 @@ mpi_do() {
elif [ "${cmd#new}" != "${cmd}" ]; then
prefix="new"; cmd=${cmd#new}
else
- die "Unknown command passed to mpi_do: ${cmd}"
+ die "Unknown command passed to _mpi_do: ${cmd}"
fi
case ${cmd} in
bin|lib|lib.a|lib.so|sbin)
@@ -366,18 +118,26 @@ mpi_do() {
doc)
_E_DOCDESTTREE_="../../../../${mdir}usr/share/doc/${PF}/${_E_DOCDESTTREE_}" \
${prefix}${cmd} $*
- rc=$?;;
+ rc=$?
+ for d in "/share/doc/${P}" "/share/doc" "/share"; do
+ rmdir ${D}/usr${d} &>/dev/null
+ done
+ ;;
html)
_E_DOCDESTTREE_="../../../../${mdir}usr/share/doc/${PF}/www/${_E_DOCDESTTREE_}" \
${prefix}${cmd} $*
- rc=$?;;
+ rc=$?
+ for d in "/share/doc/${P}/html" "/share/doc/${P}" "/share/doc" "/share"; do
+ rmdir ${D}/usr${d} &>/dev/null
+ done
+ ;;
exe)
_E_EXEDESTTREE_="${mdir}${_E_EXEDESTTREE_}" ${prefix}${cmd} $*
rc=$?;;
man|info)
[ -d "${D}"usr/share/${cmd} ] && mv "${D}"usr/share/${cmd}{,-orig}
[ ! -d "${D}"${mdir}usr/share/${cmd} ] \
- && install -d "${D}"${mdir}usr/share/${cmd}
+ && install -d "${D}"${mdir}usr/share/${cmd}
ln -snf ../../${mdir}usr/share/${cmd} ${D}usr/share/${cmd}
${prefix}${cmd} $*
@@ -390,7 +150,7 @@ mpi_do() {
hard|sym)
${prefix}${cmd} "${mdir}$1" "${mdir}/$2"; rc=$?;;
ins)
- INSDESTTREE="${mdir}${INSTREE}" ${cmd}${prefix} $*; rc=$?;;
+ INSDESTTREE="${mdir}${INSTREE}" ${prefix}${cmd} $*; rc=$?;;
*)
rc=0;;
esac
@@ -398,27 +158,207 @@ mpi_do() {
[[ ${ran} -eq 0 ]] && die "mpi_do passed unknown command: ${cmd}"
return ${rc}
}
+mpi_dobin() { _mpi_do "dobin" $*; }
+mpi_newbin() { _mpi_do "newbin" $*; }
+mpi_dodoc() { _mpi_do "dodoc" $*; }
+mpi_newdoc() { _mpi_do "newdoc" $*; }
+mpi_doexe() { _mpi_do "doexe" $*; }
+mpi_newexe() { _mpi_do "newexe" $*; }
+mpi_dohtml() { _mpi_do "dohtml" $*; }
+mpi_dolib() { _mpi_do "dolib" $*; }
+mpi_dolib.a() { _mpi_do "dolib.a" $*; }
+mpi_newlib.a() { _mpi_do "newlib.a" $*; }
+mpi_dolib.so() { _mpi_do "dolib.so" $*; }
+mpi_newlib.so() { _mpi_do "newlib.so" $*; }
+mpi_dosbin() { _mpi_do "dosbin" $*; }
+mpi_newsbin() { _mpi_do "newsbin" $*; }
+mpi_doman() { _mpi_do "doman" $*; }
+mpi_newman() { _mpi_do "newman" $*; }
+mpi_doinfo() { _mpi_do "doinfo" $*; }
+mpi_dodir() { _mpi_do "dodir" $*; }
+mpi_dohard() { _mpi_do "dohard" $*; }
+mpi_doins() { _mpi_do "doins" $*; }
+mpi_dosym() { _mpi_do "dosym" $*; }
+
+
+###########################################
+# Functions for MPI Implementation Builds #
+###########################################
+
+# @FUNCTION: mpi_imp_deplist
+# @USAGE:
+# @RETURNS: Returns a deplist that handles the blocking between mpi
+# implementations, the dep on eselect-mpi if a classed build, and any blockers
+# as specified in MPI_UNCLASSED_BLOCKERS
+mpi_imp_deplist() {
+ local c="sys-cluster"
+ local pn ver
+
+ mpi_classed && c="${CATEGORY}"
+ ver=""
+ for pn in ${__MPI_ALL_IMPLEMENTATION_PNS}; do
+ ver="${ver} !${c}/${pn}"
+ done
+ if mpi_classed; then
+ ver="${ver} >=app-admin/eselect-mpi-0.0.5"
+ else
+ for pn in ${MPI_UNCLASSED_BLOCKERS}; do
+ ver="${ver} !${MPI_UNCLASSED_BLOCKERS}"
+ done
+ fi
+ echo "${ver}"
+}
+
+mpi_imp_add_eselect() {
+ mpi_classed || return 0
+ local c=$(mpi_class)
+ cp "${FILESDIR}"/${MPI_ESELECT_FILE} ${T}/${c}.eselect || die
+ sed -i \
+ -e "s|@ROOT@|$(mpi_root)|g" \
+ -e "s|@LIBDIR@|$(get_libdir)|g" \
+ -e "s|@BASE_IMP@|${PN}|g" \
+ ${T}/${c}.eselect || die
+
+ eselect mpi add "${T}"/${c}.eselect || die
+}
+
+
+
+########################################
+# Functions for packages requiring MPI #
+########################################
+
+# @ECLASS-VARIABLE: MPI_PKG_NEED_IMPS
+# @DESCRIPTION: List of package names (${PN}) that this package is compatible
+# with. Default is the list of all mpi implementations
+MPI_PKG_NEED_IMPS="${MPI_PKG_NEED_IMPS:-${__MPI_ALL_CLASSABLE_PNS}}"
+
+# @FUNCTION: mpi_pkg_deplist
+# @USAGE:
+# @RETURN: Returns a deplist comprised of valid implementations and any blockers
+# depending on if this package is building with mpi class support.
+mpi_pkg_deplist() {
+ local c="sys-cluster"
+ local pn ver
+
+ mpi_classed && c="${CATEGORY}"
+ ver="|| ("
+ for pn in ${MPI_PKG_NEED_IMPS}; do
+ ver="${ver} ${c}/${pn}"
+ done
+ ver="${ver} )"
+
+ if ! mpi_classed && [ -n "${MPI_UNCLASSED_BLOCKERS}" ]; then
+ for pn in ${MPI_UNCLASSED_BLOCKERS}; do
+ ver="${ver} !${pn}"
+ done
+ fi
+ echo "${ver}"
+}
+
+# @FUNCTION: mpi_pkg_base_imp
+# @USAGE:
+# @DESCRIPTION: Returns the ${PN} of the package providing mpi support. Works
+# even when using an unclassed mpi build.
+mpi_pkg_base_imp() {
+ if mpi_classed; then
+ echo "$(_get_eselect_var CLASS_BASE_MPI_IMP)"
+ else
+ local pn
+ for pn in ${MPI_PKG_NEED_IMPS}; do
+ if has_version "sys-cluster/${pn}"; then
+ echo "${PN}"
+ fi
+ done
+ fi
+}
+
+# @FUNCTION: mpi_pkg_cc
+# @USAGE:
+# @DESCRIPTION: Returns the full path to the mpi C compiler. Trys to find one
+# even if this build is unclassed. If return is empty, user should assume the
+# implementation does not support this compiler
+# @FUNCTION: mpi_pkg_cxx
+# @USAGE:
+# @DESCRIPTION: Returns the full path to the mpi C++ compiler. Trys to find one
+# even if this build is unclassed. If return is empty, user should assume the
+# implementation does not support this compiler
+# @FUNCTION: mpi_pkg_fc
+# @USAGE:
+# @DESCRIPTION: Returns the full path to the mpi f90 compiler. Trys to find one
+# even if this build is unclassed. If return is empty, user should assume the
+# implementation does not support this compiler
+# @FUNCTION: mpi_pkg_f77
+# @USAGE:
+# @DESCRIPTION: Returns the full path to the mpi f77 compiler. Trys to find one
+# even if this build is unclassed. If return is empty, user should assume the
+# implementation does not support this compiler
+
+mpi_pkg_cc() { _mpi_pkg_compiler "MPI_CC" "cc"; }
+mpi_pkg_cxx() { _mpi_pkg_compiler "MPI_CXX" "cxx c++"; }
+mpi_pkg_f77() { _mpi_pkg_compiler "MPI_F77" "f77"; }
+mpi_pkg_fc() { _mpi_pkg_compiler "MPI_FC" "f90 fc"; }
+
+# If classed, we can ask eselect-mpi. Otherwise we'll look for some common
+# executable names in ${ROOT}usr/bin.
+_mpi_pkg_compiler() {
+ if mpi_classed; then
+ echo "$(eselect mpi printvar $(mpi_class) ${1})"
+ else
+ local suffixes=${2}
+ local p
+
+ for p in ${suffixes}; do
+ if [ -x ${ROOT}usr/bin/mpi${p} ]; then
+ echo "${ROOT}usr/bin/mpi${p}"
+ break
+ fi
+ done
+ fi
+}
-mpi_dobin() { mpi_do "dobin" $*; }
-mpi_newbin() { mpi_do "newbin" $*; }
-mpi_dodoc() { mpi_do "dodoc" $*; }
-mpi_newdoc() { mpi_do "newdoc" $*; }
-mpi_doexe() { mpi_do "doexe" $*; }
-mpi_newexe() { mpi_do "newexe" $*; }
-mpi_dohtml() { mpi_do "dohtml" $*; }
-mpi_dolib() { mpi_do "dolib" $*; }
-mpi_dolib.a() { mpi_do "dolib.a" $*; }
-mpi_newlib.a() { mpi_do "newlib.a" $*; }
-mpi_dolib.so() { mpi_do "dolib.so" $*; }
-mpi_newlib.so() { mpi_do "newlib.so" $*; }
-mpi_dosbin() { mpi_do "dosbin" $*; }
-mpi_newsbin() { mpi_do "newsbin" $*; }
-mpi_doman() { mpi_do "doman" $*; }
-mpi_newman() { mpi_do "newman" $*; }
-mpi_doinfo() { mpi_do "doinfo" $*; }
-mpi_dodir() { mpi_do "dodir" $*; }
-mpi_dohard() { mpi_do "dohard" $*; }
-mpi_doins() { mpi_do "doins" $*; }
-mpi_dosym() { mpi_do "dosym" $*; }
-
-EXPORT_FUNCTIONS src_compile src_install pkg_setup
+# @FUNCTION: mpi_pkg_set_env
+# @USAGE:
+# @DESCRIPTION: Exports 'some influential environment variables'. CC, CXX, F77, FC
+mpi_pkg_set_env() {
+ if mpi_classed; then
+ _mpi_oCC=$CC
+ _mpi_oCXX=$CXX
+ _mpi_oF77=$F77
+ _mpi_oFC=$FC
+ _mpi_oPCP=${PKG_CONFIG_PATH}
+ _mpi_oLLP=${LD_LIBRARY_PATH}
+ export CC=$(mpi_pkg_cc)
+ export CXX=$(mpi_pkg_cxx)
+ export F77=$(mpi_pkg_f77)
+ export FC=$(mpi_pkg_fc)
+ export PKG_CONFIG_PATH="$(mpi_root)$(get_libdir)/pkgconfig:${PKG_CONFIG_PATH}"
+ export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$(_get_eselect_var LD_LIBRARY_PATH)"
+ fi
+}
+
+# @FUNCTION: mpi_pkg_restore_env
+# @USAGE:
+# @DESCRIPTION: Attempts to undo the damage done by mpi_pkg_set_env
+mpi_pkg_restore_env() {
+ if mpi_classed; then
+ export CC=$_mpi_oCC
+ export CXX=$_mpi_oCXX
+ export F77=$_mpi_oF77
+ export FC=$_mpi_oFC
+ export PKG_CONFIG_PATH=$_mpi_oPCP
+ export LD_LIBRARY_PATH=$_mpi_oLLP
+ fi
+}
+
+
+
+# @FUNCTION: _get_eselect_var
+# @USAGE: $1 - Variable to get from the class definition
+# @RETURN: If classed, and given a valid variable, the contents; empty
+# otherwise.
+_get_eselect_var() {
+ if mpi_classed && [ -n "${1}" ]; then
+ echo "$(eselect mpi printvar $(mpi_class) ${1} 2>/dev/null)"
+ fi
+}