test-release.sh: Minor fixes.
[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 set -e                          # Exit if any command fails
352
353 if [ "$do_checkout" = "yes" ]; then
354     export_sources
355 fi
356
357 (
358 Flavors="Release"
359 if [ "$do_debug" = "yes" ]; then
360     Flavors="Debug $Flavors"
361 fi
362 if [ "$do_asserts" = "yes" ]; then
363     Flavors="$Flavors Release+Asserts"
364 fi
365 if [ "$do_64bit" = "yes" ]; then
366     Flavors="$Flavors Release-64"
367 fi
368
369 for Flavor in $Flavors ; do
370     echo ""
371     echo ""
372     echo "********************************************************************************"
373     echo "  Release:     $Release-$RC"
374     echo "  Build:       $Flavor"
375     echo "  System Info: "
376     echo "    `uname -a`"
377     echo "********************************************************************************"
378     echo ""
379
380     c_compiler="$CC"
381     cxx_compiler="$CXX"
382
383     llvmCore_phase1_objdir=$BuildDir/Phase1/$Flavor/llvmCore-$Release-$RC.obj
384     llvmCore_phase1_installdir=$BuildDir/Phase1/$Flavor/llvmCore-$Release-$RC.install
385
386     llvmCore_phase2_objdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-$RC.obj
387     llvmCore_phase2_installdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-$RC.install
388
389     llvmCore_phase3_objdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-$RC.obj
390     llvmCore_phase3_installdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-$RC.install
391
392     rm -rf $llvmCore_phase1_objdir
393     rm -rf $llvmCore_phase1_installdir
394
395     rm -rf $llvmCore_phase2_objdir
396     rm -rf $llvmCore_phase2_installdir
397
398     rm -rf $llvmCore_phase3_objdir
399     rm -rf $llvmCore_phase3_installdir
400
401     mkdir -p $llvmCore_phase1_objdir
402     mkdir -p $llvmCore_phase1_installdir
403
404     mkdir -p $llvmCore_phase2_objdir
405     mkdir -p $llvmCore_phase2_installdir
406
407     mkdir -p $llvmCore_phase3_objdir
408     mkdir -p $llvmCore_phase3_installdir
409
410     ############################################################################
411     # Phase 1: Build llvmCore and clang
412     echo "# Phase 1: Building llvmCore"
413     configure_llvmCore 1 $Flavor \
414         $llvmCore_phase1_objdir $llvmCore_phase1_installdir
415     build_llvmCore 1 $Flavor \
416         $llvmCore_phase1_objdir
417     clean_RPATH $llvmCore_phase1_installdir
418
419     # Test clang
420     if [ "$do_clang" = "yes" ]; then
421         ########################################################################
422         # Phase 2: Build llvmCore with newly built clang from phase 1.
423         c_compiler=$llvmCore_phase1_installdir/bin/clang
424         cxx_compiler=$llvmCore_phase1_installdir/bin/clang++
425         echo "# Phase 2: Building llvmCore"
426         configure_llvmCore 2 $Flavor \
427             $llvmCore_phase2_objdir $llvmCore_phase2_installdir
428         build_llvmCore 2 $Flavor \
429             $llvmCore_phase2_objdir
430         clean_RPATH $llvmCore_phase2_installdir
431
432         ########################################################################
433         # Phase 3: Build llvmCore with newly built clang from phase 2.
434         c_compiler=$llvmCore_phase2_installdir/bin/clang
435         cxx_compiler=$llvmCore_phase2_installdir/bin/clang++
436         echo "# Phase 3: Building llvmCore"
437         configure_llvmCore 3 $Flavor \
438             $llvmCore_phase3_objdir $llvmCore_phase3_installdir
439         build_llvmCore 3 $Flavor \
440             $llvmCore_phase3_objdir
441         clean_RPATH $llvmCore_phase3_installdir
442
443         ########################################################################
444         # Testing: Test phase 3
445         echo "# Testing - built with clang"
446         test_llvmCore 3 $Flavor $llvmCore_phase3_objdir
447
448         ########################################################################
449         # Compare .o files between Phase2 and Phase3 and report which ones
450         # differ.
451         if [ "$do_compare" = "yes" ]; then
452             echo
453             echo "# Comparing Phase 2 and Phase 3 files"
454             for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do
455                 p3=`echo $o | sed -e 's,Phase2,Phase3,'`
456                 if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then
457                     echo "file `basename $o` differs between phase 2 and phase 3"
458                 fi
459             done
460         fi
461     fi
462
463     # Otherwise just test the core.
464     if [ "$do_clang" != "yes" ]; then
465         echo "# Testing - built with system compiler"
466         test_llvmCore 1 $Flavor $llvmCore_phase1_objdir
467     fi
468 done
469 ) 2>&1 | tee $LogDir/testing.$Release-$RC.log
470
471 package_release
472
473 set +e
474
475 # Woo hoo!
476 echo "### Testing Finished ###"
477 if [ "$use_gzip" = "yes" ]; then
478   echo "### Package: $Package.tar.gz"
479 else
480   echo "### Package: $Package.tar.xz"
481 fi
482 echo "### Logs: $LogDir"
483 exit 0