1#!/bin/sh 2 3# Multi-build script for testing compilation of all maintained 4# configs of GDB. 5 6# Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. 7 8# Contributed by Richard Earnshaw (rearnsha@arm.com) 9 10# This program is free software; you can redistribute it and/or modify 11# it under the terms of the GNU General Public License as published by 12# the Free Software Foundation; either version 3 of the License, or 13# (at your option) any later version. 14# 15# This program is distributed in the hope that it will be useful, 16# but WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18# GNU General Public License for more details. 19# 20# You should have received a copy of the GNU General Public License 21# along with this program. If not, see <http://www.gnu.org/licenses/>. 22 23# Make certain that the script is not running in an internationalized 24# environment. 25LANG=c ; export LANG 26LC_ALL=c ; export LC_ALL 27 28usage() 29{ 30 cat <<EOF 31Usage: gdb_mbuild.sh [ <options> ... ] <srcdir> <builddir> 32 Options: 33 -j <makejobs> Run <makejobs> in parallel. Passed to make. 34 On a single cpu machine, 2 is recommended. 35 -k Keep going. Do not stop after the first build fails. 36 --keep Keep builds. Do not remove each build when finished. 37 -e <regexp> Regular expression for selecting the targets to build. 38 -f Force rebuild. Even rebuild previously built directories. 39 -v Be more (and more, and more) verbose. 40 Arguments: 41 <srcdir> Source code directory. 42 <builddir> Build directory. 43 Environment variables examined (with default if not defined): 44 MAKE (make)" 45EOF 46 exit 1; 47cat <<NOTYET 48 -b <maxbuilds> Run <maxbuild> builds in parallel. 49 On a single cpu machine, 1 is recommended. 50NOTYET 51} 52 53### COMMAND LINE OPTIONS 54 55makejobs= 56maxbuilds=1 57keepgoing= 58force=false 59targexp="" 60verbose=0 61keep=false 62while test $# -gt 0 63do 64 case "$1" in 65 -j ) 66 # Number of parallel make jobs. 67 shift 68 test $# -ge 1 || usage 69 makejobs="-j $1" 70 ;; 71 -b | -c ) 72 # Number of builds to fire off in parallel. 73 shift 74 test $# -ge 1 || usage 75 maxbuilds=$1 76 ;; 77 -k ) 78 # Should we soldier on after the first build fails? 79 keepgoing=-k 80 ;; 81 --keep ) 82 keep=true 83 ;; 84 -e ) 85 # A regular expression for selecting targets 86 shift 87 test $# -ge 1 || usage 88 targexp="${targexp} -e ${1}" 89 ;; 90 -f ) 91 # Force a rebuild 92 force=true ; 93 ;; 94 -v ) 95 # Be more, and more, and more, verbose 96 verbose=`expr ${verbose} + 1` 97 ;; 98 -* ) usage ;; 99 *) break ;; 100 esac 101 shift 102done 103 104 105### COMMAND LINE PARAMETERS 106 107if test $# -ne 2 108then 109 usage 110fi 111 112# Convert these to absolute directory paths. 113 114# Where the sources live 115srcdir=`cd $1 && /bin/pwd` || exit 1 116 117# Where the builds occur 118builddir=`cd $2 && /bin/pwd` || exit 1 119 120### ENVIRONMENT PARAMETERS 121 122# Version of make to use 123make=${MAKE:-make} 124MAKE=${make} 125export MAKE 126 127 128# Where to look for the list of targets to test 129maintainers=${srcdir}/gdb/MAINTAINERS 130if [ ! -r ${maintainers} ] 131then 132 echo Maintainers file ${maintainers} not found 133 exit 1 134fi 135 136# Get the list of targets and the build options 137alltarg=`cat ${maintainers} | tr -s '[\t]' '[ ]' | sed -n ' 138/^[ ]*[-a-z0-9\.]*[ ]*[(]*--target=.*/ !d 139s/^.*--target=// 140s/).*$// 141h 142:loop 143 g 144 /^[^ ]*,/ !b end 145 s/,[^ ]*// 146 p 147 g 148 s/^[^,]*,// 149 h 150b loop 151:end 152p 153' | if test "${targexp}" = "" 154then 155 grep -v -e broken -e OBSOLETE 156else 157 grep ${targexp} 158fi` 159 160 161# Usage: fail <message> <test-that-should-succeed>. Should the build 162# fail? If the test is true, and we don't want to keep going, print 163# the message and shoot everything in sight and abort the build. 164 165fail () 166{ 167 msg="$1" ; shift 168 if test "$@" 169 then 170 echo "${target}: ${msg}" 171 if test "${keepgoing}" != "" 172 then 173 #exit 1 174 continue 175 else 176 kill $$ 177 exit 1 178 fi 179 fi 180} 181 182 183# Usage: log <level> <logfile>. Write standard input to <logfile> and 184# stdout (if verbose >= level). 185 186log () 187{ 188 if test ${verbose} -ge $1 189 then 190 tee $2 191 else 192 cat > $2 193 fi 194} 195 196 197 198# Warn the user of what is comming, print the list of targets 199 200echo "$alltarg" 201echo "" 202 203 204# For each target, configure, build and test it. 205 206echo "$alltarg" | while read target gdbopts simopts 207do 208 209 trap "exit 1" 1 2 15 210 dir=${builddir}/${target} 211 212 # Should a scratch rebuild be forced, for perhaps the entire 213 # build be skipped? 214 215 if ${force} 216 then 217 echo forcing ${target} ... 218 rm -rf ${dir} 219 elif test -f ${dir} 220 then 221 echo "${target}" 222 continue 223 else 224 echo ${target} ... 225 fi 226 227 # Did the previous configure attempt fail? If it did 228 # restart from scratch. 229 230 if test -d ${dir} -a ! -r ${dir}/Makefile 231 then 232 echo ... removing partially configured ${target} 233 rm -rf ${dir} 234 if test -d ${dir} 235 then 236 echo "${target}: unable to remove directory ${dir}" 237 exit 1 238 fi 239 fi 240 241 # From now on, we're in this target's build directory 242 243 mkdir -p ${dir} 244 cd ${dir} || exit 1 245 246 # Configure, if not already. Should this go back to being 247 # separate and done in parallel? 248 249 if test ! -r Makefile 250 then 251 # Default SIMOPTS to GDBOPTS. 252 test -z "${simopts}" && simopts="${gdbopts}" 253 # The config options 254 __target="--target=${target}" 255 __enable_gdb_build_warnings=`test -z "${gdbopts}" \ 256 || echo "--enable-gdb-build-warnings=${gdbopts}"` 257 __enable_sim_build_warnings=`test -z "${simopts}" \ 258 || echo "--enable-sim-build-warnings=${simopts}"` 259 __configure="${srcdir}/configure \ 260 ${__target} \ 261 ${__enable_gdb_build_warnings} \ 262 ${__enable_sim_build_warnings}" 263 echo ... ${__configure} 264 trap "echo Removing partially configured ${dir} directory ...; rm -rf ${dir}; exit 1" 1 2 15 265 ${__configure} 2>&1 | log 2 Config.log 266 trap "exit 1" 1 2 15 267 fi 268 fail "configure failed" ! -r Makefile 269 270 # Build, if not built. 271 272 if test ! -x gdb/gdb -a ! -x gdb/gdb.exe 273 then 274 # Iff the build fails remove the final build target so that 275 # the follow-on code knows things failed. Stops the follow-on 276 # code thinking that a failed rebuild succedded (executable 277 # left around from previous build). 278 echo ... ${make} ${keepgoing} ${makejobs} ${target} 279 ( ${make} ${keepgoing} ${makejobs} all-gdb || rm -f gdb/gdb gdb/gdb.exe 280 ) 2>&1 | log 1 Build.log 281 fi 282 fail "compile failed" ! -x gdb/gdb -a ! -x gdb/gdb.exe 283 284 # Check that the built GDB can at least print it's architecture. 285 286 echo ... run ${target} 287 rm -f core gdb.core ${dir}/gdb/x 288 cat <<EOF > x 289maint print architecture 290quit 291EOF 292 ./gdb/gdb -batch -nx -x x 2>&1 | log 1 Gdb.log 293 fail "gdb dumped core" -r core -o -r gdb.core 294 fail "gdb printed no output" ! -s Gdb.log 295 grep -e internal-error Gdb.log && fail "gdb panic" 1 296 297 echo ... cleanup ${target} 298 299 # Create a sed script that cleans up the output from GDB. 300 rm -f mbuild.sed 301 touch mbuild.sed || exit 1 302 # Rules to replace <0xNNNN> with the corresponding function's 303 # name. 304 sed -n -e '/<0x0*>/d' -e 's/^.*<0x\([0-9a-f]*\)>.*$/0x\1/p' Gdb.log \ 305 | sort -u \ 306 | while read addr 307 do 308 func="`addr2line -f -e ./gdb/gdb -s ${addr} | sed -n -e 1p`" 309 test ${verbose} -gt 0 && echo "${addr} ${func}" 1>&2 310 echo "s/<${addr}>/<${func}>/g" 311 done >> mbuild.sed 312 # Rules to strip the leading paths off of file names. 313 echo 's/"\/.*\/gdb\//"gdb\//g' >> mbuild.sed 314 # Run the script 315 sed -f mbuild.sed Gdb.log > Mbuild.log 316 317 # Replace the build directory with a file as semaphore that stops 318 # a rebuild. (should the logs be saved?) 319 320 cd ${builddir} 321 322 if ${keep} 323 then 324 : 325 else 326 rm -f ${target}.tmp 327 mv ${target}/Mbuild.log ${target}.tmp 328 rm -rf ${target} 329 mv ${target}.tmp ${target} 330 fi 331 332 # Success! 333 echo ... ${target} built 334 335done 336 337exit 0 338