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 15if [ `uname -s` = "FreeBSD" ]; then 16 MAKE=gmake 17else 18 MAKE=make 19fi 20 21projects="llvm cfe dragonegg test-suite" 22 23# Base SVN URL for the sources. 24Base_url="http://llvm.org/svn/llvm-project" 25 26Release="" 27Release_no_dot="" 28RC="" 29do_checkout="yes" 30do_ada="no" 31do_objc="yes" 32do_fortran="no" 33do_64bit="yes" 34do_debug="no" 35do_asserts="no" 36BuildDir="`pwd`" 37 38function usage() { 39 echo "usage: `basename $0` -release X.Y -rc NUM [OPTIONS]" 40 echo "" 41 echo " -release X.Y The release number to test." 42 echo " -rc NUM The pre-release candidate number." 43 echo " -j NUM Number of compile jobs to run. [default: 3]" 44 echo " -build-dir DIR Directory to perform testing in. [default: pwd]" 45 echo " -no-checkout Don't checkout the sources from SVN." 46 echo " -no-64bit Don't test the 64-bit version. [default: yes]" 47 echo " -enable-ada Build Ada. [default: disable]" 48 echo " -enable-fortran Enable Fortran build. [default: disable]" 49 echo " -disable-objc Disable ObjC build. [default: enable]" 50 echo " -test-debug Test the debug build. [default: no]" 51 echo " -test-asserts Test with asserts on. [default: no]" 52} 53 54while [ $# -gt 0 ]; do 55 case $1 in 56 -release | --release ) 57 shift 58 Release="$1" 59 Release_no_dot="`echo $1 | sed -e 's,\.,,'`" 60 ;; 61 -rc | --rc | -RC | --RC ) 62 shift 63 RC=$1 64 ;; 65 -j* ) 66 NumJobs="`echo $1 | sed -e 's,-j\([0-9]*\),\1,g'`" 67 if [ -z "$NumJobs" ]; then 68 shift 69 NumJobs="$1" 70 fi 71 ;; 72 -build-dir | --build-dir | -builddir | --builddir ) 73 shift 74 BuildDir="$1" 75 ;; 76 -no-checkout | --no-checkout ) 77 do_checkout="no" 78 ;; 79 -no-64bit | --no-64bit ) 80 do_64bit="no" 81 ;; 82 -enable-ada | --enable-ada ) 83 do_ada="yes" 84 ;; 85 -enable-fortran | --enable-fortran ) 86 do_fortran="yes" 87 ;; 88 -disable-objc | --disable-objc ) 89 do_objc="no" 90 ;; 91 -test-debug | --test-debug ) 92 do_debug="yes" 93 ;; 94 -test-asserts | --test-asserts ) 95 do_asserts="yes" 96 ;; 97 -help | --help | -h | --h | -\? ) 98 usage 99 exit 0 100 ;; 101 * ) 102 echo "unknown option: $1" 103 usage 104 exit 1 105 ;; 106 esac 107 shift 108done 109 110# Check required arguments. 111if [ -z "$Release" ]; then 112 echo "error: no release number specified" 113 exit 1 114fi 115if [ -z "$RC" ]; then 116 echo "error: no release candidate number specified" 117 exit 1 118fi 119 120# Figure out how many make processes to run. 121if [ -z "$NumJobs" ]; then 122 NumJobs=`sysctl -n hw.activecpu 2> /dev/null || true` 123fi 124if [ -z "$NumJobs" ]; then 125 NumJobs=`sysctl -n hw.ncpu 2> /dev/null || true` 126fi 127if [ -z "$NumJobs" ]; then 128 NumJobs=`grep -c processor /proc/cpuinfo 2> /dev/null || true` 129fi 130if [ -z "$NumJobs" ]; then 131 NumJobs=3 132fi 133 134# Go to the build directory (may be different from CWD) 135BuildDir=$BuildDir/rc$RC 136mkdir -p $BuildDir 137cd $BuildDir 138 139# Location of log files. 140LogDir=$BuildDir/logs 141mkdir -p $LogDir 142 143# Find a compilers. 144c_compiler="$CC" 145cxx_compiler="$CXX" 146 147# Make sure that the URLs are valid. 148function check_valid_urls() { 149 for proj in $projects ; do 150 echo "# Validating $proj SVN URL" 151 152 if ! svn ls $Base_url/$proj/tags/RELEASE_$Release_no_dot/rc$RC > /dev/null 2>&1 ; then 153 echo "llvm $Release release candidate $RC doesn't exist!" 154 exit 1 155 fi 156 done 157} 158 159# Export sources to the the build directory. 160function export_sources() { 161 check_valid_urls 162 163 for proj in $projects ; do 164 echo "# Exporting $proj $Release-RC$RC sources" 165 if ! svn export -q $Base_url/$proj/tags/RELEASE_$Release_no_dot/rc$RC $proj.src ; then 166 echo "error: failed to export $proj project" 167 exit 1 168 fi 169 done 170 171 echo "# Creating symlinks" 172 cd $BuildDir/llvm.src/tools 173 if [ ! -h clang ]; then 174 ln -s ../../cfe.src clang 175 fi 176 cd $BuildDir/llvm.src/projects 177 if [ ! -h llvm-test ]; then 178 ln -s ../../test-suite.src llvm-test 179 fi 180 cd $BuildDir 181} 182 183function configure_llvmCore() { 184 Phase="$1" 185 Flavor="$2" 186 ObjDir="$3" 187 InstallDir="$4" 188 189 case $Flavor in 190 Release | Release-64 ) 191 Optimized="yes" 192 Assertions="no" 193 ;; 194 Release+Asserts ) 195 Optimized="yes" 196 Assertions="yes" 197 ;; 198 Debug ) 199 Optimized="no" 200 Assertions="yes" 201 ;; 202 * ) 203 echo "# Invalid flavor '$Flavor'" 204 echo "" 205 return 206 ;; 207 esac 208 209 echo "# Using C compiler: $c_compiler" 210 echo "# Using C++ compiler: $cxx_compiler" 211 212 cd $ObjDir 213 echo "# Configuring llvm $Release-rc$RC $Flavor" 214 echo "# $BuildDir/llvm.src/configure --prefix=$InstallDir \ 215 --enable-optimized=$Optimized \ 216 --enable-assertions=$Assertions" 217 env CC=$c_compiler CXX=$cxx_compiler \ 218 $BuildDir/llvm.src/configure --prefix=$InstallDir \ 219 --enable-optimized=$Optimized \ 220 --enable-assertions=$Assertions \ 221 2>&1 | tee $LogDir/llvm.configure-Phase$Phase-$Flavor.log 222 cd $BuildDir 223} 224 225function build_llvmCore() { 226 Phase="$1" 227 Flavor="$2" 228 ObjDir="$3" 229 ExtraOpts="" 230 231 if [ "$Flavor" = "Release-64" ]; then 232 ExtraOpts="EXTRA_OPTIONS=-m64" 233 fi 234 235 cd $ObjDir 236 echo "# Compiling llvm $Release-rc$RC $Flavor" 237 echo "# ${MAKE} -j $NumJobs VERBOSE=1 $ExtraOpts" 238 ${MAKE} -j $NumJobs VERBOSE=1 $ExtraOpts \ 239 2>&1 | tee $LogDir/llvm.make-Phase$Phase-$Flavor.log 240 241 echo "# Installing llvm $Release-rc$RC $Flavor" 242 echo "# ${MAKE} install" 243 ${MAKE} install \ 244 2>&1 | tee $LogDir/llvm.install-Phase$Phase-$Flavor.log 245 cd $BuildDir 246} 247 248function test_llvmCore() { 249 Phase="$1" 250 Flavor="$2" 251 ObjDir="$3" 252 253 cd $ObjDir 254 ${MAKE} -k check-all \ 255 2>&1 | tee $LogDir/llvm.check-Phase$Phase-$Flavor.log 256 ${MAKE} -k unittests \ 257 2>&1 | tee $LogDir/llvm.unittests-Phase$Phase-$Flavor.log 258 cd $BuildDir 259} 260 261set -e # Exit if any command fails 262 263if [ "$do_checkout" = "yes" ]; then 264 export_sources 265fi 266 267( 268Flavors="Release" 269if [ "$do_debug" = "yes" ]; then 270 Flavors="Debug $Flavors" 271fi 272if [ "$do_asserts" = "yes" ]; then 273 Flavors="$Flavors Release+Asserts" 274fi 275if [ "$do_64bit" = "yes" ]; then 276 Flavors="$Flavors Release-64" 277fi 278 279for Flavor in $Flavors ; do 280 echo "" 281 echo "" 282 echo "********************************************************************************" 283 echo " Release: $Release-rc$RC" 284 echo " Build: $Flavor" 285 echo " System Info: " 286 echo " `uname -a`" 287 echo "********************************************************************************" 288 echo "" 289 290 llvmCore_phase1_objdir=$BuildDir/Phase1/$Flavor/llvmCore-$Release-rc$RC.obj 291 llvmCore_phase1_installdir=$BuildDir/Phase1/$Flavor/llvmCore-$Release-rc$RC.install 292 293 llvmCore_phase2_objdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-rc$RC.obj 294 llvmCore_phase2_installdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-rc$RC.install 295 296 llvmCore_phase3_objdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-rc$RC.obj 297 llvmCore_phase3_installdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-rc$RC.install 298 299 rm -rf $llvmCore_phase1_objdir 300 rm -rf $llvmCore_phase1_installdir 301 rm -rf $llvmCore_phase2_objdir 302 rm -rf $llvmCore_phase2_installdir 303 rm -rf $llvmCore_phase3_objdir 304 rm -rf $llvmCore_phase3_installdir 305 306 mkdir -p $llvmCore_phase1_objdir 307 mkdir -p $llvmCore_phase1_installdir 308 mkdir -p $llvmCore_phase2_objdir 309 mkdir -p $llvmCore_phase2_installdir 310 mkdir -p $llvmCore_phase3_objdir 311 mkdir -p $llvmCore_phase3_installdir 312 313 ############################################################################ 314 # Phase 1: Build llvmCore and llvmgcc42 315 echo "# Phase 1: Building llvmCore" 316 configure_llvmCore 1 $Flavor \ 317 $llvmCore_phase1_objdir $llvmCore_phase1_installdir 318 build_llvmCore 1 $Flavor \ 319 $llvmCore_phase1_objdir 320 321 ############################################################################ 322 # Phase 2: Build llvmCore with newly built clang from phase 1. 323 c_compiler=$llvmCore_phase1_installdir/bin/clang 324 cxx_compiler=$llvmCore_phase1_installdir/bin/clang++ 325 echo "# Phase 2: Building llvmCore" 326 configure_llvmCore 2 $Flavor \ 327 $llvmCore_phase2_objdir $llvmCore_phase2_installdir 328 build_llvmCore 2 $Flavor \ 329 $llvmCore_phase2_objdir 330 331 ############################################################################ 332 # Phase 3: Build llvmCore with newly built clang from phase 2. 333 c_compiler=$llvmCore_phase2_installdir/bin/clang 334 cxx_compiler=$llvmCore_phase2_installdir/bin/clang++ 335 echo "# Phase 3: Building llvmCore" 336 configure_llvmCore 3 $Flavor \ 337 $llvmCore_phase3_objdir $llvmCore_phase3_installdir 338 build_llvmCore 3 $Flavor \ 339 $llvmCore_phase3_objdir 340 341 ############################################################################ 342 # Testing: Test phase 3 343 echo "# Testing - built with clang" 344 test_llvmCore 3 $Flavor $llvmCore_phase3_objdir 345 346 ############################################################################ 347 # Compare .o files between Phase2 and Phase3 and report which ones differ. 348 echo 349 echo "# Comparing Phase 2 and Phase 3 files" 350 for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do 351 p3=`echo $o | sed -e 's,Phase2,Phase3,'` 352 if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then 353 echo "file `basename $o` differs between phase 2 and phase 3" 354 fi 355 done 356done 357) 2>&1 | tee $LogDir/testing.$Release-rc$RC.log 358 359set +e 360 361# Woo hoo! 362echo "### Testing Finished ###" 363echo "### Logs: $LogDir" 364exit 0 365