#!/bin/bash
#
# Copyright (c) 2006 Mellanox Technologies. All rights reserved.
# Copyright (c) 2006 Cisco Systems, Inc.  All rights reserved.
#
# This Software is licensed under one of the following licenses:
#
# 1) under the terms of the "Common Public License 1.0" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/cpl.php.
#
# 2) under the terms of the "The BSD License" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/bsd-license.php.
#
# 3) under the terms of the "GNU General Public License (GPL) Version 2" a
#    copy of which is available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/gpl-license.php.
#
# Licensee has the right to choose one of the above licenses.
#
# Redistributions of source code must retain the above copyright
# notice and one of the license notices.
#
# Redistributions in binary form must reproduce both the above copyright
# notice, one of the license notices in the documentation
# and/or other materials provided with the distribution.
#
#  $Id: build.sh 9595 2006-09-21 09:09:26Z vlad $
#
# Description: OFED RPMs build script

usage()
{
cat << EOF

    `basename $0` [ -c <config_file> ]

EOF
}

unalias -a

cd ${0%*/*}
CWD=`pwd`

INTERACTIVE=1

if [ ! -e ./build_env.sh ]; then
    echo "ERROR: $CWD/build_env.sh is missing"
    exit 1
fi

while [ $# -gt 0 ]
do
    case $1 in
            -c)
                shift
                CONFIG=$1
                INTERACTIVE=0
            ;;
            *)
                usage
                exit 1
            ;;
    esac
    shift
done

. $CWD/build_env.sh


# Set default values
SELECTED_PACKAGES=""
OFA_PACKAGES=""
EXTRA_PACKAGES=""
IB_EXTRA_PACKAGES=""
WITH_PACKAGES=""
WITH_PACKAGES32=""
WITH_KERNEL_PACKAGES=""
WITH_BIN_PACKAGES=""
WITH_BIN_PACKAGES32=""
MEMTRACK=0
MADEYE=0

build_kernel_ib=0
build_kernel_ib_devel=0
modprobe_update=1
include_ipoib_conf=1
apply_hpage_patch=1
more_kernel_options=""

# Environment variables definition
BUILD_COUNTER=0
EXISTING_RPMS=0


# Create RPMs for selected packages from ofa_user and ofa_kernel
ofa()
{
#        if ! check_build_req openib err; then
#            exit 2
#        fi    
        cd $BUILD_TMP
        for package in ${OFA_PACKAGES}
        do
            case ${package} in
                kernel-ib)
                    build_kernel_ib=1
                ;;
                kernel-ib-devel)
                    build_kernel_ib_devel=1
                ;;
                libo*sm*|opensm)
                    if ! ( echo "${WITH_PACKAGES}" | grep "with-opensm" > $NULL 2>&1 ); then
                        WITH_PACKAGES="${WITH_PACKAGES} --with-opensm"
                    fi
                ;;
                *-devel|*-utils)
                ;;
                mstflint|tvflash)
                    case $ARCH in
                        ppc64)
                        WITH_BIN_PACKAGES32="${WITH_BIN_PACKAGES32} --with-${package}"
                        ;;
                        *)
                        WITH_BIN_PACKAGES="${WITH_BIN_PACKAGES} --with-${package}"
                        ;;
                    esac
                ;;
                perftest)
                    WITH_BIN_PACKAGES="${WITH_BIN_PACKAGES} --with-${package}"
                ;;
                *)
                    WITH_PACKAGES="${WITH_PACKAGES} --with-${package}"
                ;;
            esac
        done

        if [ $build_32bit -eq 1 ]; then
            WITH_PACKAGES32="${WITH_PACKAGES} ${WITH_PACKAGES32} ${WITH_BIN_PACKAGES32}"
        fi

        if [ -n "${WITH_BIN_PACKAGES32}" ] && [ $build_32bit -eq 0 ]; then
            build_32bit=1
            WITH_PACKAGES32="${WITH_BIN_PACKAGES32}"
        fi

        if [ ! -n "$OFA_KERNEL_PACKAGES" ]; then
            # OFA_KERNEL_PACKAGES="$BASIC_IB_KERNEL_PACKAGES"
            OFA_KERNEL_PACKAGES=""
        fi

        for package in ${OFA_KERNEL_PACKAGES}
        do
            case ${package} in
                ib_verbs)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-core-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod"
                ;;
                ib_mthca)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-mthca-mod"
                ;;
                ib_ipath)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-ipath_inf-mod"
                ;;
                ib_ehca)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-ehca-mod"
                ;;
                ib_ipoib)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-ipoib-mod"
                ;;
                ib_sdp)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-sdp-mod"
                ;;
                ib_srp)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-srp-mod"
                ;;
                ib_iser)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-iser-mod"
                ;;
                cxgb3)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-cxgb3-mod"
                ;;
                vnic)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-vnic-mod"
                ;;
                rds)
                    WITH_KERNEL_PACKAGES="${WITH_KERNEL_PACKAGES} --with-rds-mod"
                ;;
                *)
                    warn_echo "Unknown package ${package}"
                ;;
            esac
        done

        for param in ${OFA_KERNEL_PARAMS}
        do
            case ${param} in
                --with-modprobe)
                    modprobe_update=1
                ;;
                --without-modprobe)
                    modprobe_update=0
                ;;
                --memtrack|--with-memtrack)
                    MEMTRACK=1
                ;;
                --without-memtrack)
                    MEMTRACK=0
                ;;
                --with-madeye|--with-madeye-mod)
                    MADEYE=1
                ;;
                --without-madeye|--without-madeye-mod)
                    MADEYE=0
                ;;
                --with-ipoibconf)
                    include_ipoib_conf=1
                ;;
                --without-ipoibconf)
                    include_ipoib_conf=0
                ;;
                --with-hpage-patch)
                    apply_hpage_patch=1
                ;;
                --without-hpage-patch)
                    apply_hpage_patch=0
                ;;
                --with*)
                    more_kernel_options="${more_kernel_options} ${param}"
                ;;
            esac
        done

        # Configure options for userspace
        if [ ! -n "${WITH_PACKAGES32}" ]; then
            configure_options32="%{nil}"
        else
            configure_options32="${WITH_PACKAGES32}"
        fi

        if [ ! -n "${WITH_PACKAGES}" ] && [ ! -n "${WITH_BIN_PACKAGES}" ]; then
            configure_options_user="%{nil}"
        else
            configure_options_user="${WITH_PACKAGES} ${WITH_BIN_PACKAGES}"
        fi

        # Configure options for kernel
        if [ ! -n "${WITH_KERNEL_PACKAGES}" ]; then
            configure_options_kernel="%{nil}"
        else
            configure_options_kernel="${WITH_KERNEL_PACKAGES} ${more_kernel_options}"
        fi

        if [ $MEMTRACK -eq 1 ]; then
            configure_options_kernel="$configure_options_kernel --with-memtrack"
        fi

        if [ $MADEYE -eq 1 ]; then
            configure_options_kernel="$configure_options_kernel --with-madeye-mod"
        fi

        if [ ${apply_hpage_patch} -eq 0 ]; then
            configure_options_kernel="$configure_options_kernel --without-hpage-patch"
        fi

        # Remove RPM_BUILD_ROOT
        case ${BUILD_ROOT} in
                /var/tmp/?*)
                /bin/rm -rf ${BUILD_ROOT}
                ;;
        esac

        if [[ -n "${WITH_PACKAGES32}" || -n "${WITH_PACKAGES}" ]]; then
                echo
                echo "Building ${OFA_USER_NAME} RPMs. Please wait..."
                echo

                ex  rpmbuild --rebuild --define \'_topdir ${RPM_DIR}\' \
                        --define \'_prefix ${STACK_PREFIX}\' \
                        --define \'build_root  ${BUILD_ROOT}\' \
                        --define \'configure_options ${configure_options_user} --sysconfdir=${sysconfdir} --mandir=${mandir}\' \
                        --define \'configure_options32 ${configure_options32} --sysconfdir=${sysconfdir} --mandir=${mandir}\' \
                        --define \'build_32bit ${build_32bit}\' \
                        --define \'_mandir ${mandir}\' \
                        ${OFA_USER_SRC_RPM}
        fi

        if [ -n "${WITH_KERNEL_PACKAGES}" ]; then
                echo
                echo "Building ${OFA_KERNEL_NAME} RPMs. Please wait..."
                echo

                ex  rpmbuild --rebuild --define \'_topdir ${RPM_DIR}\' \
                        --define \'_prefix ${STACK_PREFIX}\' \
                        --define \'build_root  ${BUILD_ROOT}\' \
                        --define \'configure_options ${configure_options_kernel}\' \
                        --define \'KVERSION ${K_VER}\' \
                        --define \'KSRC ${K_SRC}\' \
                        --define \'build_kernel_ib ${build_kernel_ib}\' \
                        --define \'build_kernel_ib_devel ${build_kernel_ib_devel}\' \
                        --define \'NETWORK_CONF_DIR ${NETWORK_CONF_DIR}\' \
                        --define \'modprobe_update ${modprobe_update}\' \
                        --define \'include_ipoib_conf ${include_ipoib_conf}\' \
                        ${OFA_KERNEL_SRC_RPM}

                rpms=""
        fi

        for package in ${OFA_PACKAGES}
        do
            rpm=""
            if ( ls -1 ${RPM_DIR}/RPMS/$build_arch/${package}-*.${build_arch}.rpm > $NULL 2>&1 ); then
                rpm=$(ls -1 ${RPM_DIR}/RPMS/$build_arch/${package}-*.${build_arch}.rpm 2> $NULL)
                rpms="$rpms $rpm"
                let BUILD_COUNTER++
            fi
        done
        rpms=$(echo $rpms | tr -s ' ' '\n' | sort -n | uniq | tr -s '\n' ' ')

        if [ ! -n "${rpms/ /}" ]; then
                echo "No ofa packages were built."
                return 1
        fi

        ex "$MV -f ${rpms} $RPMS"
        
        return 0
}

open-iscsi()
{
        if ! check_build_req open_iscsi err; then
            return 2
        fi    

        echo
        echo "Building open RPM. Please wait..."
        echo

        if [[ -z $OPEN_ISCSI_NAME || -z $OPEN_ISCSI_VERSION ]]; then
            err_echo "Failed to define OPEN_ISCSI RPM version"
            return 1
        fi
        ex rpmbuild --rebuild --define \'_topdir ${RPM_DIR}\' ${OPEN_ISCSI_SRC_RPM}

        case ${DISTRIBUTION} in
            SuSE)
	    ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${OPEN_ISCSI_SUSE_NAME}-${OPEN_ISCSI_VERSION}.${build_arch}.rpm $RPMS"
	    ;;
            redhat|redhat5)
	    ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${OPEN_ISCSI_REDHAT_NAME}-${OPEN_ISCSI_VERSION}.${build_arch}.rpm $RPMS"
            ;;
	    *)
	    err_echo "Distribution ${DISTRIBUTION} is not supported by open-iscsi over iSER"
	    return 1
	    ;;
	esac
        
        let BUILD_COUNTER++
        
        return 0
}

ofed-docs()
{
        if [[ -z $DOCS_NAME || -z $DOCS_VERSION ]]; then
            err_echo "Failed to define DOCS RPM version"
            return 1
        fi
        ex rpmbuild --rebuild --target=noarch --define \'_topdir ${RPM_DIR}\' --define \'_prefix ${STACK_PREFIX}\' ${DOCS_SRC_RPM}

        ex "$MV -f ${RPM_DIR}/RPMS/noarch/${DOCS_NAME}-${DOCS_VERSION}.noarch.rpm $RPMS"
        let BUILD_COUNTER++
        return 0
}

ofed-scripts()
{
        if [[ -z $SCRIPTS_NAME || -z $SCRIPTS_VERSION ]]; then
            err_echo "Failed to define SCRIPTS RPM version"
            return 1
        fi
        ex rpmbuild --rebuild --target=noarch --define \'_topdir ${RPM_DIR}\' --define \'_prefix ${STACK_PREFIX}\' ${SCRIPTS_SRC_RPM}

        ex "$MV -f ${RPM_DIR}/RPMS/noarch/${SCRIPTS_NAME}-${SCRIPTS_VERSION}.noarch.rpm $RPMS"
        let BUILD_COUNTER++
        return 0
}

ibutils()
{
#        if ! check_build_req ibutils err; then
#            return 2
#        fi    

        echo
        echo "Building ibutils RPM. Please wait..."
        echo

        if [[ -z $IBUTILS_NAME || -z $IBUTILS_VERSION ]]; then
            err_echo "Failed to define IBUTILS RPM version"
            return 1
        fi

        local libdir
        case ${ARCH} in
            i?86|ia64)
            libdir=${STACK_PREFIX}/lib
            ;;
            *)
            libdir=${STACK_PREFIX}/lib64
            ;;
        esac

        ex rpmbuild --rebuild \
        --define \'_topdir ${RPM_DIR}\' \
        --define \'configure_options --prefix=${STACK_PREFIX} --mandir=${mandir} --cache-file=${BUILD_ROOT}/ibutils.cache --with-osm=${BUILD_ROOT}${STACK_PREFIX}\' \
        --define \'_prefix ${STACK_PREFIX}\' \
        --define \'_libdir ${libdir}\' \
        --define \'_mandir ${mandir}\' \
        --define \'build_root ${BUILD_ROOT}\' \
        ${IBUTILS_SRC_RPM}

        ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${IBUTILS_NAME}-${IBUTILS_VERSION}.${build_arch}.rpm $RPMS"
        let BUILD_COUNTER++
        
        return 0

}

# mpi-selector tool
mpi-selector()
{
    echo
    echo "Building mpi-selector RPM. Please wait..."
    echo

    ex rpmbuild -v --target noarch --rebuild \
        --define \'_topdir ${RPM_DIR}\' \
        --define \'ofed 1\' \
        --define \'buildroot ${BUILD_ROOT}\' \
        --define \'configure_options --mandir=${mandir} --with-shell-startup-dir=/etc/profile.d --localstatedir=/var/lib\' \
        --define \'_prefix ${STACK_PREFIX}\' \
        --define \'_mandir ${mandir}\' \
        --define \'_docdir %{_prefix}/share/doc/${MPI_SELECTOR_NAME}-${MPI_SELECTOR_VERSION}\' \
        ${MPI_SELECTOR_SRC_RPM}
    
    ex "$MV -f ${RPM_DIR}/RPMS/noarch/${MPI_SELECTOR_NAME}-${MPI_SELECTOR_VERSION}.noarch.rpm $RPMS"
    let BUILD_COUNTER++
}

# MVAPICH MPI installation
mvapich()
{
#        if ! check_build_req mvapich err; then
#            return 2
#        fi    

        echo
        echo "Building MVAPICH RPM. Please wait..."
        echo

        for mpi_comp in ${MPI_COMPILER_mvapich}
        do
            echo "Using ${mpi_comp} compiler"
            ex rpmbuild -v --rebuild \
                --define \'_topdir ${RPM_DIR}\' \
                --define \'_name ${MVAPICH_NAME}_${mpi_comp}\' \
                --define \'ofed 1\' \
                --define \'compiler ${mpi_comp}\' \
                --define \'openib_prefix ${STACK_PREFIX}\'  \
                --define \'mpi_selector ${STACK_PREFIX}/bin/mpi-selector\' \
                --define \'build_root ${BUILD_ROOT}\' \
                --define \'_prefix ${STACK_PREFIX}/mpi/${mpi_comp}/${MVAPICH_NAME}-${MVAPICH_VER}\' \
                ${MVAPICH_SRC_RPM}

            ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${MVAPICH_NAME}_${mpi_comp}-${MVAPICH_VERSION}.${build_arch}.rpm $RPMS"
            let BUILD_COUNTER++
        if [ "$mpitests" == "y" ]; then
            echo
            echo "Building mpitests RPM over MVAPICH MPI using ${mpi_comp} compiler. Please wait..."
            echo
            MPITESTS_RPM=${MPITESTS_NAME}_${MVAPICH_NAME}_${mpi_comp}-${MPITESTS_VERSION}.${build_arch}.rpm
            ex rpmbuild --rebuild \
            --define \'_topdir ${RPM_DIR}\' \
            --define \'_name ${MPITESTS_NAME}_${MVAPICH_NAME}_${mpi_comp}\' \
            --define \'path_to_mpihome ${STACK_PREFIX}/mpi/${mpi_comp}/${MVAPICH_NAME}-${MVAPICH_VER}\' \
            --define \'buildroot ${BUILD_ROOT}\' \
            --define \'stack_prefix ${STACK_PREFIX}\' \
            $MPITESTS_SRC_RPM
            ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${MPITESTS_RPM} $RPMS"
            let BUILD_COUNTER++
        fi

        done        
        return 0
}

mvapich2()
{
    if [ $MVAPICH2_CONF_impl = "ofa" ]; then
        echo "Building the MVAPICH2 RPM in the OFA configuration. Please wait..."
    elif [ $MVAPICH2_CONF_impl = "udapl" ]; then
        echo "Building the MVAPICH2 RPM in the uDPAL configuration. Please wait..."
        if [ -d ${BUILD_ROOT}${STACK_PREFIX}/lib64 ]; then
            MVAPICH2_DAT_LIB=${STACK_PREFIX}/lib64
        elif [ -d ${BUILD_ROOT}${STACK_PREFIX}/lib ]; then
            MVAPICH2_DAT_LIB=${STACK_PREFIX}/lib
        else
            echo "Could not find a proper uDAPL lib directory."
            return 1
        fi

        if [ -d ${BUILD_ROOT}${STACK_PREFIX}/include ]; then
            MVAPICH2_DAT_INCLUDE=${STACK_PREFIX}/include
        else
            echo "Could not find a proper uDAPL include directory."
            return 1
        fi
    fi

    echo

    for mpi_comp in ${MPI_COMPILER_mvapich2}
    do
        echo "Using the ${mpi_comp} compiler"
        MVAPICH2_RPM=${MVAPICH2_NAME}_${mpi_comp}-${MVAPICH2_VER}-${MVAPICH2_REL}.${build_arch}.rpm
        MVAPICH2_PREFIX="${STACK_PREFIX}/mpi/${mpi_comp}/${MVAPICH2_NAME}-${MVAPICH2_VERSION}"

        case ${mpi_comp} in
            gcc)
                if [ $is_gfortran -eq 1 ]; then
                    if [ $ARCH = "ppc64" ]; then
                        MVAPICH2_COMP_ENV='CC="gcc -m64" CXX="g++ -m64" F77="gfortran -m64" F90="gfortran -m64"'
                    else
                        MVAPICH2_COMP_ENV="CC=gcc CXX=g++ F77=gfortran F90=gfortran"
                    fi
                elif [ $is_gcc_g77 -eq 1 ]; then
                    if [ $ARCH = "ppc64" ]; then
                        MVAPICH2_COMP_ENV='CC="gcc -m64" CXX="g++ -m64" F77="g77 -m64" F90=/bin/false'
                    else
                        MVAPICH2_COMP_ENV="CC=gcc CXX=g++ F77=g77 F90=/bin/false"
                    fi
                fi
            ;;
            pathscale)
                MVAPICH2_COMP_ENV="CC=pathcc CXX=pathCC F77=pathf90 F90=pathf90"

                # On i686 the PathScale compiler requires -g optimization
                # for MVAPICH2 in the shared library configuration.
                if [ "$ARCH" = "i686" ] && [ $MVAPICH2_CONF_shared_libs -eq 1 ]; then
                    MVAPICH2_COMP_ENV="$MVAPICH2_COMP_ENV OPT_FLAG=-g"
                fi
            ;;
            pgi)
                MVAPICH2_COMP_ENV="CC=pgcc CXX=pgCC F77=pgf77 F90=pgf90"
            ;;
            intel)
                if [ $MVAPICH2_CONF_shared_libs -eq 1 ]; then
                    # The -i-dynamic flag is required for MVAPICH2 in the shared
                    # library configuration.
                    MVAPICH2_COMP_ENV='CC="icc -i-dynamic" CXX="icpc -i-dynamic" F77="ifort -i-dynamic" F90="ifort -i-dynamic"'
                else
                    MVAPICH2_COMP_ENV="CC=icc CXX=icpc F77=ifort F90=ifort"
                fi
            ;;
        esac

        if [ $MVAPICH2_CONF_impl = "ofa" ] && [ $MVAPICH2_CONF_ckpt -eq 0 ]; then
            ex rpmbuild --rebuild \
               --define \'_topdir ${RPM_DIR}\' \
	       --define \'_prefix ${MVAPICH2_PREFIX}\' \
               --define \'_name ${MVAPICH2_NAME}_${mpi_comp}\' \
               --define \'build_root ${BUILD_ROOT}\' \
               --define \'impl ofa\' \
               --define \'multithread ${MVAPICH2_CONF_multithread}\' \
               --define \'romio ${MVAPICH2_CONF_romio}\' \
               --define \'shared_libs ${MVAPICH2_CONF_shared_libs}\' \
               --define \'rdma_cm 1\' \
               --define \'ckpt 0\' \
               --define \'open_ib_home ${STACK_PREFIX}\' \
               --define \'comp_env ${MVAPICH2_COMP_ENV}\' \
               --define \'auto_req 0\' \
               --define \'mpi_selector ${STACK_PREFIX}/bin/mpi-selector\' \
               --define \'ofa_build 1\' \
               $MVAPICH2_SRC_RPM
        elif [ $MVAPICH2_CONF_impl = "ofa" ] && [ $MVAPICH2_CONF_ckpt -eq 1 ]; then
            ex rpmbuild --rebuild \
               --define \'_topdir ${RPM_DIR}\' \
               --define \'_prefix ${MVAPICH2_PREFIX}\' \
               --define \'_name ${MVAPICH2_NAME}_${mpi_comp}\' \
               --define \'build_root ${BUILD_ROOT}\' \
               --define \'impl ofa\' \
               --define \'multithread 0\' \
               --define \'romio ${MVAPICH2_CONF_romio}\' \
               --define \'shared_libs ${MVAPICH2_CONF_shared_libs}\' \
               --define \'rdma_cm 0\' \
               --define \'ckpt 1\' \
               --define \'blcr_home ${MVAPICH2_CONF_blcr_home}\' \
               --define \'open_ib_home ${STACK_PREFIX}\' \
               --define \'comp_env ${MVAPICH2_COMP_ENV}\' \
               --define \'auto_req 0\' \
               --define \'mpi_selector ${STACK_PREFIX}/bin/mpi-selector\' \
               --define \'ofa_build 1\' \
               $MVAPICH2_SRC_RPM
        elif [ $MVAPICH2_CONF_impl = "udapl" ]; then
            ex rpmbuild --rebuild \
               --define \'_topdir ${RPM_DIR}\' \
               --define \'_prefix ${MVAPICH2_PREFIX}\' \
               --define \'_name ${MVAPICH2_NAME}_${mpi_comp}\' \
               --define \'build_root ${BUILD_ROOT}\' \
               --define \'impl udapl\' \
               --define \'multithread ${MVAPICH2_CONF_multithread}\' \
               --define \'romio ${MVAPICH2_CONF_romio}\' \
               --define \'shared_libs ${MVAPICH2_CONF_shared_libs}\' \
               --define \'vcluster ${MVAPICH2_CONF_vcluster}\' \
               --define \'io_bus ${MVAPICH2_CONF_io_bus}\' \
               --define \'link_speed ${MVAPICH2_CONF_link_speed}\' \
               --define \'dapl_provider ${MVAPICH2_CONF_dapl_provider}\' \
               --define \'dat_lib ${MVAPICH2_DAT_LIB}\' \
               --define \'dat_include ${MVAPICH2_DAT_INCLUDE}\' \
               --define \'comp_env ${MVAPICH2_COMP_ENV}\' \
               --define \'auto_req 0\' \
               --define \'mpi_selector ${STACK_PREFIX}/bin/mpi-selector\' \
               --define \'ofa_build 1\' \
               $MVAPICH2_SRC_RPM
        fi

        ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${MVAPICH2_RPM} $RPMS"
        let BUILD_COUNTER++

        if [ "$mpitests" == "y" ]; then
            echo
            echo "Building the mpitests RPM over MVAPICH2 using the ${mpi_comp} compiler. Please wait..."
            echo
            MPITESTS_RPM=${MPITESTS_NAME}_${MVAPICH2_NAME}_${mpi_comp}-${MPITESTS_VERSION}.${build_arch}.rpm

            # rowland: The MVAPICH2 SRPM was built above by specifying
            # ofed_build_root (set to the same as its build_root), thus
            # enabling its ofed_bootstrap mode internally.  This means that
            # it was installed in the same temporary location as the OFED
            # libraries in the proper place and built in such a way as to
            # be able to use the OFED libraries in that location. It was
            # also left in place after the RPM was created so that the
            # mpitests package could be built.   However, files like mpicc
            # were cleaned up so that they will point to the final location
            # of the OFED libraries, which causes a problem when building
            # the mpitests package below.  Therefore, I am exporting
            # LD_LIBRARY_PATH very carefully to make this work.  I restore
            # the original state after the mpitests build.  This works, and
            # seems necessary due to the way the OFED libraries are in a
            # temporary "bootstrap" directory.
            MVAPICH2_OLD_LD_PATH="$LD_LIBRARY_PATH"

            if [ -d ${BUILD_ROOT}/${STACK_PREFIX}/lib ]; then
                export LD_LIBRARY_PATH="${BUILD_ROOT}${STACK_PREFIX}/lib:$LD_LIBRARY_PATH"
            fi

            if [ -d ${BUILD_ROOT}${STACK_PREFIX}/lib64 ]; then
                export LD_LIBRARY_PATH="${BUILD_ROOT}${STACK_PREFIX}/lib64:$LD_LIBRARY_PATH"
            fi

            ex rpmbuild --rebuild \
               --define \'_topdir ${RPM_DIR}\' \
               --define \'_name ${MPITESTS_NAME}_${MVAPICH2_NAME}_${mpi_comp}\' \
               --define \'path_to_mpihome ${MVAPICH2_PREFIX}\' \
               --define \'buildroot ${BUILD_ROOT}\' \
               --define \'stack_prefix ${STACK_PREFIX}\' \
               $MPITESTS_SRC_RPM

            if [ -z "$MVAPICH2_OLD_LD_PATH" ]; then
                # LD_LIBRARY_PATH wasn't really set the first time, so I don't
                # want to actually export it to nothing, though it shouldn't
                # matter in the end I think.  I want the exported environment
                # to be _exactly_ the same as the original.
                unset LD_LIBRARY_PATH
            else
                export LD_LIBRARY_PATH="${MVAPICH2_OLD_LD_PATH}"
            fi

            ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${MPITESTS_RPM} $RPMS"
            let BUILD_COUNTER++
        fi
    done
    return 0
}

openmpi()
{
    local rpm_cnt=0
    
#    if ! check_run_req openmpi err; then
#        return 2
#    fi    

    # Note: installation fails if existing Open MPI rpm was created under different prefix
    # need_openmpi_build=0
    # for mpi_comp in ${MPI_COMPILER_openmpi}
    # do
    #     [ ! -f ${RPMS}/${OPENMPI_NAME}_${mpi_comp}-${OPENMPI_VERSION}.${build_arch}.rpm ] && need_openmpi_build=1
    # done  
    # if test "$need_openmpi_build" = 0; then
    #     return 0
    # fi

    if [[ -z $OPENMPI_NAME || -z $OPENMPI_VERSION ]]; then
        err_echo "Failed to identify the Open MPI RPM version"
        return 1
    fi
    
    echo
    echo "Building the Open MPI RPM. Please wait..."
    echo
    
    for mpi_comp in ${MPI_COMPILER_openmpi}
    do
        echo "Using the ${mpi_comp} compiler"
        OPENMPI_RPM=${OPENMPI_NAME}_${mpi_comp}-${OPENMPI_VERSION}.${build_arch}.rpm

        # We use this in multiple locations, so we might as well
        # put it into a common variable
        OMPI_PREFIX="${STACK_PREFIX}/mpi/${mpi_comp}/${OPENMPI_NAME}-${OPENMPI_VERSION}"
        case ${ARCH} in
            i?86|ia64)
                OMPI_LIBDIR="lib"
                ;;
            *)
                OMPI_LIBDIR="lib64"
                ;;
        esac

        # The compilers listed below all accept the following form
        # for setting the rpath.
        OMPI_RPATH="-Wl,-rpath -Wl,$OMPI_PREFIX/$OMPI_LIBDIR"
        OMPI_LDFLAGS='LDFLAGS=\"-Wl,-R'$STACK_PREFIX/$OMPI_LIBDIR' -Wl,-rpath-link,'$BUILD_ROOT/$STACK_PREFIX/$OMPI_LIBDIR'\"'
        # We have just the CXX FLAGS in a separate variable because
        # the PGI C++ compiler needs a special flag.
        OMPI_WRAPPER_CXX_FLAGS=
        # Not all compilers like the defaulr $RPM_OPT_FLAGS
        USE_DEFAULT_RPM_OPT_FLAGS=1
        case ${mpi_comp} in
            pathscale)
                COMP_OPTIONS="CC=pathcc"
                if [ $is_pathCC -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS CXX=pathCC"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                fi
                if [ $is_pathf90 -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS F77=pathf90 FC=pathf90"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77 --disable-mpi-f90"
                fi
               # On fedora6 and redhat5 the pathscale compiler fails with default $RPM_OPT_FLAGS
               if [ $DISTRIBUTION == "fedora6" -o $DISTRIBUTION == "redhat5" ]; then
                   USE_DEFAULT_RPM_OPT_FLAGS=0
               fi
            ;;
            intel)
                COMP_OPTIONS="CC=icc"
                if [ $is_icpc -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS CXX=icpc"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                fi
                if [ $is_ifort -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS F77=ifort FC=ifort"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77 --disable-mpi-f90"
                fi
            ;;
            pgi)
                COMP_OPTIONS="CC=pgcc"
                USE_DEFAULT_RPM_OPT_FLAGS=0
                if [ $is_pgCC -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS CXX=pgCC"
                    # See http://www.pgroup.com/userforum/viewtopic.php?p=2371
                    OMPI_WRAPPER_CXX_FLAGS="-fpic"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                fi
                if [ $is_pgf77 -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS F77=pgf77"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77"
                fi
                if [ $is_pgf90 -eq 1 ]; then
                    # *Must* put in FCFLAGS=-O2 so that -g doesn't get
                    # snuck in there (pgi 6.2-5 has a problem with
                    # modules and -g).
                    COMP_OPTIONS="$COMP_OPTIONS FC=pgf90 FCFLAGS=-O2"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f90"
                fi
            ;;
            gcc)
                COMP_OPTIONS="CC=gcc"
                if [ $is_gpp -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS CXX=g++"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-cxx"
                fi
                if [ $is_gfortran -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS F77=gfortran FC=gfortran"
                elif [ $is_gcc_g77 -eq 1 ]; then
                    COMP_OPTIONS="$COMP_OPTIONS F77=g77 --disable-mpi-f90"
                else
                    COMP_OPTIONS="$COMP_OPTIONS --disable-mpi-f77 --disable-mpi-f90"
                fi
            ;;
            *)
                COMP_OPTIONS="CC=${mpi_comp} --disable-mpi-f77 --disable-mpi-f90"
                # If we get an unknown compiler, don't assume that
                # we can do rpath; just punt.
                OMPI_RPATH=
                OMPI_LDFLAGS=
            ;;
        esac
        
        case ${ARCH} in
            ppc64)
                # In the ppc64 case, add -m64 to all the relevant
                # flags because it's not the default.  Also
                # unconditionally add $OMPI_RPATH because even if
                # it's blank, it's ok because there are other
                # options added into the ldflags so the overall
                # string won't be blank.
                COMP_OPTIONS="$COMP_OPTIONS CFLAGS=\"-m64 -O2\" CXXFLAGS=\"-m64 -O2\" FCFLAGS=\"-m64 -O2\" FFLAGS=\"-m64 -O2\" --with-wrapper-ldflags=\"$OMPI_RPATH -g -O2 -m64 -L/usr/lib64\" --with-wrapper-cflags=-m64 --with-wrapper-cxxflags=-m64 --with-wrapper-fflags=-m64 --with-wrapper-fcflags=-m64"
                OMPI_WRAPPER_CXX_FLAGS="-m64 $OMPI_WRAPPER_CXX_FLAGS"
            ;;
            *)
                # In the non-ppc64 case, only add to the wrapper
                # LDFLAGS if $OMPI_RPATH is not empty.
                if test "$OMPI_RPATH" != ""; then
                    COMP_OPTIONS="$COMP_OPTIONS --with-wrapper-ldflags=\"$OMPI_RPATH\""
                fi
            ;;
        esac

        COMP_OPTIONS="$COMP_OPTIONS --enable-mpirun-prefix-by-default"
        if test "$OMPI_WRAPPER_CXX_FLAGS" != ""; then
            COMP_OPTIONS="$COMP_OPTIONS --with-wrapper-cxxflags=\"$OMPI_WRAPPER_CXX_FLAGS\""
        fi

        # Build the OMPI RPM.  Ensure to use the leave_build_root
        # option so that OMPI is left installed in the RPM build root
        # so that we can build the MPI tests later.  Also need to
        # specifically disable the RPM checking for packaged files
        # because there's lots of other stuff in the staging directory.
        ex rpmbuild --rebuild \
                --define \'_topdir ${RPM_DIR}\' \
                --define \'_name ${OPENMPI_NAME}_${mpi_comp}\' \
                --define \'_prefix ${OMPI_PREFIX}\' \
                --define \'_mandir %{_prefix}/share/man\' \
                --define \'_defaultdocdir ${STACK_PREFIX}/mpi/${mpi_comp}/${OPENMPI_NAME}-${OPENMPI_VERSION}\' \
                --define \'configure_options $OMPI_LDFLAGS --with-openib=${BUILD_ROOT}${STACK_PREFIX} --with-openib-libdir=${BUILD_ROOT}${STACK_PREFIX}/${OMPI_LIBDIR} ${COMP_OPTIONS}\' \
                --define \'mflags -j 4\' \
                --define \'buildroot ${BUILD_ROOT}\' \
                --define \'mpi_selector ${STACK_PREFIX}/bin/mpi-selector\' \
                --define \'ofed 1\' \
                --define \'use_default_rpm_opt_flags $USE_DEFAULT_RPM_OPT_FLAGS \' \
                $OPENMPI_SRC_RPM
            
        ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${OPENMPI_RPM} $RPMS"
        let BUILD_COUNTER++
        if [ "$mpitests" == "y" ]; then
            echo
            echo "Building the mpitests RPM over Open MPI using the ${mpi_comp} compiler. Please wait..."
            echo
            MPITESTS_RPM=${MPITESTS_NAME}_${OPENMPI_NAME}_${mpi_comp}-${MPITESTS_VERSION}.${build_arch}.rpm

            # Special environment variable directive to Open MPI to
            # tell it that it's working in a DESTDIR environment and
            # it needs to adjust all of its internal paths
            # accordingly.
            OPAL_DESTDIR=${BUILD_ROOT}
            LD_LIBRARY_PATH_save="$LD_LIBRARY_PATH"
            LD_LIBRARY_PATH="${BUILD_ROOT}${OMPI_PREFIX}/${OMPI_LIBDIR}:$LD_LIBRARY_PATH"
            export OPAL_DESTDIR LD_LIBRARY_PATH

            # Build the MPI tests RPM in the RPM build root.
            ex rpmbuild --rebuild \
                --define \'_topdir ${RPM_DIR}\' \
                --define \'_name ${MPITESTS_NAME}_${OPENMPI_NAME}_${mpi_comp}\' \
                --define \'path_to_mpihome ${OMPI_PREFIX}\' \
                --define \'buildroot ${BUILD_ROOT}\' \
                --define \'stack_prefix ${STACK_PREFIX}\' \
                $MPITESTS_SRC_RPM
            ex "$MV -f ${RPM_DIR}/RPMS/$build_arch/${MPITESTS_RPM} $RPMS"
            let BUILD_COUNTER++

            unset OPAL_DESTDIR
            LD_LIBRARY_PATH="$LD_LIBRARY_PATH_save"
            export LD_LIBRARY_PATH
        fi
    done
    return 0
}

ib-bonding()
{
    if [[ -z $IB_BONDING_NAME || -z $IB_BONDING_VER ]]; then
        err_echo "Failed to define ib-bonding RPM version"
        return 1
    fi
    ex rpmbuild --rebuild \
                --define \'KVERSION ${K_VER}\' \
                --define \'_topdir ${RPM_DIR}\' \
                --define \'_prefix ${STACK_PREFIX}\' \
		--define \' _release ${RPMK_VER}\' \
                ${IB_BONDING_SRC_RPM}
    
    ex "$MV -f ${RPM_DIR}/RPMS/${build_arch}/${IB_BONDING_NAME}-${IB_BONDING_VER}*${build_arch}.rpm $RPMS"
    let BUILD_COUNTER++
    return 0
}

rds-tools()
{
    if [[ -z $RDS_TOOLS_NAME || -z $RDS_TOOLS_VERSION ]]; then
        err_echo "Failed to define rds-tools RPM version"
        return 1
    fi
    ex rpmbuild --rebuild \
                --define \'_topdir ${RPM_DIR}\' \
                --define \'_mandir ${mandir}\' \
                --define \'_bindir ${STACK_PREFIX}/bin\' ${RDS_TOOLS_SRC_RPM}
    
    ex "$MV -f ${RPM_DIR}/RPMS/${build_arch}/${RDS_TOOLS_NAME}-${RDS_TOOLS_VERSION}*${build_arch}.rpm $RPMS"
    let BUILD_COUNTER++
    return 0
}

build_packages()
{
    # # Install packages required for ${PACKAGE} operation
    # # Like ( swig1.1p5, tcl8.3.2 )
    # install_packages

    echo   
    echo "Building InfiniBand Software RPMs. Please wait..."
    echo
    
    if [[ -n "$OFA_PACKAGES" ]]; then
            # Build ofa
            ofa
    fi        
    
    for package in $EXTRA_PACKAGES
    do
        case $package in
            mpitests)
            # Nothing to be done: RPM created/installed from MVAPICH/Open MPI
            ;;
            *)
            $package
            ;;
        esac
    done

    return 0
}

# Set configuration parameters and perform basic checks
pre_build()
{
        # Check that user is root
        check_user
        
	case $DISTRIBUTION in
		redhat*)
			rh_packages=${RH_PACKAGES// /|}
			installed_rh_packages=$($RPM -qa | grep -E ${rh_packages})
			for inst_pack in ${installed_rh_packages}
			do
				if ( $RPM --queryformat "[%{VENDOR}]\n" -q ${inst_pack} | grep "Red Hat" > $NULL 2>&1 ); then
					echo
					err_echo "Original Red Hat InfiniBand software detected."
					err_echo "You must remove the following software packages before proceeding:"
					echo "${installed_rh_packages}"
					echo
					pass_echo "Run: rpm -e --allmatches $(echo ${installed_rh_packages} | tr -s '\n' ' ')"
					exit 1
				fi
			done
		;;
	esac

#        # Check for InfiniBand software of other vendors
#        local vendors="topspin|iview_fm|ibhost-hpc"
#        local vrpms=""
#        
#        vrpms=$($RPM -qa | grep -E "${vendors}")
#        if [ -n "$vrpms" ]; then
#            echo
#            err_echo "You must remove the following InfiniBand software before continuing:"
#            echo
#            echo "$vrpms"
#            echo
#            exit 9
#        fi

}

# Run Build in interactive mode
interactive()
{
           show_menu "build_menu"
        	
                read ans_build
                case $ans_build in
                        1)
                                view_readme
                        ;;    
                        2)
                                if ! select_packages; then
                                   interactive
                                fi    
                                set_package_deps
                                check_build_dependencies
                                
                                include_ifcfg

                                echo
                                echo "Going to build ${PACKAGE} RPMs"
                                echo "The RPM build process requires a temporary directory"
                                echo
                                read -p "Please enter the temporary directory [${BUILD_ROOT}]:"
                                BUILD_ROOT=${REPLY:-$BUILD_ROOT}
                                
                                if [ "${BUILD_ROOT}" != "${BUILD_ROOT_DFT}" ]; then
                                       BUILD_ROOT=${BUILD_ROOT}/${PACKAGE}
                                fi
                                
                                [ -d $BUILD_ROOT ] && $RM -rf $BUILD_ROOT
                                
                                check_space_req "$BUILD_SPACE_REQ" "$BUILD_ROOT"
                                
                                echo
                                echo "The build process requires the target installation directory."
                                echo
                                echo "   Note: The build process does not create nor touch the target installation directory."
                                echo "         The directory will only be created when you actually install the ${PACKAGE} RPMs."
                                echo
                                read -p "Please enter the ${PACKAGE} installation directory [${STACK_PREFIX}]:"
                                STACK_PREFIX=${REPLY:-$STACK_PREFIX}
                                echo   
                                # Set  parameters with new values
                                . $CWD/build_env.sh
                                echo
                                pass_echo "Chosen temporary directory for ${PACKAGE} RPMs is: $BUILD_ROOT"
                                pass_echo "RPM packages will be stored under: $PKG_SOURCE_DIR/RPMS"
                                pass_echo "${PACKAGE} Software is configured to be installed under: ${STACK_PREFIX}"
                                echo
                                read -p "Do you want to continue? [Y/n]:" ans_r
                                if ! [[ "$ans_r" == "" || "$ans_r" == "y" || "$ans_r" == "Y" || "$ans_r" == "yes" ]]; then
                                    return 1
                                fi
                                
                                # Update CONFIG file
                                perl -ni -e "s@(BUILD_ROOT=).*@\$1${BUILD_ROOT}@; print" $CONFIG
                                perl -ni -e "s@(STACK_PREFIX=).*@\$1${STACK_PREFIX}@; print" $CONFIG

                                if [ ! -d "$BUILD_TMP" ]; then
                                   ex_silent "$MKDIR -p $BUILD_TMP"
                                fi
                                
                                echo
                                pass_echo "It may take up to 40 minutes to complete the installation process"
                                echo   
        
                                
                                if build_packages; then
                                    echo
                                    if [ $BUILD_COUNTER -gt 0 ]; then
                                       pass_echo "$BUILD_COUNTER packages were built"
                                    fi
                                    echo
                                    pass_echo "Build process finished ..."
                                
                                    echo
                                    read -p  "Do you want to remove the temporary build directory ${BUILD_ROOT}? [Y/n]:" ans_r
                                    if [[ "$ans_r" == "" || "$ans_r" == "y" || "$ans_r" == "Y" || "$ans_r" == "yes" ]]; then
                                        ex_silent "$RM -rf $BUILD_ROOT"
                                    fi
                                    
                                    getch
                                fi

                        ;;
                        Q|q)
                                close_log    
                                exit 0
                        ;;
                        *)
                                return 1
                        ;;
                esac
}

# Run Build in unattended mode
unattended()
{

    select_packages
    set_package_deps
    check_build_dependencies
    
    
    if [ ! -d  "$BUILD_ROOT" ]; then
        ex_silent "$MKDIR -p $BUILD_ROOT"
    fi
    
    check_space_req "$BUILD_SPACE_REQ" "$BUILD_ROOT"
    
    if [ ! -d "$BUILD_TMP" ]; then
       ex_silent "$MKDIR -p $BUILD_TMP"
    fi
    
    if build_packages; then
         echo
         if [ $BUILD_COUNTER -gt 0 ]; then
            pass_echo "$BUILD_COUNTER packages were built"
         fi
         if [ $EXISTING_RPMS -gt 0 ]; then
            pass_echo "$EXISTING_RPMS RPMs already exist"
         fi
         echo
         
         pass_echo "Build process finished ..."
    fi
        
    # Remove BUILD_TMP directory
    if [ "$BUILD_ROOT" == "${BUILD_ROOT_DFT}" ]; then
        ex_silent "$RM -rf $BUILD_ROOT"
    fi
    #     if [ $NEED_REBOOT -ne 0 ]; then
    #         echo
    #         echo    "Please reboot the system"
    #         echo
    #     fi
}

###
### Main
###

main()
{

        pre_build
         
        if [ $INTERACTIVE -eq 1 ]; then
            interactive
            if [ "$RPM_DIR" == "$RPM_DIR_DFT" ]; then
                ex_silent "$RM -rf $RPM_DIR"
            fi
       else
            unattended
        fi

        return 0
}

open_log
while true
do
    main
    if [ $INTERACTIVE -eq 0 ]; then
        exit 0
    fi    
done
