Fix bug in test-release.sh where the script would not exit if any
[oota-llvm.git] / utils / release / test-release.sh
1 #!/usr/bin/env bash
2 #===-- test-release.sh - Test the LLVM release candidates ------------------===#
3 #
4 #                     The LLVM Compiler Infrastructure
5 #
6 # This file is distributed under the University of Illinois Open Source
7 # License.
8 #
9 #===------------------------------------------------------------------------===#
10 #
11 # Download, build, and test the release candidate for an LLVM release.
12 #
13 #===------------------------------------------------------------------------===#
14
15 if [ `uname -s` = "FreeBSD" ]; then
16     MAKE=gmake
17 else
18     MAKE=make
19 fi
20
21 projects="llvm cfe compiler-rt libcxx libcxxabi test-suite clang-tools-extra"
22
23 # Base SVN URL for the sources.
24 Base_url="http://llvm.org/svn/llvm-project"
25
26 Release=""
27 Release_no_dot=""
28 RC=""
29 Triple=""
30 use_gzip="no"
31 do_checkout="yes"
32 do_clang="yes"
33 do_64bit="yes"
34 do_debug="no"
35 do_asserts="no"
36 do_compare="yes"
37 BuildDir="`pwd`"
38 BuildTriple=""
39
40 function usage() {
41     echo "usage: `basename $0` -release X.Y.Z -rc NUM [OPTIONS]"
42     echo ""
43     echo " -release X.Y.Z       The release version to test."
44     echo " -rc NUM              The pre-release candidate number."
45     echo " -final               The final release candidate."
46     echo " -triple TRIPLE       The target triple for this machine."
47     echo " -j NUM               Number of compile jobs to run. [default: 3]"
48     echo " -build-dir DIR       Directory to perform testing in. [default: pwd]"
49     echo " -no-checkout         Don't checkout the sources from SVN."
50     echo " -no-64bit            Don't test the 64-bit version. [default: yes]"
51     echo " -disable-clang       Do not test clang. [default: enable]"
52     echo " -test-debug          Test the debug build. [default: no]"
53     echo " -test-asserts        Test with asserts on. [default: no]"
54     echo " -no-compare-files    Don't test that phase 2 and 3 files are identical."
55     echo " -use-gzip            Use gzip instead of xz."
56     echo " -build-triple TRIPLE The build triple for this machine"
57     echo "                      [default: use config.guess]"
58 }
59
60 while [ $# -gt 0 ]; do
61     case $1 in
62         -release | --release )
63             shift
64             Release="$1"
65             Release_no_dot="`echo $1 | sed -e 's,\.,,g'`"
66             ;;
67         -rc | --rc | -RC | --RC )
68             shift
69             RC="rc$1"
70             ;;
71         -final | --final )
72             RC=final
73             ;;
74         -triple | --triple )
75             shift
76             Triple="$1"
77             ;;
78         -build-triple | --build-triple )
79             shift
80             BuildTriple="$1"
81             ;;
82         -j* )
83             NumJobs="`echo $1 | sed -e 's,-j\([0-9]*\),\1,g'`"
84             if [ -z "$NumJobs" ]; then
85                 shift
86                 NumJobs="$1"
87             fi
88             ;;
89         -build-dir | --build-dir | -builddir | --builddir )
90             shift
91             BuildDir="$1"
92             ;;
93         -no-checkout | --no-checkout )
94             do_checkout="no"
95             ;;
96         -no-64bit | --no-64bit )
97             do_64bit="no"
98             ;;
99         -disable-clang | --disable-clang )
100             do_clang="no"
101             ;;
102         -test-debug | --test-debug )
103             do_debug="yes"
104             ;;
105         -test-asserts | --test-asserts )
106             do_asserts="yes"
107             ;;
108         -no-compare-files | --no-compare-files )
109             do_compare="no"
110             ;;
111         -use-gzip | --use-gzip )
112             use_gzip="yes"
113             ;;
114         -help | --help | -h | --h | -\? )
115             usage
116             exit 0
117             ;;
118         * )
119             echo "unknown option: $1"
120             usage
121             exit 1
122             ;;
123     esac
124     shift
125 done
126
127 # Check required arguments.
128 if [ -z "$Release" ]; then
129     echo "error: no release number specified"
130     exit 1
131 fi
132 if [ -z "$RC" ]; then
133     echo "error: no release candidate number specified"
134     exit 1
135 fi
136 if [ -z "$Triple" ]; then
137     echo "error: no target triple specified"
138     exit 1
139 fi
140
141 # Figure out how many make processes to run.
142 if [ -z "$NumJobs" ]; then
143     NumJobs=`sysctl -n hw.activecpu 2> /dev/null || true`
144 fi
145 if [ -z "$NumJobs" ]; then
146     NumJobs=`sysctl -n hw.ncpu 2> /dev/null || true`
147 fi
148 if [ -z "$NumJobs" ]; then
149     NumJobs=`grep -c processor /proc/cpuinfo 2> /dev/null || true`
150 fi
151 if [ -z "$NumJobs" ]; then
152     NumJobs=3
153 fi
154
155 # Go to the build directory (may be different from CWD)
156 BuildDir=$BuildDir/$RC
157 mkdir -p $BuildDir
158 cd $BuildDir
159
160 # Location of log files.
161 LogDir=$BuildDir/logs
162 mkdir -p $LogDir
163
164 # Final package name.
165 Package=clang+llvm-$Release
166 if [ $RC != "final" ]; then
167   Package=$Package-$RC
168 fi
169 Package=$Package-$Triple
170
171 # Make sure that a required program is available
172 function check_program_exists() {
173   local program="$1"
174   if ! type -P $program > /dev/null 2>&1 ; then
175     echo "program '$1' not found !"
176     exit 1
177   fi
178 }
179
180 if [ `uname -s` != "Darwin" ]; then
181   check_program_exists 'chrpath'
182   check_program_exists 'file'
183   check_program_exists 'objdump'
184 fi
185
186 # Make sure that the URLs are valid.
187 function check_valid_urls() {
188     for proj in $projects ; do
189         echo "# Validating $proj SVN URL"
190
191         if ! svn ls $Base_url/$proj/tags/RELEASE_$Release_no_dot/$RC > /dev/null 2>&1 ; then
192             echo "$proj $Release release candidate $RC doesn't exist!"
193             exit 1
194         fi
195     done
196 }
197
198 # Export sources to the build directory.
199 function export_sources() {
200     check_valid_urls
201
202     for proj in $projects ; do
203         echo "# Exporting $proj $Release-$RC sources"
204         if ! svn export -q $Base_url/$proj/tags/RELEASE_$Release_no_dot/$RC $proj.src ; then
205             echo "error: failed to export $proj project"
206             exit 1
207         fi
208     done
209
210     echo "# Creating symlinks"
211     cd $BuildDir/llvm.src/tools
212     if [ ! -h clang ]; then
213         ln -s ../../cfe.src clang
214     fi
215     cd $BuildDir/llvm.src/tools/clang/tools
216     if [ ! -h clang-tools-extra ]; then
217         ln -s ../../../../clang-tools-extra.src extra
218     fi
219     cd $BuildDir/llvm.src/projects
220     if [ ! -h test-suite ]; then
221         ln -s ../../test-suite.src test-suite
222     fi
223     if [ ! -h compiler-rt ]; then
224         ln -s ../../compiler-rt.src compiler-rt
225     fi
226     if [ ! -h libcxx ]; then
227         ln -s ../../libcxx.src libcxx
228     fi
229     if [ ! -h libcxxabi ]; then
230         ln -s ../../libcxxabi.src libcxxabi
231     fi
232     cd $BuildDir
233 }
234
235 function configure_llvmCore() {
236     Phase="$1"
237     Flavor="$2"
238     ObjDir="$3"
239     InstallDir="$4"
240
241     case $Flavor in
242         Release | Release-64 )
243             Optimized="yes"
244             Assertions="no"
245             ;;
246         Release+Asserts )
247             Optimized="yes"
248             Assertions="yes"
249             ;;
250         Debug )
251             Optimized="no"
252             Assertions="yes"
253             ;;
254         * )
255             echo "# Invalid flavor '$Flavor'"
256             echo ""
257             return
258             ;;
259     esac
260
261     echo "# Using C compiler: $c_compiler"
262     echo "# Using C++ compiler: $cxx_compiler"
263
264     build_triple_option="${BuildTriple:+--build=$BuildTriple}"
265
266     cd $ObjDir
267     echo "# Configuring llvm $Release-$RC $Flavor"
268     echo "# $BuildDir/llvm.src/configure --prefix=$InstallDir \
269         --enable-optimized=$Optimized \
270         --enable-assertions=$Assertions \
271         --disable-timestamps \
272         $build_triple_option"
273     env CC="$c_compiler" CXX="$cxx_compiler" \
274         $BuildDir/llvm.src/configure --prefix=$InstallDir \
275         --enable-optimized=$Optimized \
276         --enable-assertions=$Assertions \
277         --disable-timestamps \
278         $build_triple_option \
279         2>&1 | tee $LogDir/llvm.configure-Phase$Phase-$Flavor.log
280     cd $BuildDir
281 }
282
283 function build_llvmCore() {
284     Phase="$1"
285     Flavor="$2"
286     ObjDir="$3"
287     ExtraOpts=""
288
289     if [ "$Flavor" = "Release-64" ]; then
290         ExtraOpts="EXTRA_OPTIONS=-m64"
291     fi
292
293     cd $ObjDir
294     echo "# Compiling llvm $Release-$RC $Flavor"
295     echo "# ${MAKE} -j $NumJobs VERBOSE=1 $ExtraOpts"
296     ${MAKE} -j $NumJobs VERBOSE=1 $ExtraOpts \
297         2>&1 | tee $LogDir/llvm.make-Phase$Phase-$Flavor.log
298
299     echo "# Installing llvm $Release-$RC $Flavor"
300     echo "# ${MAKE} install"
301     ${MAKE} install \
302         2>&1 | tee $LogDir/llvm.install-Phase$Phase-$Flavor.log
303     cd $BuildDir
304 }
305
306 function test_llvmCore() {
307     Phase="$1"
308     Flavor="$2"
309     ObjDir="$3"
310
311     cd $ObjDir
312     ${MAKE} -k check-all \
313         2>&1 | tee $LogDir/llvm.check-Phase$Phase-$Flavor.log
314     ${MAKE} -k unittests \
315         2>&1 | tee $LogDir/llvm.unittests-Phase$Phase-$Flavor.log
316     cd $BuildDir
317 }
318
319 # Clean RPATH. Libtool adds the build directory to the search path, which is
320 # not necessary --- and even harmful --- for the binary packages we release.
321 function clean_RPATH() {
322   if [ `uname -s` = "Darwin" ]; then
323     return
324   fi
325   local InstallPath="$1"
326   for Candidate in `find $InstallPath/{bin,lib} -type f`; do
327     if file $Candidate | grep ELF | egrep 'executable|shared object' > /dev/null 2>&1 ; then
328       rpath=`objdump -x $Candidate | grep 'RPATH' | sed -e's/^ *RPATH *//'`
329       if [ -n "$rpath" ]; then
330         newrpath=`echo $rpath | sed -e's/.*\(\$ORIGIN[^:]*\).*/\1/'`
331         chrpath -r $newrpath $Candidate 2>&1 > /dev/null 2>&1
332       fi
333     fi
334   done
335 }
336
337 # Create a package of the release binaries.
338 function package_release() {
339     cwd=`pwd`
340     cd $BuildDir/Phase3/Release
341     mv llvmCore-$Release-$RC.install $Package
342     if [ "$use_gzip" = "yes" ]; then
343       tar cfz $BuildDir/$Package.tar.gz $Package
344     else
345       tar cfJ $BuildDir/$Package.tar.xz $Package
346     fi
347     mv $Package llvmCore-$Release-$RC.install
348     cd $cwd
349 }
350
351 # Exit if any command fails
352 # Note: pipefail is necessary for running build commands through
353 # a pipe (i.e. it changes the output of ``false | tee /dev/null ; echo $?``)
354 set -e
355 set -o pipefail
356
357 if [ "$do_checkout" = "yes" ]; then
358     export_sources
359 fi
360
361 (
362 Flavors="Release"
363 if [ "$do_debug" = "yes" ]; then
364     Flavors="Debug $Flavors"
365 fi
366 if [ "$do_asserts" = "yes" ]; then
367     Flavors="$Flavors Release+Asserts"
368 fi
369 if [ "$do_64bit" = "yes" ]; then
370     Flavors="$Flavors Release-64"
371 fi
372
373 for Flavor in $Flavors ; do
374     echo ""
375     echo ""
376     echo "********************************************************************************"
377     echo "  Release:     $Release-$RC"
378     echo "  Build:       $Flavor"
379     echo "  System Info: "
380     echo "    `uname -a`"
381     echo "********************************************************************************"
382     echo ""
383
384     c_compiler="$CC"
385     cxx_compiler="$CXX"
386
387     llvmCore_phase1_objdir=$BuildDir/Phase1/$Flavor/llvmCore-$Release-$RC.obj
388     llvmCore_phase1_installdir=$BuildDir/Phase1/$Flavor/llvmCore-$Release-$RC.install
389
390     llvmCore_phase2_objdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-$RC.obj
391     llvmCore_phase2_installdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-$RC.install
392
393     llvmCore_phase3_objdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-$RC.obj
394     llvmCore_phase3_installdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-$RC.install
395
396     rm -rf $llvmCore_phase1_objdir
397     rm -rf $llvmCore_phase1_installdir
398
399     rm -rf $llvmCore_phase2_objdir
400     rm -rf $llvmCore_phase2_installdir
401
402     rm -rf $llvmCore_phase3_objdir
403     rm -rf $llvmCore_phase3_installdir
404
405     mkdir -p $llvmCore_phase1_objdir
406     mkdir -p $llvmCore_phase1_installdir
407
408     mkdir -p $llvmCore_phase2_objdir
409     mkdir -p $llvmCore_phase2_installdir
410
411     mkdir -p $llvmCore_phase3_objdir
412     mkdir -p $llvmCore_phase3_installdir
413
414     ############################################################################
415     # Phase 1: Build llvmCore and clang
416     echo "# Phase 1: Building llvmCore"
417     configure_llvmCore 1 $Flavor \
418         $llvmCore_phase1_objdir $llvmCore_phase1_installdir
419     build_llvmCore 1 $Flavor \
420         $llvmCore_phase1_objdir
421     clean_RPATH $llvmCore_phase1_installdir
422
423     # Test clang
424     if [ "$do_clang" = "yes" ]; then
425         ########################################################################
426         # Phase 2: Build llvmCore with newly built clang from phase 1.
427         c_compiler=$llvmCore_phase1_installdir/bin/clang
428         cxx_compiler=$llvmCore_phase1_installdir/bin/clang++
429         echo "# Phase 2: Building llvmCore"
430         configure_llvmCore 2 $Flavor \
431             $llvmCore_phase2_objdir $llvmCore_phase2_installdir
432         build_llvmCore 2 $Flavor \
433             $llvmCore_phase2_objdir
434         clean_RPATH $llvmCore_phase2_installdir
435
436         ########################################################################
437         # Phase 3: Build llvmCore with newly built clang from phase 2.
438         c_compiler=$llvmCore_phase2_installdir/bin/clang
439         cxx_compiler=$llvmCore_phase2_installdir/bin/clang++
440         echo "# Phase 3: Building llvmCore"
441         configure_llvmCore 3 $Flavor \
442             $llvmCore_phase3_objdir $llvmCore_phase3_installdir
443         build_llvmCore 3 $Flavor \
444             $llvmCore_phase3_objdir
445         clean_RPATH $llvmCore_phase3_installdir
446
447         ########################################################################
448         # Testing: Test phase 3
449         echo "# Testing - built with clang"
450         test_llvmCore 3 $Flavor $llvmCore_phase3_objdir
451
452         ########################################################################
453         # Compare .o files between Phase2 and Phase3 and report which ones
454         # differ.
455         if [ "$do_compare" = "yes" ]; then
456             echo
457             echo "# Comparing Phase 2 and Phase 3 files"
458             for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do
459                 p3=`echo $o | sed -e 's,Phase2,Phase3,'`
460                 if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then
461                     echo "file `basename $o` differs between phase 2 and phase 3"
462                 fi
463             done
464         fi
465     fi
466
467     # Otherwise just test the core.
468     if [ "$do_clang" != "yes" ]; then
469         echo "# Testing - built with system compiler"
470         test_llvmCore 1 $Flavor $llvmCore_phase1_objdir
471     fi
472 done
473 ) 2>&1 | tee $LogDir/testing.$Release-$RC.log
474
475 package_release
476
477 set +e
478
479 # Woo hoo!
480 echo "### Testing Finished ###"
481 if [ "$use_gzip" = "yes" ]; then
482   echo "### Package: $Package.tar.gz"
483 else
484   echo "### Package: $Package.tar.xz"
485 fi
486 echo "### Logs: $LogDir"
487 exit 0