#!/bin/sh
# Top level jenkins script to build for promoted AMDT libraries, and verify
# that the built results have all of the expected bits.
# 
# Usage:
#   $0 [<version number>] [scratch]
#   <version number>:
#       An optional parameter is the build number.
#       When the build number is 0 (zero) only the debug version is built
#       If no build number is passed in, do not modify the version file
#   scratch:
#       An optional parameter.  When passed in, the script will run
#       scons <stuff> -c to perform a clean prior to the normal build
#       Thus, a scratch build
#

#
# Assumptions:
# - WORKSPACE environment variable to be set
#

export AMD_PERFORCE_ROOT=$WORKSPACE
export AMD_AMDLIBS=$AMD_PERFORCE_ROOT/main/Common/Lib/AMD
export AMD_EXTLIBS=$AMD_PERFORCE_ROOT/main/Common/Lib/Ext
export AMD_OUTPUT=$AMD_PERFORCE_ROOT/main/
export AMD_CODEXL=$AMD_PERFORCE_ROOT/main/CodeXL
export AMD_WS_LINUX_UTIL_DIR=${AMD_CODEXL}/Util/linux

export NARGS=$#
export VERSION_MAJOR=6
export VERSION_MINOR=3
export BUILD_VERSION=0
export VERSION_UPDATE=0
export VERSIONINFO_FILE=${AMD_CODEXL}/../CommonProjects/VersionInfo/VersionInfo.h

export CONFIG_FILE_BASE=CodeXL-Linux

NUM_ERRORS=0
BUILD_DEBUG_RC=0
BUILD_RELEASE_RC=0
ONLY_BUILD_DEBUG=0
IS_SCRATCH_BUILD=0
GPUP_BACKEND_BUILD_NUM=0

# A utility bit of code - simply does a scons -c over both builds
NukeIt()
{
    ARCHTYPE=$1
    BUILD_OPTS="--debug=time -j ${NCPUS} CXL_build=release CXL_arch=${ARCHTYPE} -c"
    sh $AMD_WS_LINUX_UTIL_DIR/buildCodeXLCpuLinux ${BUILD_OPTS} > ${WORKSPACE}/CodeXL-Linux_${ARCHTYPE}_release.log 2>&1
    BUILD_OPTS="-j ${NCPUS} CXL_build=debug CXL_arch=${ARCHTYPE} -c"
    sh $AMD_WS_LINUX_UTIL_DIR/buildCodeXLCpuLinux ${BUILD_OPTS} > ${WORKSPACE}/CodeXL-Linux_${ARCHTYPE}_debug.log 2>&1
}

# The bulk of the work is done here
# The only parameter is the architecture name (x86 or x86_64)
RunTheBuild()
{
    ARCHTYPE=$1

    cd $AMD_WS_LINUX_UTIL_DIR

    if [ ${ONLY_BUILD_DEBUG} -eq 0 ]
    then
        # BUILD RELEASE when the version is non-zero
        BUILD_OPTS="--debug=time -j ${NCPUS} CXL_build=release CXL_arch=${ARCHTYPE}"
        echo ""
        echo "========== Timing start: `date` ============================================"
        echo "Building: sh $AMD_WS_LINUX_UTIL_DIR/buildCodeXLCpuLinux ${BUILD_OPTS}"
        sh $AMD_WS_LINUX_UTIL_DIR/buildCodeXLCpuLinux ${BUILD_OPTS} > ${WORKSPACE}/CodeXL-Linux_${ARCHTYPE}_release.log 2>&1
        BUILD_RELEASE_RC=$?
        echo "========== Timing end: `date` =============================================="
    fi

    # BUILD DEBUG
    BUILD_OPTS="-j ${NCPUS} CXL_build=debug CXL_arch=${ARCHTYPE}"
    echo ""
    echo "========== Timing start: `date` ============================================"
    echo "Building: sh $AMD_WS_LINUX_UTIL_DIR/buildCodeXLCpuLinux ${BUILD_OPTS}"
    sh $AMD_WS_LINUX_UTIL_DIR/buildCodeXLCpuLinux ${BUILD_OPTS} > ${WORKSPACE}/CodeXL-Linux_${ARCHTYPE}_debug.log 2>&1
    BUILD_DEBUG_RC=$?
    echo "========== Timing end: `date` =============================================="

    NUM_ERRORS=`expr ${NUM_ERRORS} + ${BUILD_RELEASE_RC} + ${BUILD_DEBUG_RC}`
    if [ ${BUILD_RELEASE_RC} -ne 0 -o ${BUILD_DEBUG_RC} -ne 0 ]
    then
        echo "*** ERROR ***"
        echo "*** The debug build had ${BUILD_DEBUG_RC} errors ***"
        echo "*** The release build had ${BUILD_RELEASE_RC} errors ***"
    else
	echo "Build succeeded"
    fi

}

