#!/bin/sh

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

#  Copyright (C) 2002-2003, 2007-2012 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
