#!/bin/sh

#  Multi-build script for testing compilation of all maintained
#  configs of GDB.

#  Copyright (C) 2002, 2003, 2007, 2008, 2009, 2010
#  Free Software Foundation, Inc.

#  Contributed by Richard Earnshaw  (rearnsha@arm.com)

#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Make certain that the script is not running in an internationalized
# environment.
LANG=c ; export LANG
LC_ALL=c ; export LC_ALL

usage()
{
    cat <<EOF
Usage: gdb_mbuild.sh [ <options> ... ] <srcdir> <builddir>
 Options:
   -j <makejobs>  Run <makejobs> in parallel.  Passed to make.
	          On a single cpu machine, 2 is recommended.
   -k             Keep going.  Do not stop after the first build fails.
   --keep         Keep builds.  Do not remove each build when finished.
   -e <regexp>    Regular expression for selecting the targets to build.
   -f             Force rebuild.  Even rebuild previously built directories.
   -v             Be more (and more, and more) verbose.
 Arguments:
   <srcdir>       Source code directory.
   <builddir>     Build directory.
 Environment variables examined (with default if not defined):
   MAKE (make)"
EOF
    exit 1;
cat <<NOTYET
  -b <maxbuilds> Run <maxbuild> builds in parallel.
		 On a single cpu machine, 1 is recommended.
NOTYET
}

### COMMAND LINE OPTIONS

makejobs=
maxbuilds=1
keepgoing=
force=false
targexp=""
verbose=0
keep=false
while test $# -gt 0
do
    case "$1" in
    -j )
	# Number of parallel make jobs.
	shift
	test $# -ge 1 || usage
	makejobs="-j $1"
	;;
    -b | -c )
	# Number of builds to fire off in parallel.
	shift
	test $# -ge 1 || usage
	maxbuilds=$1
	;;
    -k )
	# Should we soldier on after the first build fails?
	keepgoing=-k
	;;
    --keep )
        keep=true
	;;
    -e )
	# A regular expression for selecting targets
	shift
	test $# -ge 1 || usage
	targexp="${targexp} -e ${1}"
	;;
    -f )
	# Force a rebuild
	force=true ;
	;;
    -v )
	# Be more, and more, and more, verbose
	verbose=`expr ${verbose} + 1`
	;;
    -* ) usage ;;
    *) break ;;
    esac
    shift
done


### COMMAND LINE PARAMETERS

if test $# -ne 2
then
    usage
fi

# Convert these to absolute directory paths.

# Where the sources live
srcdir=`cd $1 && /bin/pwd` || exit 1

# Where the builds occur
builddir=`cd $2 && /bin/pwd` || exit 1

### ENVIRONMENT PARAMETERS

# Version of make to use
make=${MAKE:-make}
MAKE=${make}
export MAKE


# Where to look for the list of targets to test
maintainers=${srcdir}/gdb/MAINTAINERS
if [ ! -r ${maintainers} ]
then
    echo Maintainers file ${maintainers} not found
    exit 1
fi

# Get the list of targets and the build options
alltarg=`cat ${maintainers} | tr -s '[\t]' '[ ]' | sed -n '
/^[ ]*[-a-z0-9\.]*[ ]*[(]*--target=.*/ !d
s/^.*--target=//
s/).*$//
h
:loop
  g
  /^[^ ]*,/ !b end
  s/,[^ ]*//
  p
  g
  s/^[^,]*,//
  h
b loop
:end
p
' | if test "${targexp}" = ""
then
    grep -v -e broken -e OBSOLETE
else
    grep ${targexp}
fi`


# Usage: fail <message> <test-that-should-succeed>.  Should the build
# fail?  If the test is true, and we don't want to keep going, print
# the message and shoot everything in sight and abort the build.

fail ()
{
    msg="$1" ; shift
    if test "$@"
    then
	echo "${target}: ${msg}"
	if test "${keepgoing}" != ""
	then
	    #exit 1
	    continue
	else
	    kill $$
	    exit 1
	fi
    fi
}


# Usage: log <level> <logfile>.  Write standard input to <logfile> and
# stdout (if verbose >= level).

log ()
{
    if test ${verbose} -ge $1
    then
	tee $2
    else
	cat > $2
    fi
}



# Warn the user of what is comming, print the list of targets

echo "$alltarg"
echo ""


# For each target, configure, build and test it.

