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