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 15System=`uname -s` 16if [ "$System" = "FreeBSD" ]; then 17 MAKE=gmake 18else 19 MAKE=make 20fi 21 22# Base SVN URL for the sources. 23Base_url="http://llvm.org/svn/llvm-project" 24 25Release="" 26Release_no_dot="" 27RC="" 28Triple="" 29use_gzip="no" 30do_checkout="yes" 31do_debug="no" 32do_asserts="no" 33do_compare="yes" 34do_rt="yes" 35do_libs="yes" 36do_libcxxabi="yes" 37do_libunwind="yes" 38do_test_suite="yes" 39do_openmp="yes" 40do_lld="yes" 41do_lldb="no" 42do_polly="yes" 43BuildDir="`pwd`" 44ExtraConfigureFlags="" 45ExportBranch="" 46 47function 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 76while [ $# -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 175done 176 177# Check required arguments. 178if [ -z "$Release" ]; then 179 echo "error: no release number specified" 180 exit 1 181fi 182if [ -z "$RC" ]; then 183 echo "error: no release candidate number specified" 184 exit 1 185fi 186if [ -z "$ExportBranch" ]; then 187 ExportBranch="tags/RELEASE_$Release_no_dot/$RC" 188fi 189if [ -z "$Triple" ]; then 190 echo "error: no target triple specified" 191 exit 1 192fi 193 194# Figure out how many make processes to run. 195if [ -z "$NumJobs" ]; then 196 NumJobs=`sysctl -n hw.activecpu 2> /dev/null || true` 197fi 198if [ -z "$NumJobs" ]; then 199 NumJobs=`sysctl -n hw.ncpu 2> /dev/null || true` 200fi 201if [ -z "$NumJobs" ]; then 202 NumJobs=`grep -c processor /proc/cpuinfo 2> /dev/null || true` 203fi 204if [ -z "$NumJobs" ]; then 205 NumJobs=3 206fi 207 208# Projects list 209projects="llvm cfe clang-tools-extra" 210if [ $do_rt = "yes" ]; then 211 projects="$projects compiler-rt" 212fi 213if [ $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 221fi 222case $do_test_suite in 223 yes|export-only) 224 projects="$projects test-suite" 225 ;; 226esac 227if [ $do_openmp = "yes" ]; then 228 projects="$projects openmp" 229fi 230if [ $do_lld = "yes" ]; then 231 projects="$projects lld" 232fi 233if [ $do_lldb = "yes" ]; then 234 projects="$projects lldb" 235fi 236if [ $do_polly = "yes" ]; then 237 projects="$projects polly" 238fi 239 240# Go to the build directory (may be different from CWD) 241BuildDir=$BuildDir/$RC 242mkdir -p $BuildDir 243cd $BuildDir 244 245# Location of log files. 246LogDir=$BuildDir/logs 247mkdir -p $LogDir 248 249# Final package name. 250Package=clang+llvm-$Release 251if [ $RC != "final" ]; then 252 Package=$Package-$RC 253fi 254Package=$Package-$Triple 255 256# Errors to be highlighted at the end are written to this file. 257echo -n > $LogDir/deferred_errors.log 258 259function 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 267function 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 275if [ "$System" != "Darwin" ]; then 276 check_program_exists 'chrpath' 277 check_program_exists 'file' 278 check_program_exists 'objdump' 279fi 280 281# Make sure that the URLs are valid. 282function 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. 294function 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 337function 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 382function 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 402function 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. 427function 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. 446function 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 $?``) 462set -e 463set -o pipefail 464 465if [ "$do_checkout" = "yes" ]; then 466 export_sources 467fi 468 469# Setup the test-suite. Do this early so we can catch failures before 470# we do the full 3 stage build. 471if [ $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 480fi 481 482( 483Flavors="Release" 484if [ "$do_debug" = "yes" ]; then 485 Flavors="Debug $Flavors" 486fi 487if [ "$do_asserts" = "yes" ]; then 488 Flavors="$Flavors Release+Asserts" 489fi 490 491for 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 584done 585 586) 2>&1 | tee $LogDir/testing.$Release-$RC.log 587 588if [ "$use_gzip" = "yes" ]; then 589 echo "# Packaging the release as $Package.tar.gz" 590else 591 echo "# Packaging the release as $Package.tar.xz" 592fi 593package_release 594 595set +e 596 597# Woo hoo! 598echo "### Testing Finished ###" 599echo "### Logs: $LogDir" 600 601echo "### Errors:" 602if [ -s "$LogDir/deferred_errors.log" ]; then 603 cat "$LogDir/deferred_errors.log" 604 exit 1 605else 606 echo "None." 607fi 608 609exit 0 610