David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 61 | UBUNTU_ARCHS="i386 amd64" |
| 62 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 74 | GCC_TARGET=i686-linux |
| 75 | GMP_TARGET=i386-linux |
| 76 | ;; |
| 77 | 64) |
| 78 | HOST_ARCH=x86_64 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 109 | BINUTILS_VERSION=2.23 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 110 | GMP_VERSION=5.0.5 |
| 111 | MPFR_VERSION=3.1.1 |
| 112 | MPC_VERSION=1.0.1 |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 113 | GCC_VERSION=4.6 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 114 | CLOOG_VERSION=0.18.0 |
| 115 | ISL_VERSION=0.11.1 |
| 116 | |
| 117 | GLIBC_VERSION=2.11 |
| 118 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 188 | libxau6 \ |
David 'Digit' Turner | 4767fbc | 2014-03-27 13:51:24 +0100 | [diff] [blame] | 189 | libxcb1-dev \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 190 | libxdmcp6 \ |
David 'Digit' Turner | 4767fbc | 2014-03-27 13:51:24 +0100 | [diff] [blame] | 191 | libxext-dev \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | ;; |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 332 | Note that this script will download various binary packages from Ubuntu |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 333 | servers in order to prepare a compatible "sysroot". |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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>]" |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 352 | echo " --only-sysroot Only download and build sysroot packages" |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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." |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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]" |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | |
David 'Digit' Turner | 4767fbc | 2014-03-27 13:51:24 +0100 | [diff] [blame] | 496 | PATH=$(sanitize_path_list $PATH) |
| 497 | LD_LIBRARY_PATH=$(sanitize_path_list $LD_LIBRARY_PATH) |
| 498 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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\"`" |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 748 | # $3: Ubuntu arch ("i386" or "amd64") |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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\"`" |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 755 | local FILE=`awk -f "$DOWNLOAD_DIR/extract-filename.awk" -v PKG=$1 $DOWNLOAD_DIR/Packages-$3` |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 .. |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1261 | } |
| 1262 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 | ) |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1290 | local PACKAGE PKGURL |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1291 | |
| 1292 | rm -f $DOWNLOAD_DIR/SOURCES && touch $DOWNLOAD_DIR/SOURCES |
| 1293 | for PACKAGE in $UBUNTU_PACKAGES; do |
| 1294 | echo "Downloading $PACKAGE" |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1314 | local PACKAGE PKGURL SRC_PKG |
| 1315 | mkdir -p $SRC_PKG $ORG_SYSROOT_DIR |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1316 | for PACKAGE in $UBUNTU_PACKAGES; do |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1376 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1397 | done |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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." |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1429 | if [ -n "$GIT_BASE" -o -n "$GIT_REFERENCE" ]; then |
| 1430 | task_depends prepare_toolchain_sources patch_toolchain_sources |
| 1431 | fi |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1432 | cmd_prepare_toolchain_sources () |
| 1433 | { |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 && |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1444 | run $TOOLCHAIN_SRC_DIR/binutils/binutils-$BINUTILS_VERSION/configure \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1445 | --prefix=$(install_dir) \ |
| 1446 | --with-sysroot=$(sysroot_dir) \ |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1486 | task2_define configure_gmp "Configure gmp-$GMP_VERSION" |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1487 | task2_depends2 configure_gmp extract_gmp install_binutils |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1488 | cmd_configure_gmp () |
| 1489 | { |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1490 | export ABI=$GMP_ABI && |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1491 | cd $(build_dir_for gmp) && mkdir -p build && cd build && |
| 1492 | ../gmp-$GMP_VERSION/configure \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 && |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1504 | cd $(build_dir_for gmp)/build && |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1512 | cd $(build_dir_for gmp)/build && |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1513 | make install |
| 1514 | } |
| 1515 | |
| 1516 | # Third, build mpfr |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1533 | task2_define configure_mpfr "Configure mpfr-$MPFR_VERSION" |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1534 | task2_depends2 configure_mpfr extract_mpfr install_gmp |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1535 | cmd_configure_mpfr () |
| 1536 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1537 | cd $(build_dir_for mpfr) && mkdir -p build && cd build && |
| 1538 | run ../mpfr-$MPFR_VERSION/configure \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1550 | cd $(build_dir_for mpfr)/build && |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1558 | cd $(build_dir_for mpfr)/build && |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1559 | run make install |
| 1560 | } |
| 1561 | |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 | |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1578 | task2_define configure_mpc "Configure mpc-$MPC_VERSION" |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1579 | task2_depends2 configure_mpc extract_mpc install_mpfr |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1580 | cmd_configure_mpc () |
| 1581 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1582 | cd $(build_dir_for mpc) && mkdir -p build && cd build && |
| 1583 | run ../mpc-$MPC_VERSION/configure \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1595 | cd $(build_dir_for mpc)/build && |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 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 && |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1680 | task2_depends2 configure_gcc install_binutils install_gmp install_mpfr install_mpc install_cloog |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1681 | cmd_configure_gcc () |
| 1682 | { |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1683 | local EXTRA_CONFIGURE_FLAGS= |
| 1684 | if [ "$GCC_VERSION" != "4.6" ]; then |
| 1685 | EXTRA_CONFIGURE_FLAGS="--with-cloog=$(install_dir)" |
| 1686 | fi |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1687 | OUT_DIR=$(build_dir_for gcc) |
| 1688 | mkdir -p $OUT_DIR && cd $OUT_DIR && |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1689 | export CC=$HOST_CC && |
| 1690 | export CC_FOR_TARGET="$HOST_CC" && |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1691 | run $TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION/configure \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 \ |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1699 | --with-arch=x86-64 \ |
| 1700 | --with-multilib-list=m32,m64 \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1701 | --disable-plugin \ |
| 1702 | --disable-docs \ |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1703 | --disable-bootstrap \ |
| 1704 | --disable-libgomp \ |
| 1705 | --disable-libmudflap \ |
| 1706 | --disable-libquadmath \ |
| 1707 | --enable-target-optspace \ |
| 1708 | --enable-gold=default \ |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1709 | --enable-languages=c,c++ \ |
| 1710 | $EXTRA_CONFIGURE_FLAGS |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1711 | } |
| 1712 | |
| 1713 | task2_define build_gcc "Build gcc-$GCC_VERSION" |
| 1714 | task2_depends2 build_gcc configure_gcc |
| 1715 | cmd_build_gcc () |
| 1716 | { |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 | { |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 1737 | rm -rf $(install_dir)/libexec/*/*/install-tools |
| 1738 | #rm -rf $(install_dir)/$GCC_TARGET/bin |
Andrew Hsieh | 89a270f | 2014-03-12 15:22:31 +0800 | [diff] [blame] | 1739 | find $(install_dir) -name "*.la" -exec rm -f {} \; |
David Turner | c87db05 | 2014-03-12 14:55:59 +0800 | [diff] [blame] | 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 |