PackageTheBuild()
{
    echo "---- TIMING: Packaging start: `date`"  

    cd $AMD_PERFORCE_ROOT/main

    # un-tar the GPU Profiler backend if it exists
    if [ ${GPUP_BACKEND_BUILD_NUM} -ne 0 ]
    then
        cd $AMD_PERFORCE_ROOT/main/Output_x86_64/release/bin
        GPUP_BACKEND_TARBALL=GPUProfilingBackendCodeXL-v2.6.$GPUP_BACKEND_BUILD_NUM.tgz
        GPUP_BACKEND_INTERNAL_TARBALL=GPUProfilingBackendCodeXLInternal-v2.6.$GPUP_BACKEND_BUILD_NUM.tgz
        if [ -e $GPUP_BACKEND_TARBALL ]
        then
            tar xzf $GPUP_BACKEND_TARBALL
            rm -f $GPUP_BACKEND_TARBALL
        fi
        if [ -e $GPUP_BACKEND_INTERNAL_TARBALL ]
        then
            # tar xzf $GPUP_BACKEND_INTERNAL_TARBALL
            rm -f $GPUP_BACKEND_INTERNAL_TARBALL
        fi
        cd $AMD_PERFORCE_ROOT/main
    fi

    # rm -rf Output_x86/release/obj
    # rm -rf Output_x86/debug/obj
    rm -rf Output_x86_64/release/obj
    rm -rf Output_x86_64/debug/obj

    #mkdir -p CodeXL-Full/Output_x86
    #cp -drf Output_x86/release CodeXL-Full/Output_x86
    mkdir -p CodeXL-Full/Output_x86_64
    cp -drf Output_x86_64/release CodeXL-Full/Output_x86_64
    tar czf CodeXL-Full.tar.gz CodeXL-Full

    echo "---- TIMING: Packaging end: `date`"  
}

UsageAndExit()
{
    echo "Usage: $0 [quick] [build-num BUILDNUM] [scratch] [gpup-backend-build-num GPUPBUILDNUM] [help]"
    echo "If quick is specified a compile-only (x86_64, debug) build is performed."
    echo "    No packaging is performed at all in this case, no matter what"
    echo "If BUILDNUM is 0 (zero) a quick build is performed."
    echo "If scratch is specified, the build is from scratch (not the default)"
    echo "If gpup-backend-build-num is specified, then the packaging portion will try to un-tar the tgz file from the upstream Jenkins build with number GPUPBUILDNUM"
    echo "If help is specified, then this message is displayed"
    exit 1
}

########################## MAIN #############################

FOUND_VERNO=0
if [ ${NARGS} -eq 0 ]
then
    UsageAndExit
fi

if [ ${NARGS} -gt 7 ]
then
    UsageAndExit
fi

while [ "$*" != "" ]
do
   if [ "$1" = "scratch" ]
   then
      IS_SCRATCH_BUILD=1
   elif [ "$1" = "quick" ]
   then
      FOUND_VERNO=1
      BUILD_VERSION=0
   elif [ "$1" = "build-num" ]
   then
      shift
      FOUND_VERNO=1
      BUILD_VERSION=$1
   elif [ "$1" = "gpup-backend-build-num" ]
   then
      shift
      GPUP_BACKEND_BUILD_NUM="$1"
   elif [ "$1" = "help" ]
   then
      UsageAndExit
   else
      UsageAndExit
   fi
   shift
done

# FOUND_VERNO and IS_SCRATCH_BUILD have the correct (boolean) values
# at this point
if [ ${FOUND_VERNO} -eq 1 ]
then
    if [ "${BUILD_VERSION}" = "0" ]
    then
        ONLY_BUILD_DEBUG=1
    fi
    # Edit the version file - in situ.  A different approach would be to
    # dynamically generate said file (perhaps in the future)
    chmod 666 ${VERSIONINFO_FILE}
    CHM_RC=$?
    NUM_ERRORS=`expr ${NUM_ERRORS} + ${CHM_RC}`
    if [ ${CHM_RC} -ne 0 ]
    then
        echo "*** ERROR ***"
        echo "*** Unable to modify ${VERSIONINFO_FILE} ***"
        echo "*** The default version numbers will be used ***"
    else
        # The pattern to match on in the file is 1,0,0,0
        # meaning major,minor,build,update
        OLDPAT=0,0,0,0
        NEWPAT=${VERSION_MAJOR},${VERSION_MINOR},${BUILD_VERSION},${VERSION_UPDATE}
        # And mangle
        sed -i "s/${OLDPAT}/${NEWPAT}/g" ${VERSIONINFO_FILE}
        SED_RC=$?
        NUM_ERRORS=`expr ${NUM_ERRORS} + ${SED_RC}`
        if [ ${SED_RC} -ne 0 ]
        then
            echo "*** ERROR ***"
            echo "*** Unable to modify fields in ${VERSIONINFO_FILE} ***"
            echo "*** The build may fail due to compile errors ***"
        fi
    fi
fi

# Figure out how much parallelism we can use.  2x cores on a really fast system
# The build system is pretty heavily used - both for tests and builds, so dial
# this back to be just the number of cores
NCPUS=`grep processor /proc/cpuinfo | wc | awk '{print $1}'`
if [ $? -ne 0 ]
then
    echo "Warning - Unable to determine the number of CPU cores - assuming one core"
    NCPUS=1
fi
# If the system is capable of more cores, re-enable this
NCPUS=`expr ${NCPUS} \* 2`
echo "Building with -j ${NCPUS}"

#
# BUILDING 
#

# Clean up everything from past builds if this is a scratch build
if [ ${IS_SCRATCH_BUILD} -ne 0 ]
then
    NukeIt x86_64
fi
RunTheBuild x86_64

if [ ${NUM_ERRORS} -ne 0 ]
then
    echo "*** The build failed ***"
    exit 1
else
    PackageTheBuild
    echo "*** The build succeeded ***"
    exit 0
fi
