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