Automatic date update in version.in
[external/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-2019 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.
25 LANG=c ; export LANG
26 LC_ALL=c ; export LC_ALL
27
28 usage()
29 {
30     cat <<EOF
31 Usage: 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)"
45 EOF
46     exit 1;
47 cat <<NOTYET
48   -b <maxbuilds> Run <maxbuild> builds in parallel.
49                  On a single cpu machine, 1 is recommended.
50 NOTYET
51 }
52
53 ### COMMAND LINE OPTIONS
54
55 makejobs=
56 maxbuilds=1
57 keepgoing=
58 force=false
59 targexp=""
60 verbose=0
61 keep=false
62 while test $# -gt 0
63 do
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
102 done
103
104
105 ### COMMAND LINE PARAMETERS
106
107 if test $# -ne 2
108 then
109     usage
110 fi
111
112 # Convert these to absolute directory paths.
113
114 # Where the sources live
115 srcdir=`cd $1 && /bin/pwd` || exit 1
116
117 # Where the builds occur
118 builddir=`cd $2 && /bin/pwd` || exit 1
119
120 ### ENVIRONMENT PARAMETERS
121
122 # Version of make to use
123 make=${MAKE:-make}
124 MAKE=${make}
125 export MAKE
126
127
128 # Where to look for the list of targets to test
129 maintainers=${srcdir}/gdb/MAINTAINERS
130 if [ ! -r ${maintainers} ]
131 then
132     echo Maintainers file ${maintainers} not found
133     exit 1
134 fi
135
136 # Get the list of targets and the build options
137 alltarg=`cat ${maintainers} | tr -s '[\t]' '[ ]' | sed -n '
138 /^[ ]*[-a-z0-9\.]*[ ]*[(]*--target=.*/ !d
139 s/^.*--target=//
140 s/).*$//
141 h
142 :loop
143   g
144   /^[^ ]*,/ !b end
145   s/,[^ ]*//
146   p
147   g
148   s/^[^,]*,//
149   h
150 b loop
151 :end
152 p
153 ' | if test "${targexp}" = ""
154 then
155     grep -v -e broken -e OBSOLETE
156 else
157     grep ${targexp}
158 fi`
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
165 fail ()
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
186 log ()
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 coming, print the list of targets
199
200 echo "$alltarg"
201 echo ""
202
203
204 # For each target, configure, build and test it.
205
206 echo "$alltarg" | while read target gdbopts simopts
207 do
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 succeeded (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
289 maint print architecture
290 quit
291 EOF
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
335 done
336
337 exit 0