1 #!/bin/bash 2 # 3 # Copyright (C) 2010 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 # This script is used to rebuild the Linux 32-bit cross-toolchain 19 # that allows you to generate 32-bit binaries that target Ubuntu 8.04 20 # (a.k.a. Hardy Heron) instead of the host system (which usually is 10.04, 21 # a.k.a. Lucid Lynx) 22 # 23 # Use --help for complete usage information. 24 # 25 # WARNING: At this time, the generated toolchain binaries will *not* run 26 # with GLibc 2.11, only the machine code it generates. 27 # 28 29 PROGNAME="`basename \"$0\"`" 30 PATCHES_DIR="$( cd "$( dirname "$0" )" && pwd )/toolchain-patches" 31 32 ########################################################################### 33 ########################################################################### 34 ##### 35 ##### C O N F I G U R A T I O N 36 ##### 37 ########################################################################### 38 ########################################################################### 39 40 panic () 41 { 42 echo "ERROR: $@" 43 exit 1 44 } 45 46 fail_panic () 47 { 48 if [ $? != 0 ] ; then 49 echo "ERROR: $@" 50 exit 1 51 fi 52 } 53 54 55 # We only support running this script on Linux 56 OS=$(uname -s) 57 if [ "$OS" != Linux ]; then 58 panic "This script can only run on Linux machines!" 59 fi 60 61 UBUNTU_ARCHS="i386 amd64" 62 63 # Used to set the host bitness of the generted toolchain binaries 64 # First call with the build machine's bitness, and later with 32 65 # if --32-bits option is used. 66 # $1: 32 or 64 67 set_host_bits () 68 { 69 HOST_BITS=$1 70 GMP_ABI=$1 71 case $1 in 72 32) 73 HOST_ARCH=i686 74 GCC_TARGET=i686-linux 75 GMP_TARGET=i386-linux 76 ;; 77 64) 78 HOST_ARCH=x86_64 79 GCC_TARGET=x86_64-linux 80 GMP_TARGET=x86_64-linux 81 ;; 82 *) 83 panic "Invalid host bitness (32 or 64 expected): $1" 84 esac 85 } 86 87 # Determine build machine bitness 88 BUILD_ARCH=$(uname -m) 89 case "$BUILD_ARCH" in 90 x86_64|amd64) 91 BUILD_BITS=64 92 BUILD_ARCH=x86_64 93 BUILD_GCC_TARGET=x86_64-linux 94 set_host_bits 64 95 ;; 96 i?86) 97 BUILD_BITS=32 98 BUILD_ARCH=i686 99 BUILD_GCC_TARGET=i686-linux 100 set_host_bits 32 101 ;; 102 *) 103 panic "Unknown build CPU architecture: $BUILD_ARCH" 104 esac 105 106 # Versions of various toolchain components, do not touch unless you know 107 # what you're doing! 108 109 BINUTILS_VERSION=2.23 110 GMP_VERSION=5.0.5 111 MPFR_VERSION=3.1.1 112 MPC_VERSION=1.0.1 113 GCC_VERSION=4.6 114 CLOOG_VERSION=0.18.0 115 ISL_VERSION=0.11.1 116 117 GLIBC_VERSION=2.11 118 119 GIT_CMD=git 120 GIT_DATE= 121 GIT_BRANCH=master 122 GIT_REFERENCE= 123 GIT_BASE= 124 GIT_BASE_DEFAULT=https://android.googlesource.com/toolchain 125 126 # Location where we're going to install the toolchain during the build 127 # This will depend on the phase of the build. 128 install_dir () { echo "$WORK_DIR/$PHASE/$TOOLCHAIN_NAME"; } 129 130 # Given an input string that looks like <major>.<minor>.<patch> 131 # Return <major>.<minor> only. 132 major_minor_only () { 133 local MAJOR=$(echo -n "$1" | cut -f1 -d.) 134 local MINOR=$(echo -n "$1" | cut -f2 -d.) 135 echo "$MAJOR.$MINOR" 136 } 137 138 # Location where we're going to install the final binaries 139 # If empty, TOOLCHAIN_ARCHIVE will be generated 140 PREFIX_DIR= 141 142 # Location of the final sysroot. This must be a sub-directory of INSTALL_DIR 143 # to ensure that the toolchain binaries are properly relocatable (i.e. can 144 # be used when moved to another directory). 145 sysroot_dir () { echo "$(install_dir)/sysroot"; } 146 147 # Try to parallelize the build for faster performance. 148 JOBS=$(cat /proc/cpuinfo | grep -c processor) 149 150 # The base URL of the Ubuntu mirror we're going to use. 151 UBUNTU_MIRROR=http://mirrors.us.kernel.org 152 153 # Ubuntu release name we want packages from. Can be a name or a number 154 # (i.e. "lucid" or "10.04") 155 UBUNTU_RELEASE=lucid 156 157 158 # The list of packages we need to download from the Ubuntu servers and 159 # extract into the original sysroot 160 # 161 # Call add_ubuntu_package <package-name> to add a package to the list, 162 # which will be processed later. 163 # 164 UBUNTU_PACKAGES= 165 166 add_ubuntu_package () 167 { 168 UBUNTU_PACKAGES="$UBUNTU_PACKAGES $@" 169 } 170 171 # The package files containing kernel headers for Hardy and the C 172 # library headers and binaries 173 add_ubuntu_package \ 174 linux-libc-dev \ 175 libc6 \ 176 libc6-dev \ 177 libcap2 \ 178 libcap-dev \ 179 libattr1 \ 180 libattr1-dev \ 181 libacl1 \ 182 libacl1-dev \ 183 184 # The X11 headers and binaries (for the emulator) 185 add_ubuntu_package \ 186 libx11-6 \ 187 libx11-dev \ 188 libxau6 \ 189 libxcb1-dev \ 190 libxdmcp6 \ 191 libxext-dev \ 192 x11proto-core-dev \ 193 x11proto-xext-dev \ 194 x11proto-input-dev \ 195 x11proto-kb-dev 196 197 # The OpenGL-related headers and libraries (for GLES emulation) 198 add_ubuntu_package \ 199 mesa-common-dev \ 200 libgl1-mesa-dev \ 201 libgl1-mesa-glx \ 202 libxxf86vm1 \ 203 libxext6 \ 204 libxdamage1 \ 205 libxfixes3 \ 206 libdrm2 207 208 # Audio libraries (required by the emulator) 209 add_ubuntu_package \ 210 libasound2 \ 211 libasound2-dev \ 212 libesd0-dev \ 213 libaudiofile-dev \ 214 libpulse0 \ 215 libpulse-dev 216 217 # ZLib and others. 218 add_ubuntu_package \ 219 zlib1g \ 220 zlib1g-dev \ 221 libncurses5 \ 222 libncurses5-dev 223 224 225 226 ########################################################################### 227 ########################################################################### 228 ##### 229 ##### E N D O F C O N F I G U R A T I O N 230 ##### 231 ########################################################################### 232 ########################################################################### 233 234 # Parse all options 235 OPTION_HELP=no 236 VERBOSE=0 237 FORCE=no 238 ONLY_SYSROOT=no 239 ONLY_TOOLCHAIN_DIR= 240 BOOTSTRAP= 241 PARAMETERS= 242 FORCE_32= 243 LIST_TASKS= 244 245 for opt do 246 optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') 247 case $opt in 248 --help|-h|-\?) OPTION_HELP=yes 249 ;; 250 --verbose) VERBOSE=$(( $VERBOSE + 1 )) 251 ;; 252 --force) FORCE="yes" 253 ;; 254 --32-bits) FORCE_32=true 255 ;; 256 --ubuntu-mirror=*) UBUNTU_MIRROR=$optarg 257 ;; 258 --ubuntu-release=*) UBUNTU_RELEASE=$optarg 259 ;; 260 --prefix=*) PREFIX_DIR=$optarg 261 ;; 262 --work-dir=*) WORK_DIR=$optarg 263 ;; 264 --gcc-version=*) GCC_VERSION=$optarg 265 ;; 266 --binutils-version=*) BINUTILS_VERSION=$optarg 267 ;; 268 --gmp-version=*) GMP_VERSION=$optarg 269 ;; 270 --mpfr-version=*) MPFR_VERSION=$optarg 271 ;; 272 --mpc-version=*) MPC_VERSION=$optarg 273 ;; 274 --isl-version=*) ISL_VERSION=$optarg 275 ;; 276 --cloog-version=*) CLOOG_VERSION=$oparg 277 ;; 278 --git=*) GIT_CMD=$optarg 279 ;; 280 --git-date=*) GIT_DATE=$optarg 281 ;; 282 --git-branch=*) GIT_BRANCH=$optarg 283 ;; 284 --git-base=*) GIT_BASE=$optarg 285 ;; 286 --git-reference=*) GIT_REFERENCE=$optarg 287 ;; 288 --out-dir=*) OPTION_OUT_DIR=$optarg 289 ;; 290 --cc=*) OPTION_CC=$optarg 291 ;; 292 --jobs=*) JOBS=$optarg 293 ;; 294 -j*) JOBS=${opt#-j} 295 ;; 296 --only-sysroot) ONLY_SYSROOT=yes 297 ;; 298 --bootstrap) BOOTSTRAP=yes 299 ;; 300 --list-tasks) LIST_TASKS=yes 301 ;; 302 -*) 303 echo "unknown option '$opt', use --help" 304 exit 1 305 ;; 306 *) 307 if [ -z "$PARAMETERS" ]; then 308 PARAMETERS=$opt 309 else 310 PARAMETERS="$PARAMETERS $opt" 311 fi 312 esac 313 done 314 315 if [ "$OPTION_HELP" = "yes" ]; then 316 cat << EOF 317 318 Usage: $PROGNAME [options] [<path-to-toolchain-sources>] 319 320 This script is used to rebuild a custom Linux host toolchain that targets 321 GLibc $GLIBC_VERSION or higher. The machine code generated by this toolchain 322 will run properly on Ubuntu $UBUNTU_RELEASE or higher. 323 324 If you're running on a 32-bit system, it will generate a 32-bit toolchain. 325 If you're running on a 64-bit system, it will generate a 64-bit toolchain 326 unless you use the --32-bits option. 327 328 You can provide the path to a local copy of the toolchain sources repository 329 as a first parameter. If you don't, the sources will be downloaded and 330 extracted automatically into your work directory. 331 332 Note that this script will download various binary packages from Ubuntu 333 servers in order to prepare a compatible "sysroot". 334 335 By default, it generates a package archive ($TOOLCHAIN_ARCHIVE) but you can, 336 as an alternative, ask for direct installation with --prefix=<path> 337 338 Use the bootstrap option to re-generate the toolchain with itself. This is 339 useful if you want to ensure that the generated compiler binaries will work 340 properly on Ubuntu 8.04 or higher. By default, they will only run on systems 341 that match your build system's C library ABI, or higher. 342 343 Options: [defaults in brackets after descriptions] 344 EOF 345 echo "Standard options:" 346 echo " --help Print this message" 347 echo " --force Force-rebuild everything" 348 echo " --prefix=PATH Installation path [$PREFIX_DIR]" 349 echo " --ubuntu-mirror=URL Ubuntu mirror URL [$UBUNTU_MIRROR]" 350 echo " --ubuntu-release=NAME Ubuntu release name [$UBUNTU_RELEASE]" 351 echo " --work-dir=PATH Temporary work directory [/tmp/gcc.<random>]" 352 echo " --only-sysroot Only download and build sysroot packages" 353 echo " --verbose Verbose output. Can be used twice." 354 echo " --binutils-version=VERSION Binutils version number [$BINUTILS_VERSION]" 355 echo " --gcc-version=VERSION GCC version number [$GCC_VERSION]" 356 echo " --gmp-version=VERSION GMP version number [$GMP_VERSION]" 357 echo " --mpfr-version=VERSION MPFR version numner [$MPFR_VERSION]" 358 echo " --mpc-version=VERSION MPC version number [$MPC_VERSION]" 359 echo " --isl-version=VERSION ISL version number [$ISL_VERSION]" 360 echo " --cloog-version=VERSION Cloog version number [$CLOOG_VERSION]" 361 echo " --jobs=COUNT Run COUNT build jobs in parallel [$JOBS]" 362 echo " -j<COUNT> Same as --jobs=COUNT." 363 echo " --git=<cmd> Use this version of the git tool [$GIT_CMD]" 364 echo " --git-date=<date> Specify specific git date when download sources [none]" 365 echo " --git-branch=<name> Specify which branch to use when downloading the sources [$GIT_BRANCH]" 366 echo " --git-reference=<path> Use a git reference repository" 367 echo " --git-base=<url> Use this git repository base [$GIT_BASE]" 368 echo " --bootstrap Bootstrap toolchain (i.e. compile it with itself)" 369 echo " --32-bits Generate 32-bit toolchain on 64-bit build system." 370 echo "" 371 exit 1 372 fi 373 374 if [ "$FORCE_32" ]; then 375 if [ "$BUILD_BITS" = 64 ]; then 376 set_host_bits 32 377 else 378 echo "Warning: --32-bits option ignored on 32-bit build machine." 379 fi 380 fi 381 382 # Determine root working directory for our script 383 if [ -z "$WORK_DIR" ]; then 384 WORK_DIR=$(mktemp -d /tmp/$USER-gcc-$HOST_BITS-XXXXXX) 385 WORK_DIR_CLEANUP=true 386 else 387 mkdir -p "$WORK_DIR" 388 fail_panic "Could not create directory: $WORK_DIR" 389 WORK_DIR_CLEANUP=false 390 fi 391 392 if [ -z "$PARAMETERS" ] ; then 393 if [ -n "$GIT_REFERENCE" ] ; then 394 if [ ! -d "$GIT_REFERENCE" -o ! -d "$GIT_REFERENCE/build" ]; then 395 echo "ERROR: Invalid reference repository directory path: $GIT_REFERENCE" 396 exit 1 397 fi 398 if [ -n "$GIT_BASE" ]; then 399 echo "Using git clone reference: $GIT_REFERENCE" 400 else 401 # If we have a reference without a base, use it as a download base instead. 402 GIT_BASE=$GIT_REFERENCE 403 GIT_REFERENCE= 404 echo "Using git clone base: $GIT_BASE" 405 fi 406 elif [ -z "$GIT_BASE" ]; then 407 GIT_BASE=$GIT_BASE_DEFAULT 408 echo "Auto-config: --git-base=$GIT_BASE" 409 fi 410 411 # Location where we will download the toolchain sources 412 TOOLCHAIN_SRC_DIR=$WORK_DIR/toolchain-src 413 else 414 set_parameters () { 415 TOOLCHAIN_SRC_DIR="$1" 416 if [ ! -d "$TOOLCHAIN_SRC_DIR" ]; then 417 echo "ERROR: Not a directory: $1" 418 exit 1 419 fi 420 if [ ! -d "$TOOLCHAIN_SRC_DIR/build" ]; then 421 echo "ERROR: Missing directory: $1/build" 422 exit 1 423 fi 424 } 425 426 set_parameters $PARAMETERS 427 fi 428 429 # Location of original sysroot. This is where we're going to extract all 430 # binary Ubuntu packages. 431 ORG_SYSROOT_DIR=$WORK_DIR/sysroot 432 433 # Name of the final generated toolchain 434 TOOLCHAIN_NAME=$GCC_TARGET-glibc$GLIBC_VERSION-$(major_minor_only $GCC_VERSION) 435 436 # Name of the final toolchain binary tarball that this script will create 437 TOOLCHAIN_ARCHIVE=/tmp/$TOOLCHAIN_NAME.tar.bz2 438 439 # A file that will contain details about all the sources used to generate 440 # the final toolchain. This includes both SHA-1 for toolchain git repositories 441 # and SHA-1 hashes for downloaded Ubuntu packages. 442 SOURCES_LIST=$WORK_DIR/SOURCES 443 444 # Determine Make flags 445 MAKE_FLAGS="-j$JOBS" 446 447 # Create the work directory 448 mkdir -p "$WORK_DIR" 449 mkdir -p "$TOOLCHAIN_SRC_DIR" 450 451 # Location where we download packages from the Ubuntu servers 452 DOWNLOAD_DIR=$WORK_DIR/download 453 454 # Empty the SOURCES file 455 rm -f "$SOURCES_LIST" && touch "$SOURCES_LIST" 456 457 458 if [ "$VERBOSE" -ge 1 ] ; then 459 run () { 460 echo "## COMMAND: $@" 461 $@ 462 } 463 log () { 464 echo "$@" 465 } 466 if [ "$VERBOSE" -ge 2 ] ; then 467 log2 () { 468 echo "$@" 469 } 470 else 471 log2 () { 472 return 473 } 474 fi 475 else 476 run () { 477 "$@" >>$TMPLOG 2>&1 478 } 479 log () { 480 return 481 } 482 log2 () { 483 return 484 } 485 fi 486 487 # Sanitize a path list, we want to remove empty sub-dirs and 488 # leading/trailing columns. 489 sanitize_path_list () 490 { 491 local RESULT 492 RESULT=$(printf "%s\n" "$*" | tr ':' '\n' | awk '$1 != "" && $1 != "." { print $0; }' | tr '\n' ':') 493 printf "%s" ${RESULT%:} 494 } 495 496 PATH=$(sanitize_path_list $PATH) 497 LD_LIBRARY_PATH=$(sanitize_path_list $LD_LIBRARY_PATH) 498 499 BUILD_DIR=$WORK_DIR/build 500 mkdir -p $BUILD_DIR 501 502 TMPLOG=$BUILD_DIR/build.log 503 rm -rf $TMPLOG && touch $TMPLOG 504 505 build_dir_for () { echo "$BUILD_DIR/$PHASE/$1"; } 506 507 TIMESTAMPS_DIR=$BUILD_DIR/timestamps 508 mkdir -p $TIMESTAMPS_DIR 509 510 stamp_check () { 511 [ -f "$TIMESTAMPS_DIR/$1" ] 512 } 513 514 stamp_clear () { 515 rm -f "$TIMESTAMPS_DIR/$1" 516 } 517 518 stamp_set () { 519 touch "$TIMESTAMPS_DIR/$1" 520 } 521 522 if [ "$FORCE" = "yes" ] ; then 523 echo "Cleaning up timestamps (forcing the build)." 524 rm -f $TIMESTAMPS_DIR/* 525 fi 526 527 if [ "$VERBOSE" = 0 ] ; then 528 echo "To follow build, run: tail -F $TMPLOG" 529 fi 530 531 # returns 0 iff the string in $2 matches the pattern in $1 532 # $1: pattern 533 # $2: string 534 pattern_match () 535 { 536 echo "$2" | grep -q -E -e "$1" 537 } 538 539 # Find if a given shell program is available. 540 # We need to take care of the fact that the 'which <foo>' command 541 # may return either an empty string (Linux) or something like 542 # "no <foo> in ..." (Darwin). Also, we need to redirect stderr 543 # to /dev/null for Cygwin 544 # 545 # $1: variable name 546 # $2: program name 547 # 548 # Result: set $1 to the full path of the corresponding command 549 # or to the empty/undefined string if not available 550 # 551 find_program () 552 { 553 local PROG 554 PROG=`which $2 2>/dev/null` 555 if [ -n "$PROG" ] ; then 556 if pattern_match '^no ' "$PROG"; then 557 PROG= 558 fi 559 fi 560 eval $1="$PROG" 561 } 562 563 # Copy a directory, create target location if needed 564 # 565 # $1: source directory 566 # $2: target directory location 567 # 568 copy_directory () 569 { 570 local SRCDIR="$1" 571 local DSTDIR="$2" 572 if [ ! -d "$SRCDIR" ] ; then 573 panic "Can't copy from non-directory: $SRCDIR" 574 fi 575 log2 "Directory copy: $SRCDIR -> $DSTDIR" 576 mkdir -p "$DSTDIR" && (cd "$SRCDIR" && tar cf - *) | (tar xf - -C "$DSTDIR") 577 fail_panic "Cannot copy to directory: $DSTDIR" 578 } 579 580 find_program CMD_WGET wget 581 find_program CMD_CURL curl 582 find_program CMD_SCP scp 583 584 # Download a file with either 'curl', 'wget' or 'scp' 585 # 586 # $1: source URL (e.g. http://foo.com, ssh://blah, /some/path) 587 # $2: target file 588 download_file () 589 { 590 # Is this HTTP, HTTPS or FTP ? 591 if pattern_match "^(http|https|ftp):.*" "$1"; then 592 if [ -n "$CMD_WGET" ] ; then 593 run $CMD_WGET -O $2 $1 594 elif [ -n "$CMD_CURL" ] ; then 595 run $CMD_CURL -o $2 $1 596 else 597 echo "Please install wget or curl on this machine" 598 exit 1 599 fi 600 return 601 fi 602 603 # Is this SSH ? 604 # Accept both ssh://<path> or <machine>:<path> 605 # 606 if pattern_match "^(ssh|[^:]+):.*" "$1"; then 607 if [ -n "$CMD_SCP" ] ; then 608 scp_src=`echo $1 | sed -e s%ssh://%%g` 609 run $CMD_SCP $scp_src $2 610 else 611 echo "Please install scp on this machine" 612 exit 1 613 fi 614 return 615 fi 616 617 # Is this a file copy ? 618 # Accept both file://<path> or /<path> 619 # 620 if pattern_match "^(file://|/).*" "$1"; then 621 cp_src=`echo $1 | sed -e s%^file://%%g` 622 run cp -f $cp_src $2 623 return 624 fi 625 626 # Unknown schema 627 echo "ERROR: Unsupported source URI: $1" 628 exit 1 629 } 630 631 # A variant of 'download_file' used to specify the target directory 632 # $1: source URL 633 # $2: target directory 634 download_file_to () 635 { 636 local URL="$1" 637 local DIR="$2" 638 local DST="$DIR/`basename $URL`" 639 mkdir -p $DIR 640 download_file "$URL" "$DST" 641 } 642 643 # Pack a given archive 644 # 645 # $1: archive file path (including extension) 646 # $2: source directory for archive content 647 # $3+: list of files (including patterns), all if empty 648 pack_archive () 649 { 650 local ARCHIVE="$1" 651 local SRCDIR="$2" 652 local SRCFILES 653 local TARFLAGS ZIPFLAGS 654 shift; shift; 655 if [ -z "$1" ] ; then 656 SRCFILES="*" 657 else 658 SRCFILES="$@" 659 fi 660 if [ "`basename $ARCHIVE`" = "$ARCHIVE" ] ; then 661 ARCHIVE="`pwd`/$ARCHIVE" 662 fi 663 mkdir -p `dirname $ARCHIVE` 664 if [ "$VERBOSE" -ge 2 ] ; then 665 TARFLAGS="vcf" 666 ZIPFLAGS="-9r" 667 else 668 TARFLAGS="cf" 669 ZIPFLAGS="-9qr" 670 fi 671 case "$ARCHIVE" in 672 *.zip) 673 (cd $SRCDIR && run zip $ZIPFLAGS "$ARCHIVE" $SRCFILES) 674 ;; 675 *.tar) 676 (cd $SRCDIR && run tar $TARFLAGS "$ARCHIVE" $SRCFILES) 677 ;; 678 *.tar.gz) 679 (cd $SRCDIR && run tar z$TARFLAGS "$ARCHIVE" $SRCFILES) 680 ;; 681 *.tar.bz2) 682 (cd $SRCDIR && run tar j$TARFLAGS "$ARCHIVE" $SRCFILES) 683 ;; 684 *) 685 panic "Unsupported archive format: $ARCHIVE" 686 ;; 687 esac 688 } 689 690 no_trailing_slash () 691 { 692 echo ${1##/} 693 } 694 695 # Load the Ubuntu packages file. This is a long text file that will list 696 # each package for a given release. 697 # 698 # $1: Ubuntu mirror base URL (e.g. http://mirrors.us.kernel.org/) 699 # $2: Release name 700 # 701 get_ubuntu_packages_list () 702 { 703 local RELEASE=$2 704 local BASE="`no_trailing_slash \"$1\"`" 705 local SRCFILE DSTFILE 706 for UA in $UBUNTU_ARCHS; do 707 SRCFILE="$BASE/ubuntu/dists/$RELEASE/main/binary-$UA/Packages.bz2" 708 DSTFILE="$DOWNLOAD_DIR/Packages-$UA.bz2" 709 log "Trying to load $SRCFILE" 710 download_file "$SRCFILE" "$DSTFILE" 711 fail_panic "Could not download $SRCFILE" 712 (cd $DOWNLOAD_DIR && bunzip2 -cf Packages-$UA.bz2 > Packages-$UA) 713 fail_panic "Could not uncompress $DSTFILE to Packages-$UA" 714 done 715 716 # Write a small awk script used to extract filenames for a given package 717 cat > $DOWNLOAD_DIR/extract-filename.awk <<EOF 718 BEGIN { 719 # escape special characters in package name 720 gsub("\\\\.","\\\\.",PKG) 721 gsub("\\\\+","\\\\+",PKG) 722 FILE = "" 723 PACKAGE = "" 724 } 725 726 \$1 == "Package:" { 727 if (\$2 == PKG) { 728 PACKAGE = \$2 729 } else { 730 PACKAGE = "" 731 } 732 } 733 734 \$1 == "Filename:" && PACKAGE == PKG { 735 FILE = \$2 736 } 737 738 END { 739 print FILE 740 } 741 EOF 742 } 743 744 # Convert an unversioned package name into a .deb package URL 745 # 746 # $1: Package name without version information (e.g. libc6-dev) 747 # $2: Ubuntu mirror base URL 748 # $3: Ubuntu arch ("i386" or "amd64") 749 # 750 get_ubuntu_package_deb_url () 751 { 752 # The following is an awk command to parse the Packages file and extract 753 # the filename of a given package. 754 local BASE="`no_trailing_slash \"$1\"`" 755 local FILE=`awk -f "$DOWNLOAD_DIR/extract-filename.awk" -v PKG=$1 $DOWNLOAD_DIR/Packages-$3` 756 if [ -z "$FILE" ]; then 757 log "Could not find filename for package $1" 758 exit 1 759 fi 760 echo "$2/ubuntu/$FILE" 761 } 762 763 # Does the host compiler generate 32-bit machine code? 764 # If not, add the -m32 flag to the compiler name to ensure this. 765 # 766 compute_host_flags () 767 { 768 HOST_CC=${CC:-gcc} 769 HOST_CXX=${CXX-g++} 770 if [ -n "$USE_CCACHE" ]; then 771 echo -n "Checking for ccache..." 772 find_program CMD_CCACHE ccache 773 if [ -n "$CMD_CCACHE" ] ; then 774 echo "$HOST_CC" | tr ' ' '\n' | grep -q -e "ccache" 775 if [ $? = 0 ] ; then 776 echo "yes (ignored)" 777 else 778 echo "yes" 779 HOST_CC="ccache $HOST_CC" 780 HOST_CXX="ccache $HOST_CXX" 781 fi 782 else 783 echo "no" 784 fi 785 fi 786 echo -n "Checking compiler bitness... " 787 cat > "$BUILD_DIR"/conftest.c << EOF 788 #include <stdio.h> 789 int main(void) { 790 printf("%d\n",sizeof(void*)*8); 791 return 0; 792 } 793 EOF 794 $HOST_CC -o "$BUILD_DIR"/conftest "$BUILD_DIR"/conftest.c > "$BUILD_DIR"/conftest.log 2>&1 795 if [ $? != 0 ] ; then 796 echo "Could not compile test program!!" 797 echo "Error log is:" 798 cat "$BUILD_DIR"/conftest.log 799 rm "$BUID_DIR"/conftest.log 800 panic "Need a working build toolchain!" 801 fi 802 HOST_CC_BITS=$("$BUILD_DIR"/conftest) 803 echo -n "$HOST_CC_BITS" 804 case $HOST_CC_BITS in 805 32) # Nothing to do 806 ;; 807 64) # Do we need to force 32-bits 808 if [ "$FORCE_32" ]; then 809 echo " (forcing generation of 32-bit binaries)" 810 HOST_CC=$HOST_CC" -m32" 811 HOST_CXX=$HOST_CXX" -m32" 812 fi 813 ;; 814 *) 815 panic "Unknown bitness (32 or 64 expected) !!" 816 esac 817 echo "" 818 echo "Using build C compiler: $HOST_CC" 819 echo "Using build C++ compiler: $HOST_CXX" 820 echo "GCC target name: $GCC_TARGET" 821 echo "GMP target name: $GMP_TARGET" 822 echo "GMP ABI: $GMP_ABI" 823 export CC="$HOST_CC" 824 export CXX="$HOST_CXX" 825 } 826 827 compute_host_flags 828 829 # Return the value of a given named variable 830 # $1: variable name 831 # 832 # example: 833 # FOO=BAR 834 # BAR=ZOO 835 # echo `var_value $FOO` 836 # will print 'ZOO' 837 # 838 var_value () 839 { 840 eval echo \$$1 841 } 842 843 var_list_append () 844 { 845 local VARNAME=$1 846 local VARVAL=`var_value $VARNAME` 847 shift 848 if [ -z "$VARVAL" ] ; then 849 eval $VARNAME=\"$@\" 850 else 851 eval $VARNAME=\"$VARVAL $@\" 852 fi 853 } 854 855 var_list_prepend () 856 { 857 local VARNAME=$1 858 local VARVAL=`var_value $VARNAME` 859 shift 860 if [ -z "$VARVAL" ] ; then 861 eval $VARNAME=\"$@\" 862 else 863 eval $VARNAME=\"$@ $VARVAL\" 864 fi 865 } 866 867 _list_first () 868 { 869 echo $1 870 } 871 872 _list_rest () 873 { 874 shift 875 echo "$@" 876 } 877 878 _list_reverse () 879 { 880 local I1 I2 I3 I4 I5 I6 I7 I8 I9 REST RET 881 I1=$1; I2=$2; I3=$3; I4=$I4; I5=$I5; I6=$I6; I7=$I7; I8=$I8; I9=$I9 882 shift 9 883 RET=$I9${I8:+" "}$I8${I7:+" "}$I7${I6:+" "}$I6${I5:+" "}$I5${I4:+" "}$I4${I3:+" "}$I3${I2:+" "}$I2${I1:+" "}$I1 884 REST="$*" 885 if [ "$REST" ]; then 886 RET=$(_list_reverse $REST)$RET 887 fi 888 echo "$RET" 889 } 890 891 var_list_pop_first () 892 { 893 local VARNAME=$1 894 local VARVAL=`var_value $VARNAME` 895 local FIRST=`_list_first $VARVAL` 896 eval $VARNAME=\"`_list_rest $VARVAL`\" 897 echo "$FIRST" 898 } 899 900 _list_first () 901 { 902 echo $1 903 } 904 905 _list_rest () 906 { 907 shift 908 echo "$@" 909 } 910 911 var_list_first () 912 { 913 local VAL=`var_value $1` 914 _list_first $VAL 915 } 916 917 var_list_rest () 918 { 919 local VAL=`var_value $1` 920 _list_rest $VAL 921 } 922 923 ALL_TASKS= 924 925 # Define a new task for this build script 926 # $1: Task name (e.g. build_stuff) 927 # $2: Task description 928 # $3: Optional: command name (will be cmd_$1 by default) 929 # 930 task_define () 931 { 932 local TASK="$1" 933 local DESCR="$2" 934 local COMMAND="${3:-cmd_$1}" 935 936 var_list_append ALL_TASKS $TASK 937 task_set $TASK name "$TASK" 938 task_set $TASK descr "$DESCR" 939 task_set $TASK cmd "$COMMAND" 940 task_set $TASK deps "" 941 } 942 943 # Variant of task define for dual tasks 944 # This really defines two tasks named '<task>_1' and '<task>_2" 945 # $1: Task base name 946 # $2: Task description 947 # $3: Optional: command name (will be cmd_$1 by default) 948 task2_define () 949 { 950 local TASK="$1" 951 local DESCR="$2" 952 local COMMAND="${3:-cmd_$1}" 953 954 task_define "${TASK}_1" "$DESCR 1/2" "phase_1 $COMMAND" 955 task_define "${TASK}_2" "$DESCR 2/2" "phase_2 $COMMAND" 956 } 957 958 task_set () 959 { 960 local TASK="$1" 961 local FIELD="$2" 962 shift; shift; 963 eval TASK_${TASK}__${FIELD}=\"$@\" 964 } 965 966 task_get () 967 { 968 var_value TASK_$1__$2 969 } 970 971 # return the list of dependencies for a given task 972 task_get_deps () 973 { 974 task_get $1 deps 975 } 976 977 task_get_cmd () 978 { 979 task_get $1 cmd 980 } 981 982 task_get_descr () 983 { 984 task_get $1 descr 985 } 986 987 # $1: task name 988 # $2+: other tasks this task depends on. 989 task_depends () 990 { 991 local TASK="$1" 992 shift; 993 var_list_append TASK_${TASK}__deps $@ 994 } 995 996 # $1: dual task name 997 # $2+: other non-dual tasks this dual task depends on 998 task2_depends1 () 999 { 1000 local TASK="$1" 1001 shift 1002 var_list_append TASK_${TASK}_1__deps $@ 1003 var_list_append TASK_${TASK}_2__deps $@ 1004 } 1005 1006 # $1: dual task name 1007 # $2+: other dual tasks this dual task depends on 1008 task2_depends2 () 1009 { 1010 local TASK="$1" 1011 local DEP 1012 shift 1013 for DEP; do 1014 var_list_append TASK_${TASK}_1__deps ${DEP}_1 1015 var_list_append TASK_${TASK}_2__deps ${DEP}_2 1016 done 1017 } 1018 1019 task_dump () 1020 { 1021 local TASK 1022 for TASK in $ALL_TASKS; do 1023 local DEPS="`task_get_deps $TASK`" 1024 local CMD="`task_get_cmd $TASK`" 1025 local DESCR="`task_get_descr $TASK`" 1026 echo "TASK $TASK: $DESCR: $CMD" 1027 echo "> $DEPS" 1028 done 1029 } 1030 1031 task_visit () 1032 { 1033 task_set $TASK visit 1 1034 } 1035 1036 task_unvisit () 1037 { 1038 task_set $TASK visit 0 1039 } 1040 1041 task_is_visited () 1042 { 1043 [ `task_get $TASK visit` = 1 ] 1044 } 1045 1046 task_queue_reset () 1047 { 1048 TASK_QUEUE= 1049 } 1050 1051 task_queue_push () 1052 { 1053 var_list_append TASK_QUEUE $1 1054 } 1055 1056 task_queue_pop () 1057 { 1058 local FIRST=`var_list_first TASK_QUEUE` 1059 TASK_QUEUE=`var_list_rest TASK_QUEUE` 1060 } 1061 1062 do_all_tasks () 1063 { 1064 local TASK 1065 local TASK_LIST= 1066 task_queue_reset 1067 # Clear visit flags 1068 for TASK in $ALL_TASKS; do 1069 task_unvisit $TASK 1070 done 1071 task_queue_push $1 1072 while [ -n "$TASK_QUEUE" ] ; do 1073 TASK=`task_queue_pop` 1074 if task_is_visited $TASK; then 1075 continue 1076 fi 1077 # Prepend the task to the list if its timestamp is not set 1078 if stamp_check $TASK; then 1079 var_list_prepend TASK_LIST $TASK 1080 fi 1081 # Add all dependencies to the work-queue 1082 local SUBTASK 1083 for SUBTASK in `task_get_deps $TASK`; do 1084 task_queue_push $SUBTASK 1085 done 1086 task_visit $TASK 1087 done 1088 1089 # Now, TASK_LIST contains the 1090 } 1091 1092 1093 # Return the first item of a space-separated list 1094 list_first () { 1095 set -- "$@" 1096 echo "$1" 1097 } 1098 1099 # Append an item to a given list 1100 list_append () { 1101 local ITEM=$1 1102 shift; 1103 echo $@${@:+" "}$1 1104 } 1105 1106 # Return the second-to-last items of a space-separated list 1107 list_rest () { 1108 set -- "$@" 1109 shift 1110 echo "$@" 1111 } 1112 1113 # Reverse a space-separated list 1114 list_reverse () 1115 { 1116 set -- "$@" 1117 local I1 I2 I3 I4 I5 I6 I7 I8 I9 REST RET 1118 I1=$1; I2=$2; I3=$3; I4=$4; I5=$5; I6=$6; I7=$7; I8=$8; I9=$9 1119 shift; shift; shift; shift; shift; shift; shift; shift; shift; 1120 RET=$I9${I9:+" "}$I8${I8:+" "}$I7${I7:+" "}$I6${I6:+" "}$I5${I5:+" "}$I4${I4:+" "}$I3${I3:+" "}$I2${I2:+" "}$I1 1121 REST="$*" 1122 if [ -n "$REST" ]; then 1123 RET=$(list_reverse $REST)" "$RET 1124 fi 1125 echo "$RET" 1126 } 1127 1128 # Used to build the list of tasks with a tree post-order traversal, i.e. 1129 # the list starts at the leaves and finishes with the top level task, 1130 # so that if task(A) depends on task(B), then A will always appear _after_ 1131 # B in the result. 1132 # 1133 # $1: space-separated list of tasks to visit 1134 # Out: list of all tasks in post-order 1135 # 1136 task_build_postorder_list () 1137 { 1138 local TASK 1139 local STACK="$1" 1140 local RET="" 1141 for TASK in $ALL_TASKS; do 1142 stamp_clear $TASK.visit 1143 done 1144 while true; do 1145 # Peek at stack 1146 TASK=$(list_first $STACK) 1147 #echo >&2 "STACK: ($TASK) '$STACK'" 1148 if [ -z "$TASK" ]; then 1149 break 1150 fi 1151 HAS_DEPS= 1152 for DEP in $(task_get_deps $TASK); do 1153 #echo >&2 "CHECK: '$DEP'" 1154 if ! stamp_check $DEP.visit; then 1155 STACK=$DEP" "$STACK 1156 #echo >&2 "PUSH: '$DEP' => '$STACK'" 1157 HAS_DEPS=1 1158 fi 1159 done 1160 1161 if [ -z "$HAS_DEPS" ]; then 1162 #echo >&2 "ADD: $TASK -> '$RET'" 1163 STACK=$(list_rest $STACK) 1164 if ! stamp_check $TASK.visit; then 1165 RET=$RET${RET:+" "}$TASK 1166 stamp_set $TASK.visit 1167 fi 1168 fi 1169 done 1170 for TASK in $ALL_TASKS; do 1171 stamp_clear $TASK.visit 1172 done 1173 echo "$RET" 1174 } 1175 1176 run_task () 1177 { 1178 # Build the list of tasks, in reverse order (from leafs to last) 1179 local TASKS=$(task_build_postorder_list $1) 1180 # Do all tasks 1181 local TASK DEP DESCR 1182 1183 # Dump list of tasks: 1184 # echo "ALL TASKS:" 1185 # for TASK in $TASKS; do 1186 # echo " $TASK" 1187 # done 1188 1189 # Clean timestamps of any tasks whose any of its dependents needs 1190 # to be re-done. 1191 # 1192 for TASK in $TASKS; do 1193 for DEP in $(task_get_deps $TASK); do 1194 if ! stamp_check $DEP; then 1195 #echo "Redo: $TASK due to $DEP" 1196 stamp_clear $TASK 1197 break 1198 fi 1199 done 1200 done 1201 1202 for TASK in $TASKS; do 1203 DESCR=$(task_get_descr $TASK) 1204 if stamp_check $TASK; then 1205 echo "Skipping: $DESCR" 1206 continue 1207 fi 1208 echo "Running: $DESCR" 1209 if [ "$VERBOSE" -ge 1 ] ; then 1210 (eval $(task_get_cmd $TASK)) 1211 else 1212 (eval $(task_get_cmd $TASK)) >> $TMPLOG 2>&1 1213 fi 1214 if [ $? != 0 ] ; then 1215 echo "ERROR: Cannot $DESCR" 1216 exit 1 1217 fi 1218 1219 stamp_set $TASK 1220 done 1221 } 1222 1223 # This function is used to clone a source repository either from a given 1224 # git base or a git reference. 1225 # $1: project/subdir name 1226 # $2: path to SOURCES file 1227 toolchain_clone () 1228 { 1229 local GITFLAGS 1230 GITFLAGS= 1231 if [ "$GIT_REFERENCE" ]; then 1232 GITFLAGS="$GITFLAGS --shared --reference $GIT_REFERENCE/$1" 1233 fi 1234 echo "cleaning up toolchain/$1" 1235 rm -rf $1 1236 fail_panic "Could not clean $(pwd)/$1" 1237 echo "downloading sources for toolchain/$1" 1238 if [ -d "$GIT_BASE/$1" ]; then 1239 log "cloning $GIT_BASE/$1" 1240 run $GIT_CMD clone $GITFLAGS $GIT_BASE/$1 $1 1241 else 1242 log "cloning $GITPREFIX/$1.git" 1243 run $GIT_CMD clone $GITFLAGS $GIT_BASE/$1.git $1 1244 fi 1245 fail_panic "Could not clone $GIT_BASE/$1.git ?" 1246 cd $1 1247 if [ "$GIT_BRANCH" != "master" ] ; then 1248 log "checking out $GIT_BRANCH branch of $1.git" 1249 run $GIT_CMD checkout -b $GIT_BRANCH origin/$GIT_BRANCH 1250 fail_panic "Could not checkout $1 ?" 1251 fi 1252 # If --git-date is used, or we have a default 1253 if [ -n "$GIT_DATE" ] ; then 1254 REVISION=`git rev-list -n 1 --until="$GIT_DATE" HEAD` 1255 echo "Using sources for date '$GIT_DATE': toolchain/$1 revision $REVISION" 1256 run $GIT_CMD checkout $REVISION 1257 fail_panic "Could not checkout $1 ?" 1258 fi 1259 (printf "%-32s " "toolchain/$1.git: " && git log -1 --format=oneline) >> $2 1260 cd .. 1261 } 1262 1263 task_define download_toolchain_sources "Download toolchain sources from $GIT_BASE " 1264 cmd_download_toolchain_sources () 1265 { 1266 local SUBDIRS="binutils build gcc gdb gold gmp mpfr mpc isl cloog" 1267 (mkdir -p $TOOLCHAIN_SRC_DIR && cd $TOOLCHAIN_SRC_DIR && 1268 # Create a temporary SOURCES file for the toolchain sources only 1269 # It's content will be copied to the final SOURCES file later. 1270 SOURCES_LIST=$TOOLCHAIN_SRC_DIR/SOURCES 1271 rm -f $SOURCES_LIST && touch $SOURCES_LIST 1272 for SUB in $SUBDIRS; do 1273 toolchain_clone $SUB $SOURCES_LIST 1274 done 1275 ) 1276 } 1277 1278 task_define download_ubuntu_packages_list "Download Ubuntu packages list" 1279 cmd_download_ubuntu_packages_list () 1280 { 1281 mkdir -p $DOWNLOAD_DIR 1282 get_ubuntu_packages_list "$UBUNTU_MIRROR" "$UBUNTU_RELEASE" 1283 fail_panic "Unable to download packages list, try --ubuntu-mirror=<url> to use another archive mirror" 1284 } 1285 1286 task_define download_packages "Download Ubuntu packages" 1287 task_depends download_packages download_ubuntu_packages_list 1288 cmd_download_packages () 1289 { 1290 local PACKAGE PKGURL 1291 1292 rm -f $DOWNLOAD_DIR/SOURCES && touch $DOWNLOAD_DIR/SOURCES 1293 for PACKAGE in $UBUNTU_PACKAGES; do 1294 echo "Downloading $PACKAGE" 1295 for UA in $UBUNTU_ARCHS; do 1296 PKGURL=`get_ubuntu_package_deb_url $PACKAGE $UBUNTU_MIRROR $UA` 1297 echo "URL: $PKGURL" 1298 download_file_to $PKGURL $DOWNLOAD_DIR 1299 fail_panic "Could not download $PKGURL" 1300 done 1301 done 1302 sha1sum $DOWNLOAD_DIR/*.deb | while read LINE; do 1303 PACKAGE=$(basename $(echo $LINE | awk '{ print $2;}')) 1304 SHA1=$(echo $LINE | awk '{ print $1; }') 1305 printf "%-64s %s\n" $PACKAGE $SHA1 >> $DOWNLOAD_DIR/SOURCES 1306 done 1307 } 1308 1309 task_define build_sysroot "Build sysroot" 1310 task_depends build_sysroot download_packages 1311 1312 cmd_build_sysroot () 1313 { 1314 local PACKAGE PKGURL SRC_PKG 1315 mkdir -p $SRC_PKG $ORG_SYSROOT_DIR 1316 for PACKAGE in $UBUNTU_PACKAGES; do 1317 for UA in $UBUNTU_ARCHS; do 1318 PKGURL=`get_ubuntu_package_deb_url $PACKAGE $UBUNTU_MIRROR $UA` 1319 SRC_PKG=$DOWNLOAD_DIR/`basename $PKGURL` 1320 echo "Extracting $SRC_PKG" 1321 dpkg -x $SRC_PKG $ORG_SYSROOT_DIR/$UA 1322 done 1323 done 1324 } 1325 1326 # Now, we need to patch libc.so which is actually a linker script 1327 # referencing /lib and /usr/lib. Do the same for libpthread.so 1328 patch_library () 1329 { 1330 echo "Patching $1" 1331 sed -i -e "s! /lib/! !g" -e "s! /usr/lib/! !g" $1 1332 } 1333 1334 # Used to setup phase 1 the run a command 1335 phase_1 () 1336 { 1337 PHASE=1 1338 $@ 1339 } 1340 1341 # Used to setup phase 2 then run a command 1342 phase_2 () 1343 { 1344 PHASE=1 1345 BINPREFIX=$(install_dir)/bin/${GCC_TARGET}- 1346 CC=${BINPREFIX}gcc 1347 CXX=${BINPREFIX}g++ 1348 LD=${BINPREFIX}ld 1349 AR=${BINPREFIX}ar 1350 AS=${BINPREFIX}as 1351 RANLIB=${BINPREFIX}ranlib 1352 STRIP=${BINPREFIX}strip 1353 CC_FOR_TARGET=${BINPREFIX}gcc 1354 export CC CXX LD AR AS RANLIB STRIP CC_FOR_TARGET 1355 PHASE=2 1356 $@ 1357 } 1358 1359 # Return the list of all symbolic links in a given directory, excluding 1360 # any links in its sub-directories. 1361 # $1: Sub-directory path. 1362 find_symlinks_in () { 1363 (cd $1 && find . -maxdepth 1 -type l) | sed -e 's|^\./||g' 1364 } 1365 1366 task2_define copy_sysroot "Fix and copy sysroot" 1367 task2_depends1 copy_sysroot build_sysroot 1368 cmd_copy_sysroot () 1369 { 1370 local SL 1371 1372 # Copy the content of $BUILD_DIR/lib to $(sysroot_dir)/usr/lib 1373 copy_directory $ORG_SYSROOT_DIR/i386/lib $(sysroot_dir)/usr/lib32 1374 copy_directory $ORG_SYSROOT_DIR/i386/usr/lib $(sysroot_dir)/usr/lib32 1375 copy_directory $ORG_SYSROOT_DIR/i386/usr/include $(sysroot_dir)/usr/include 1376 1377 copy_directory $ORG_SYSROOT_DIR/amd64/lib $(sysroot_dir)/usr/lib 1378 copy_directory $ORG_SYSROOT_DIR/amd64/usr/lib $(sysroot_dir)/usr/lib 1379 copy_directory $ORG_SYSROOT_DIR/amd64/usr/include $(sysroot_dir)/usr/include 1380 1381 for LIB in lib lib32; do 1382 # We need to fix the symlink like librt.so -> /lib/librt.so.1 1383 # in $(sysroot_dir)/usr/$LIB, they should point to librt.so.1 instead now. 1384 SYMLINKS=$(find_symlinks_in $(sysroot_dir)/usr/$LIB) 1385 cd $(sysroot_dir)/usr/$LIB 1386 for SL in $SYMLINKS; do 1387 # convert /lib/libfoo.so.<n> into 'libfoo.so.<n>' for the target 1388 local DST=$(readlink $SL 2>/dev/null) 1389 local DST2=${DST##/lib/} 1390 if [ "$DST2" != "$DST" ]; then 1391 echo "Fixing symlink $SL --> $DST" 1392 rm $SL && ln -s $DST2 $SL 1393 fi 1394 done 1395 patch_library $(sysroot_dir)/usr/$LIB/libc.so 1396 patch_library $(sysroot_dir)/usr/$LIB/libpthread.so 1397 done 1398 } 1399 1400 task_define patch_toolchain_sources "Patch toolchain sources." 1401 task_depends patch_toolchain_sources download_toolchain_sources 1402 cmd_patch_toolchain_sources () 1403 { 1404 log "PATCHES_DIR = $PATCHES_DIR" 1405 if [ ! -d "$PATCHES_DIR" ]; then 1406 log "$PATCHES_DIR doesn't exist" 1407 return 0 1408 fi 1409 1410 local PATCHES=`(cd $PATCHES_DIR && find . -name "*.patch" | sort ) 2> /dev/null` 1411 if [ -z "$PATCHES" ] ; then 1412 log "No patches files in $PATCHES_DIR" 1413 return 0 1414 fi 1415 1416 PATCHES=`echo $PATCHES | sed -e s%^\./%%g` 1417 for PATCH in $PATCHES; do 1418 PATCHDIR=`dirname $PATCH` 1419 PATCHNAME=`basename $PATCH` 1420 log "Applying $PATCHNAME into $TOOLCHAIN_SRC_DIR/$PATCHDIR" 1421 (cd $TOOLCHAIN_SRC_DIR/$PATCHDIR && patch -p1 < $PATCHES_DIR/$PATCH) 1422 fail_panic "Patch failure!! Please check your patches directory!" 1423 done 1424 1425 log "Done patching." 1426 } 1427 1428 task_define prepare_toolchain_sources "Prepare toolchain sources." 1429 if [ -n "$GIT_BASE" -o -n "$GIT_REFERENCE" ]; then 1430 task_depends prepare_toolchain_sources patch_toolchain_sources 1431 fi 1432 cmd_prepare_toolchain_sources () 1433 { 1434 return 1435 } 1436 1437 task2_define configure_binutils "Configure binutils-$BINUTILS_VERSION" 1438 task2_depends1 configure_binutils prepare_toolchain_sources 1439 task2_depends2 configure_binutils copy_sysroot 1440 cmd_configure_binutils () 1441 { 1442 OUT_DIR=$(build_dir_for binutils) 1443 mkdir -p $OUT_DIR && cd $OUT_DIR && 1444 run $TOOLCHAIN_SRC_DIR/binutils/binutils-$BINUTILS_VERSION/configure \ 1445 --prefix=$(install_dir) \ 1446 --with-sysroot=$(sysroot_dir) \ 1447 --target=$GCC_TARGET \ 1448 --enable-gold=default \ 1449 --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' \ 1450 --with-gold-ldflags='-static-libgcc -static-libstdc++' \ 1451 --with-bugurl=http://source.android.com/source/report-bugs.html 1452 } 1453 1454 task2_define build_binutils "Build binutils-$BINUTILS_VERSION" 1455 task2_depends2 build_binutils configure_binutils 1456 cmd_build_binutils () 1457 { 1458 cd $(build_dir_for binutils) && 1459 make $MAKE_FLAGS 1460 } 1461 1462 task2_define install_binutils "Install binutils-$BINUTILS_VERSION" 1463 task2_depends2 install_binutils build_binutils 1464 cmd_install_binutils () 1465 { 1466 cd $(build_dir_for binutils) && 1467 make install 1468 } 1469 1470 task2_define extract_gmp "Extract sources for gmp-$GMP_VERSION" 1471 task2_depends1 extract_gmp prepare_toolchain_sources 1472 cmd_extract_gmp () 1473 { 1474 OUT_DIR=$(build_dir_for gmp) 1475 GMP_TARBALL=$TOOLCHAIN_SRC_DIR/gmp/gmp-$GMP_VERSION.tar.bz2 1476 if [ ! -f "$GMP_TARBALL" ]; then 1477 GMP_TARBALL=$TOOLCHAIN_SRC_DIR/tarballs/gmp-$GMP_VERSION.tar.bz2 1478 if [ ! -f "$GMP_TARBALL" ]; then 1479 panic "Can't find gmp-$GMP_VERSION sources!!" 1480 fi 1481 fi 1482 mkdir -p $OUT_DIR && cd $OUT_DIR && 1483 tar xjf "$GMP_TARBALL" 1484 } 1485 1486 task2_define configure_gmp "Configure gmp-$GMP_VERSION" 1487 task2_depends2 configure_gmp extract_gmp install_binutils 1488 cmd_configure_gmp () 1489 { 1490 export ABI=$GMP_ABI && 1491 cd $(build_dir_for gmp) && mkdir -p build && cd build && 1492 ../gmp-$GMP_VERSION/configure \ 1493 --prefix=$(install_dir) \ 1494 --host=$GMP_TARGET \ 1495 --with-sysroot=$(install_dir) \ 1496 --disable-shared 1497 } 1498 1499 task2_define build_gmp "Build gmp-$GMP_VERSION" 1500 task2_depends2 build_gmp configure_gmp 1501 cmd_build_gmp () 1502 { 1503 export ABI=$GMP_ABI && 1504 cd $(build_dir_for gmp)/build && 1505 make $MAKE_FLAGS 1506 } 1507 1508 task2_define install_gmp "Install gmp-$GMP_VERSION" 1509 task2_depends2 install_gmp build_gmp 1510 cmd_install_gmp () 1511 { 1512 cd $(build_dir_for gmp)/build && 1513 make install 1514 } 1515 1516 # Third, build mpfr 1517 task2_define extract_mpfr "Extract sources from mpfr-$MPFR_VERSION" 1518 task2_depends1 extract_mpfr prepare_toolchain_sources 1519 cmd_extract_mpfr () 1520 { 1521 OUT_DIR=$(build_dir_for mpfr) 1522 MPFR_TARBALL=$TOOLCHAIN_SRC_DIR/mpfr/mpfr-$MPFR_VERSION.tar.bz2 1523 if [ ! -f "$MPFR_TARBALL" ]; then 1524 MPFR_TARBALL=$TOOLCHAIN_SRC_DIR/tarballs/mpfr-$MPFR_VERSION.tar.bz2 1525 if [ ! -f "$MPFR_TARBALL" ]; then 1526 panic "Can't find mpfr-$MPFR_VERSION sources!!" 1527 fi 1528 fi 1529 mkdir -p $OUT_DIR && cd $OUT_DIR && 1530 tar xjf "$MPFR_TARBALL" 1531 } 1532 1533 task2_define configure_mpfr "Configure mpfr-$MPFR_VERSION" 1534 task2_depends2 configure_mpfr extract_mpfr install_gmp 1535 cmd_configure_mpfr () 1536 { 1537 cd $(build_dir_for mpfr) && mkdir -p build && cd build && 1538 run ../mpfr-$MPFR_VERSION/configure \ 1539 --prefix=$(install_dir) \ 1540 --host=$GMP_TARGET \ 1541 --with-gmp=$(install_dir) \ 1542 --with-sysroot=$(sysroot_dir) \ 1543 --disable-shared 1544 } 1545 1546 task2_define build_mpfr "Build mpfr-$MPFR_VERSION" 1547 task2_depends2 build_mpfr configure_mpfr 1548 cmd_build_mpfr () 1549 { 1550 cd $(build_dir_for mpfr)/build && 1551 run make $MAKE_FLAGS 1552 } 1553 1554 task2_define install_mpfr "Install mpfr-$MPFR_VERSION" 1555 task2_depends2 install_mpfr build_mpfr 1556 cmd_install_mpfr () 1557 { 1558 cd $(build_dir_for mpfr)/build && 1559 run make install 1560 } 1561 1562 task2_define extract_mpc "Extract sources for mpc-$MPC_VERSION" 1563 task2_depends1 extract_mpc prepare_toolchain_sources 1564 cmd_extract_mpc () 1565 { 1566 OUT_DIR=$(build_dir_for mpc) 1567 MPC_TARBALL=$TOOLCHAIN_SRC_DIR/mpc/mpc-$MPC_VERSION.tar.gz 1568 if [ ! -f "$MPC_TARBALL" ]; then 1569 MPC_TARBALL=$TOOLCHAIN_SRC_DIR/tarballs/mpc-$MPC_VERSION.tar.gz 1570 if [ ! -f "$MPC_TARBALL" ]; then 1571 panic "Can't find mpc-$MPC_VERSION sources!!" 1572 fi 1573 fi 1574 mkdir -p $OUT_DIR && cd $OUT_DIR && 1575 tar xzf "$MPC_TARBALL" 1576 } 1577 1578 task2_define configure_mpc "Configure mpc-$MPC_VERSION" 1579 task2_depends2 configure_mpc extract_mpc install_mpfr 1580 cmd_configure_mpc () 1581 { 1582 cd $(build_dir_for mpc) && mkdir -p build && cd build && 1583 run ../mpc-$MPC_VERSION/configure \ 1584 --prefix=$(install_dir) \ 1585 --host=$GMP_TARGET \ 1586 --with-gmp=$(install_dir) \ 1587 --with-mpfr=$(install_dir) \ 1588 --disable-shared 1589 } 1590 1591 task2_define build_mpc "Build mpc-$MPC_VERSION" 1592 task2_depends2 build_mpc configure_mpc 1593 cmd_build_mpc () 1594 { 1595 cd $(build_dir_for mpc)/build && 1596 run make $MAKE_FLAGS 1597 } 1598 1599 task2_define install_mpc "Install mpc-$MPC_VERSION" 1600 task2_depends2 install_mpc build_mpc 1601 cmd_install_mpc () 1602 { 1603 cd $(build_dir_for mpc)/build && 1604 run make install 1605 } 1606 1607 task2_define extract_isl "Extract sources for isl-$ISL_VERSION" 1608 task2_depends2 extract_isl prepare_toolchain_sources 1609 cmd_extract_isl () 1610 { 1611 OUT_DIR=$(build_dir_for isl) 1612 ISL_TARBALL=$TOOLCHAIN_SRC_DIR/isl/isl-$ISL_VERSION.tar.bz2 1613 if [ ! -f "$ISL_TARBALL" ]; then 1614 panic "Can't find isl-$ISL_VERSION sources!!" 1615 fi 1616 mkdir -p $OUT_DIR && cd $OUT_DIR && 1617 tar xf "$ISL_TARBALL" 1618 } 1619 1620 task2_define configure_isl "Configuring isl-$ISL_VERSION" 1621 task2_depends2 configure_isl extract_isl install_gmp 1622 cmd_configure_isl () 1623 { 1624 cd $(build_dir_for isl) && mkdir -p build && cd build && 1625 run ../isl-$ISL_VERSION/configure \ 1626 --prefix=$(install_dir) \ 1627 --host=$GMP_TARGET \ 1628 --with-gmp-prefix=$(install_dir) \ 1629 --with-sysroot=$(sysroot_dir) \ 1630 --disable-shared 1631 } 1632 1633 task2_define build_isl "Building isl-$ISL_VERSION" 1634 task2_depends2 build_isl configure_isl 1635 cmd_build_isl () 1636 { 1637 cd $(build_dir_for isl)/build && 1638 run make $MAKE_FLAGS 1639 } 1640 1641 task2_define install_isl "Installing isl-$ISL_VERSION" 1642 task2_depends2 install_isl build_isl 1643 cmd_install_isl () 1644 { 1645 cd $(build_dir_for isl)/build && 1646 make install 1647 } 1648 1649 task2_define configure_cloog "Configure Cloog-$CLOOG_VERSION" 1650 task2_depends2 configure_cloog prepare_toolchain_sources install_gmp install_isl 1651 cmd_configure_cloog () { 1652 mkdir -p $(build_dir_for cloog)/build && cd $(build_dir_for cloog)/build && 1653 run $TOOLCHAIN_SRC_DIR/cloog/cloog-$CLOOG_VERSION/configure \ 1654 --prefix=$(install_dir) \ 1655 --host=$GMP_TARGET \ 1656 --with-gmp-prefix=$(install_dir) \ 1657 --with-sysroot=$(sysroot_dir) \ 1658 --disable-shared 1659 } 1660 1661 task2_define build_cloog "Building Cloog-$CLOOG_VERSION" 1662 task2_depends2 build_cloog configure_cloog 1663 cmd_build_cloog () 1664 { 1665 cd $(build_dir_for cloog)/build && 1666 run make $MAKE_FLAGS 1667 } 1668 1669 task2_define install_cloog "Installing Cloog-$CLOOG_VERSION" 1670 task2_depends2 install_cloog build_cloog 1671 cmd_install_cloog () 1672 { 1673 cd $(build_dir_for cloog)/build && 1674 run make install 1675 } 1676 1677 # Fourth, the compiler itself 1678 task2_define configure_gcc "Configure gcc-$GCC_VERSION" 1679 task2_depends1 configure_gcc prepare_toolchain_sources 1680 task2_depends2 configure_gcc install_binutils install_gmp install_mpfr install_mpc install_cloog 1681 cmd_configure_gcc () 1682 { 1683 local EXTRA_CONFIGURE_FLAGS= 1684 if [ "$GCC_VERSION" != "4.6" ]; then 1685 EXTRA_CONFIGURE_FLAGS="--with-cloog=$(install_dir)" 1686 fi 1687 OUT_DIR=$(build_dir_for gcc) 1688 mkdir -p $OUT_DIR && cd $OUT_DIR && 1689 export CC=$HOST_CC && 1690 export CC_FOR_TARGET="$HOST_CC" && 1691 run $TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION/configure \ 1692 --prefix=$(install_dir) \ 1693 --with-sysroot=$(sysroot_dir) \ 1694 --disable-nls \ 1695 --with-gmp=$(install_dir) \ 1696 --with-mpfr=$(install_dir) \ 1697 --with-mpc=$(install_dir) \ 1698 --target=$GCC_TARGET \ 1699 --with-arch=x86-64 \ 1700 --with-multilib-list=m32,m64 \ 1701 --disable-plugin \ 1702 --disable-docs \ 1703 --disable-bootstrap \ 1704 --disable-libgomp \ 1705 --disable-libmudflap \ 1706 --disable-libquadmath \ 1707 --enable-target-optspace \ 1708 --enable-gold=default \ 1709 --enable-languages=c,c++ \ 1710 $EXTRA_CONFIGURE_FLAGS 1711 } 1712 1713 task2_define build_gcc "Build gcc-$GCC_VERSION" 1714 task2_depends2 build_gcc configure_gcc 1715 cmd_build_gcc () 1716 { 1717 cd $(build_dir_for gcc) && 1718 make $MAKE_FLAGS 1719 } 1720 1721 task2_define install_gcc "Install gcc-$GCC_VERSION" 1722 task2_depends2 install_gcc build_gcc 1723 cmd_install_gcc () 1724 { 1725 cd $(build_dir_for gcc) && 1726 make install 1727 } 1728 1729 task2_define cleanup_toolchain "Cleanup toolchain" 1730 task2_depends2 cleanup_toolchain install_gcc 1731 cmd_cleanup_toolchain () 1732 { 1733 # Remove un-needed directories and files 1734 rm -rf $(install_dir)/share 1735 rm -rf $(install_dir)/man 1736 rm -rf $(install_dir)/info 1737 rm -rf $(install_dir)/libexec/*/*/install-tools 1738 #rm -rf $(install_dir)/$GCC_TARGET/bin 1739 find $(install_dir) -name "*.la" -exec rm -f {} \; 1740 1741 (strip $(install_dir)/bin/*) 1742 (strip $(install_dir)/libexec/gcc/$GCC_TARGET/*/*) 1743 true 1744 } 1745 1746 task2_define package_toolchain "Package final toolchain" 1747 task2_depends2 package_toolchain cleanup_toolchain 1748 cmd_package_toolchain () 1749 { 1750 # Copy this script to the install directory 1751 cp -f $0 $(install_dir) 1752 fail_panic "Could not copy build script to install directory" 1753 1754 if [ -d "$PATCHES_DIR" ]; then 1755 # Copy patches to the install directory 1756 cp -rf "$PATCHES_DIR" $(install_dir) 1757 fail_panic "Could not copy patch directory to install directory" 1758 fi 1759 1760 # Copy the SOURCES file as well 1761 cp $DOWNLOAD_DIR/SOURCES $(install_dir)/PACKAGE_SOURCES && 1762 cp $TOOLCHAIN_SRC_DIR/SOURCES $(install_dir)/TOOLCHAIN_SOURCES 1763 fail_panic "Could not copy SOURCES files to install directory" 1764 1765 # Package everything 1766 pack_archive $TOOLCHAIN_ARCHIVE "`dirname $(install_dir)`" "`basename $(install_dir)`" 1767 } 1768 1769 task2_define install_toolchain "Install final toolchain" 1770 task2_depends2 install_toolchain cleanup_toolchain 1771 cmd_install_toolchain () 1772 { 1773 copy_directory "$(install_dir)" "$PREFIX_DIR/$TOOLCHAIN_NAME" 1774 cp -f $0 "$PREFIX_DIR/$TOOLCHAIN_NAME/" 1775 } 1776 1777 # Make sure that the second toolchain depends on the first one 1778 task_depends configure_binutils_2 install_gcc_1 1779 1780 if [ "$ONLY_SYSROOT" = "yes" ]; then 1781 MAIN_TASK=copy_sysroot 1782 COMPLETION_TEXT="Done, see sysroot files in $(sysroot_dir)" 1783 elif [ -n "$PREFIX_DIR" ]; then 1784 if [ -z "$BOOTSTRAP" ]; then 1785 MAIN_TASK=install_toolchain_1 1786 else 1787 MAIN_TASK=install_toolchain_2 1788 fi 1789 COMPLETION_TEXT="Done, see $PREFIX_DIR/$TOOLCHAIN_NAME" 1790 else 1791 if [ -z "$BOOTSTRAP" ]; then 1792 MAIN_TASK=package_toolchain_1 1793 else 1794 MAIN_TASK=package_toolchain_2 1795 fi 1796 COMPLETION_TEXT="Done, see $TOOLCHAIN_ARCHIVE" 1797 fi 1798 1799 if [ "$LIST_TASKS" ]; then 1800 task_dump 1801 else 1802 run_task $MAIN_TASK 1803 echo "$COMPLETION_TEXT" 1804 fi 1805