echo "$alltarg" | while read target gdbopts simopts
do

    trap "exit 1"  1 2 15
    dir=${builddir}/${target}

    # Should a scratch rebuild be forced, for perhaps the entire
    # build be skipped?

    if ${force}
    then
	echo forcing ${target} ...
	rm -rf ${dir}
    elif test -f ${dir}
    then
	echo "${target}"
	continue
    else
	echo ${target} ...
    fi

    # Did the previous configure attempt fail?  If it did
    # restart from scratch.

    if test -d ${dir} -a ! -r ${dir}/Makefile
    then
	echo ... removing partially configured ${target}
	rm -rf ${dir}
	if test -d ${dir}
	then
	    echo "${target}: unable to remove directory ${dir}"
	    exit 1
	fi
    fi

    # From now on, we're in this target's build directory

    mkdir -p ${dir}
    cd ${dir} || exit 1

    # Configure, if not already.  Should this go back to being
    # separate and done in parallel?

    if test ! -r Makefile
    then
	# Default SIMOPTS to GDBOPTS.
	test -z "${simopts}" && simopts="${gdbopts}"
	# The config options
	__target="--target=${target}"
	__enable_gdb_build_warnings=`test -z "${gdbopts}" \
	    || echo "--enable-gdb-build-warnings=${gdbopts}"`
	__enable_sim_build_warnings=`test -z "${simopts}" \
	    || echo "--enable-sim-build-warnings=${simopts}"`
	__configure="${srcdir}/configure \
	    ${__target} \
	    ${__enable_gdb_build_warnings} \
	    ${__enable_sim_build_warnings}"
	echo ... ${__configure}
	trap "echo Removing partially configured ${dir} directory ...; rm -rf ${dir}; exit 1" 1 2 15
	${__configure} 2>&1 | log 2 Config.log
	trap "exit 1"  1 2 15
    fi
    fail "configure failed" ! -r Makefile
 
    # Build, if not built.

    if test ! -x gdb/gdb -a ! -x gdb/gdb.exe
    then
	# Iff the build fails remove the final build target so that
	# the follow-on code knows things failed.  Stops the follow-on
	# code thinking that a failed rebuild succedded (executable
	# left around from previous build).
	echo ... ${make} ${keepgoing} ${makejobs} ${target}
	( ${make} ${keepgoing} ${makejobs} all-gdb || rm -f gdb/gdb gdb/gdb.exe
	) 2>&1 | log 1 Build.log
    fi
    fail "compile failed" ! -x gdb/gdb -a ! -x gdb/gdb.exe
 
    # Check that the built GDB can at least print it's architecture.

    echo ... run ${target}
    rm -f core gdb.core ${dir}/gdb/x
    cat <<EOF > x
maint print architecture
quit
EOF
    ./gdb/gdb -batch -nx -x x 2>&1 | log 1 Gdb.log
    fail "gdb dumped core" -r core -o -r gdb.core
    fail "gdb printed no output" ! -s Gdb.log
    grep -e internal-error Gdb.log && fail "gdb panic" 1

    echo ... cleanup ${target}

    # Create a sed script that cleans up the output from GDB.
    rm -f mbuild.sed
    touch mbuild.sed || exit 1
    # Rules to replace <0xNNNN> with the corresponding function's
    # name.
    sed -n -e '/<0x0*>/d' -e 's/^.*<0x\([0-9a-f]*\)>.*$/0x\1/p' Gdb.log \
    | sort -u \
    | while read addr
    do
	func="`addr2line -f -e ./gdb/gdb -s ${addr} | sed -n -e 1p`"
	test ${verbose} -gt 0 && echo "${addr} ${func}" 1>&2
	echo "s/<${addr}>/<${func}>/g"
    done >> mbuild.sed
    # Rules to strip the leading paths off of file names.
    echo 's/"\/.*\/gdb\//"gdb\//g' >> mbuild.sed
    # Run the script
    sed -f mbuild.sed Gdb.log > Mbuild.log

    # Replace the build directory with a file as semaphore that stops
    # a rebuild. (should the logs be saved?)

    cd ${builddir}

    if ${keep}
    then
	:
    else
	rm -f ${target}.tmp
	mv ${target}/Mbuild.log ${target}.tmp
	rm -rf ${target}
	mv ${target}.tmp ${target}
    fi

    # Success!
    echo ... ${target} built

done

exit 0
