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