#!/bin/sh

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

#  Copyright (C) 2002-2020 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 coming, 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 succeeded (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
