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