blob: 4d509bff1f7b0c2f30a5b0d46cd1634b1a829d4d [file] [log] [blame]
David Turner0c7a4a92014-03-12 14:58:19 +08001#!/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
Andrew Hsieh22bcfb62014-03-12 15:14:24 +080026# with GLibc 2.11, only the machine code it generates.
David Turner0c7a4a92014-03-12 14:58:19 +080027#
28
29PROGNAME="`basename \"$0\"`"
30PATCHES_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
40panic ()
41{
42 echo "ERROR: $@"
43 exit 1
44}
45
46fail_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
56OS=$(uname -s)
57if [ "$OS" != Linux ]; then
58 panic "This script can only run on Linux machines!"
59fi
60
Andrew Hsieh22bcfb62014-03-12 15:14:24 +080061UBUNTU_ARCHS="i386 amd64"
62
David Turner0c7a4a92014-03-12 14:58:19 +080063# 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
67set_host_bits ()
68{
69 HOST_BITS=$1
70 GMP_ABI=$1
71 case $1 in
72 32)
73 HOST_ARCH=i686
David Turner0c7a4a92014-03-12 14:58:19 +080074 GCC_TARGET=i686-linux
75 GMP_TARGET=i386-linux
76 ;;
77 64)
78 HOST_ARCH=x86_64
David Turner0c7a4a92014-03-12 14:58:19 +080079 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
88BUILD_ARCH=$(uname -m)
89case "$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"
104esac
105
106# Versions of various toolchain components, do not touch unless you know
107# what you're doing!
108
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800109BINUTILS_VERSION=2.23
David Turner0c7a4a92014-03-12 14:58:19 +0800110GMP_VERSION=5.0.5
111MPFR_VERSION=3.1.1
112MPC_VERSION=1.0.1
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800113GCC_VERSION=4.6
David Turner0c7a4a92014-03-12 14:58:19 +0800114CLOOG_VERSION=0.18.0
115ISL_VERSION=0.11.1
116
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800117GLIBC_VERSION=2.11
118
David Turner0c7a4a92014-03-12 14:58:19 +0800119GIT_CMD=git
120GIT_DATE=
121GIT_BRANCH=master
122GIT_REFERENCE=
123GIT_BASE=
124GIT_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.
128install_dir () { echo "$WORK_DIR/$PHASE/$TOOLCHAIN_NAME"; }
129
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800130# Given an input string that looks like <major>.<minor>.<patch>
131# Return <major>.<minor> only.
132major_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
David Turner0c7a4a92014-03-12 14:58:19 +0800138# Location where we're going to install the final binaries
139# If empty, TOOLCHAIN_ARCHIVE will be generated
140PREFIX_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).
145sysroot_dir () { echo "$(install_dir)/sysroot"; }
146
147# Try to parallelize the build for faster performance.
148JOBS=$(cat /proc/cpuinfo | grep -c processor)
149
150# The base URL of the Ubuntu mirror we're going to use.
151UBUNTU_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")
155UBUNTU_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#
164UBUNTU_PACKAGES=
165
166add_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
173add_ubuntu_package \
174 linux-libc-dev \
175 libc6 \
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800176 libc6-dev \
177 libcap2 \
178 libcap-dev \
179 libattr1 \
180 libattr1-dev \
181 libacl1 \
182 libacl1-dev \
David Turner0c7a4a92014-03-12 14:58:19 +0800183
184# The X11 headers and binaries (for the emulator)
185add_ubuntu_package \
186 libx11-6 \
187 libx11-dev \
David Turner0c7a4a92014-03-12 14:58:19 +0800188 libxau6 \
David 'Digit' Turner1b0544d2014-03-27 13:51:24 +0100189 libxcb1-dev \
David Turner0c7a4a92014-03-12 14:58:19 +0800190 libxdmcp6 \
David 'Digit' Turner1b0544d2014-03-27 13:51:24 +0100191 libxext-dev \
David Turner0c7a4a92014-03-12 14:58:19 +0800192 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)
198add_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)
209add_ubuntu_package \
210 libasound2 \
211 libasound2-dev \
212 libesd0-dev \
213 libaudiofile-dev \
214 libpulse0 \
215 libpulse-dev
216
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800217# ZLib and others.
David Turner0c7a4a92014-03-12 14:58:19 +0800218add_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
235OPTION_HELP=no
236VERBOSE=0
237FORCE=no
238ONLY_SYSROOT=no
239ONLY_TOOLCHAIN_DIR=
240BOOTSTRAP=
241PARAMETERS=
242FORCE_32=
243LIST_TASKS=
244
245for opt do
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800246 optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
247 case $opt in
David Turner0c7a4a92014-03-12 14:58:19 +0800248 --help|-h|-\?) OPTION_HELP=yes
249 ;;
250 --verbose) VERBOSE=$(( $VERBOSE + 1 ))
251 ;;
252 --force) FORCE="yes"
253 ;;
254 --32-bits) FORCE_32=true
255 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800256 --ubuntu-mirror=*) UBUNTU_MIRROR=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800257 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800258 --ubuntu-release=*) UBUNTU_RELEASE=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800259 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800260 --prefix=*) PREFIX_DIR=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800261 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800262 --work-dir=*) WORK_DIR=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800263 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800264 --gcc-version=*) GCC_VERSION=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800265 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800266 --binutils-version=*) BINUTILS_VERSION=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800267 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800268 --gmp-version=*) GMP_VERSION=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800269 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800270 --mpfr-version=*) MPFR_VERSION=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800271 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800272 --mpc-version=*) MPC_VERSION=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800273 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800274 --isl-version=*) ISL_VERSION=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800275 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800276 --cloog-version=*) CLOOG_VERSION=$oparg
David Turner0c7a4a92014-03-12 14:58:19 +0800277 ;;
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 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800288 --out-dir=*) OPTION_OUT_DIR=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800289 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800290 --cc=*) OPTION_CC=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800291 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800292 --jobs=*) JOBS=$optarg
David Turner0c7a4a92014-03-12 14:58:19 +0800293 ;;
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800294 -j*) JOBS=${opt#-j}
David Turner0c7a4a92014-03-12 14:58:19 +0800295 ;;
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
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800308 PARAMETERS=$opt
David Turner0c7a4a92014-03-12 14:58:19 +0800309 else
310 PARAMETERS="$PARAMETERS $opt"
311 fi
312 esac
313done
314
315if [ "$OPTION_HELP" = "yes" ]; then
316 cat << EOF
317
318Usage: $PROGNAME [options] [<path-to-toolchain-sources>]
319
320This script is used to rebuild a custom Linux host toolchain that targets
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800321GLibc $GLIBC_VERSION or higher. The machine code generated by this toolchain
322will run properly on Ubuntu $UBUNTU_RELEASE or higher.
David Turner0c7a4a92014-03-12 14:58:19 +0800323
324If you're running on a 32-bit system, it will generate a 32-bit toolchain.
325If you're running on a 64-bit system, it will generate a 64-bit toolchain
326unless you use the --32-bits option.
327
328You can provide the path to a local copy of the toolchain sources repository
329as a first parameter. If you don't, the sources will be downloaded and
330extracted automatically into your work directory.
331
332Note that this script will download various binary packages from Ubuntu
333servers in order to prepare a compatible "sysroot".
334
335By default, it generates a package archive ($TOOLCHAIN_ARCHIVE) but you can,
336as an alternative, ask for direct installation with --prefix=<path>
337
338Use the bootstrap option to re-generate the toolchain with itself. This is
339useful if you want to ensure that the generated compiler binaries will work
340properly on Ubuntu 8.04 or higher. By default, they will only run on systems
341that match your build system's C library ABI, or higher.
342
343Options: [defaults in brackets after descriptions]
344EOF
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 Hsieh22bcfb62014-03-12 15:14:24 +0800352 echo " --only-sysroot Only download and build sysroot packages"
David Turner0c7a4a92014-03-12 14:58:19 +0800353 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
372fi
373
374if [ "$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
380fi
381
382# Determine root working directory for our script
383if [ -z "$WORK_DIR" ]; then
384 WORK_DIR=$(mktemp -d /tmp/$USER-gcc-$HOST_BITS-XXXXXX)
385 WORK_DIR_CLEANUP=true
386else
387 mkdir -p "$WORK_DIR"
388 fail_panic "Could not create directory: $WORK_DIR"
389 WORK_DIR_CLEANUP=false
390fi
391
392if [ -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
413else
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
427fi
428
429# Location of original sysroot. This is where we're going to extract all
430# binary Ubuntu packages.
431ORG_SYSROOT_DIR=$WORK_DIR/sysroot
432
433# Name of the final generated toolchain
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800434TOOLCHAIN_NAME=$GCC_TARGET-glibc$GLIBC_VERSION-$(major_minor_only $GCC_VERSION)
David Turner0c7a4a92014-03-12 14:58:19 +0800435
436# Name of the final toolchain binary tarball that this script will create
437TOOLCHAIN_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.
442SOURCES_LIST=$WORK_DIR/SOURCES
443
444# Determine Make flags
445MAKE_FLAGS="-j$JOBS"
446
447# Create the work directory
448mkdir -p "$WORK_DIR"
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800449mkdir -p "$TOOLCHAIN_SRC_DIR"
David Turner0c7a4a92014-03-12 14:58:19 +0800450
451# Location where we download packages from the Ubuntu servers
452DOWNLOAD_DIR=$WORK_DIR/download
453
454# Empty the SOURCES file
455rm -f "$SOURCES_LIST" && touch "$SOURCES_LIST"
456
457
458if [ "$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
475else
476 run () {
477 "$@" >>$TMPLOG 2>&1
478 }
479 log () {
480 return
481 }
482 log2 () {
483 return
484 }
485fi
486
487# Sanitize a path list, we want to remove empty sub-dirs and
488# leading/trailing columns.
489sanitize_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' Turner1b0544d2014-03-27 13:51:24 +0100496PATH=$(sanitize_path_list $PATH)
497LD_LIBRARY_PATH=$(sanitize_path_list $LD_LIBRARY_PATH)
498
David Turner0c7a4a92014-03-12 14:58:19 +0800499BUILD_DIR=$WORK_DIR/build
500mkdir -p $BUILD_DIR
501
502TMPLOG=$BUILD_DIR/build.log
503rm -rf $TMPLOG && touch $TMPLOG
504
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800505build_dir_for () { echo "$BUILD_DIR/$PHASE/$1"; }
David Turner0c7a4a92014-03-12 14:58:19 +0800506
507TIMESTAMPS_DIR=$BUILD_DIR/timestamps
508mkdir -p $TIMESTAMPS_DIR
509
510stamp_check () {
511 [ -f "$TIMESTAMPS_DIR/$1" ]
512}
513
514stamp_clear () {
515 rm -f "$TIMESTAMPS_DIR/$1"
516}
517
518stamp_set () {
519 touch "$TIMESTAMPS_DIR/$1"
520}
521
522if [ "$FORCE" = "yes" ] ; then
523 echo "Cleaning up timestamps (forcing the build)."
524 rm -f $TIMESTAMPS_DIR/*
525fi
526
527if [ "$VERBOSE" = 0 ] ; then
528 echo "To follow build, run: tail -F $TMPLOG"
529fi
530
531# returns 0 iff the string in $2 matches the pattern in $1
532# $1: pattern
533# $2: string
534pattern_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#
551find_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#
568copy_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
580find_program CMD_WGET wget
581find_program CMD_CURL curl
582find_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
588download_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
634download_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
648pack_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
690no_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#
701get_ubuntu_packages_list ()
702{
703 local RELEASE=$2
704 local BASE="`no_trailing_slash \"$1\"`"
Andrew Hsieh22bcfb62014-03-12 15:14:24 +0800705 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 Turner0c7a4a92014-03-12 14:58:19 +0800715
716 # Write a small awk script used to extract filenames for a given package
717 cat > $DOWNLOAD_DIR/extract-filename.awk <<EOF
718BEGIN {
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
738END {
739 print FILE
740}
741EOF
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 Hsieh22bcfb62014-03-12 15:14:24 +0800748# $3: Ubuntu arch ("i386" or "amd64")
David Turner0c7a4a92014-03-12 14:58:19 +0800749#
750get_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 Hsieh22bcfb62014-03-12 15:14:24 +0800755 local FILE=`awk -f "$DOWNLOAD_DIR/extract-filename.awk" -v PKG=$1 $DOWNLOAD_DIR/Packages-$3`
David Turner0c7a4a92014-03-12 14:58:19 +0800756 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#
766compute_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>
789int main(void) {
790 printf("%d\n",sizeof(void*)*8);
791 return 0;
792}
793EOF
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
827compute_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#
838var_value ()
839{
840 eval echo \$$1
841}
842
843var_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
855var_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
891var_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
911var_list_first ()
912{
913 local VAL=`var_value $1`
914 _list_first $VAL
915}
916
917var_list_rest ()
918{
919 local VAL=`var_value $1`
920 _list_rest $VAL
921}
922
923ALL_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#
930task_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)
948task2_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
958task_set ()
959{
960 local TASK="$1"
961 local FIELD="$2"
962 shift; shift;
963 eval TASK_${TASK}__${FIELD}=\"$@\"
964}
965
966task_get ()
967{
968 var_value TASK_$1__$2
969}
970
971# return the list of dependencies for a given task
972task_get_deps ()
973{
974 task_get $1 deps
975}
976
977task_get_cmd ()
978{
979 task_get $1 cmd
980}
981
982task_get_descr ()
983{
984 task_get $1 descr
985}
986
987# $1: task name
988# $2+: other tasks this task depends on.
989task_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
998task2_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
1008task2_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
1019task_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
1031task_visit ()
1032{
1033 task_set $TASK visit 1
1034}
1035
1036task_unvisit ()
1037{
1038 task_set $TASK visit 0
1039}
1040
1041task_is_visited ()
1042{
1043 [ `task_get $TASK visit` = 1 ]
1044}
1045
1046task_queue_reset ()
1047{
1048 TASK_QUEUE=
1049}
1050
1051task_queue_push ()
1052{
1053 var_list_append TASK_QUEUE $1
1054}
1055
1056task_queue_pop ()
1057{
1058 local FIRST=`var_list_first TASK_QUEUE`
1059 TASK_QUEUE=`var_list_rest TASK_QUEUE`
1060}
1061
1062do_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
1094list_first () {
1095 set -- "$@"
1096 echo "$1"
1097}
1098
1099# Append an item to a given list
1100list_append () {
1101 local ITEM=$1
1102 shift;
1103 echo $@${@:+" "}$1
1104}
1105
1106# Return the second-to-last items of a space-separated list
1107list_rest () {
1108 set -- "$@"
1109 shift
1110 echo "$@"
1111}
1112
1113# Reverse a space-separated list
1114list_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#
1136task_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
1176run_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
1227toolchain_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
1263task_define download_toolchain_sources "Download toolchain sources from $GIT_BASE "
1264cmd_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
1278task_define download_ubuntu_packages_list "Download Ubuntu packages list"
1279cmd_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
1286task_define download_packages "Download Ubuntu packages"
1287task_depends download_packages download_ubuntu_packages_list
1288cmd_download_packages ()
1289{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001290 local PACKAGE PKGURL
David Turner0c7a4a92014-03-12 14:58:19 +08001291
1292 rm -f $DOWNLOAD_DIR/SOURCES && touch $DOWNLOAD_DIR/SOURCES
1293 for PACKAGE in $UBUNTU_PACKAGES; do
1294 echo "Downloading $PACKAGE"
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001295 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 Turner0c7a4a92014-03-12 14:58:19 +08001301 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
1309task_define build_sysroot "Build sysroot"
1310task_depends build_sysroot download_packages
1311
1312cmd_build_sysroot ()
1313{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001314 local PACKAGE PKGURL SRC_PKG
1315 mkdir -p $SRC_PKG $ORG_SYSROOT_DIR
David Turner0c7a4a92014-03-12 14:58:19 +08001316 for PACKAGE in $UBUNTU_PACKAGES; do
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001317 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 Turner0c7a4a92014-03-12 14:58:19 +08001323 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
1328patch_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
1335phase_1 ()
1336{
1337 PHASE=1
1338 $@
1339}
1340
1341# Used to setup phase 2 then run a command
1342phase_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.
1362find_symlinks_in () {
1363 (cd $1 && find . -maxdepth 1 -type l) | sed -e 's|^\./||g'
1364}
1365
1366task2_define copy_sysroot "Fix and copy sysroot"
1367task2_depends1 copy_sysroot build_sysroot
1368cmd_copy_sysroot ()
1369{
1370 local SL
1371
1372 # Copy the content of $BUILD_DIR/lib to $(sysroot_dir)/usr/lib
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001373 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 Turner0c7a4a92014-03-12 14:58:19 +08001376
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001377 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 Turner0c7a4a92014-03-12 14:58:19 +08001397 done
David Turner0c7a4a92014-03-12 14:58:19 +08001398}
1399
1400task_define patch_toolchain_sources "Patch toolchain sources."
1401task_depends patch_toolchain_sources download_toolchain_sources
1402cmd_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
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001415
David Turner0c7a4a92014-03-12 14:58:19 +08001416 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
1428task_define prepare_toolchain_sources "Prepare toolchain sources."
1429if [ -n "$GIT_BASE" -o -n "$GIT_REFERENCE" ]; then
1430 task_depends prepare_toolchain_sources patch_toolchain_sources
1431fi
1432cmd_prepare_toolchain_sources ()
1433{
1434 return
1435}
1436
1437task2_define configure_binutils "Configure binutils-$BINUTILS_VERSION"
1438task2_depends1 configure_binutils prepare_toolchain_sources
1439task2_depends2 configure_binutils copy_sysroot
1440cmd_configure_binutils ()
1441{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001442 OUT_DIR=$(build_dir_for binutils)
David Turner0c7a4a92014-03-12 14:58:19 +08001443 mkdir -p $OUT_DIR && cd $OUT_DIR &&
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001444 run $TOOLCHAIN_SRC_DIR/binutils/binutils-$BINUTILS_VERSION/configure \
David Turner0c7a4a92014-03-12 14:58:19 +08001445 --prefix=$(install_dir) \
1446 --with-sysroot=$(sysroot_dir) \
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001447 --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 Turner0c7a4a92014-03-12 14:58:19 +08001452}
1453
1454task2_define build_binutils "Build binutils-$BINUTILS_VERSION"
1455task2_depends2 build_binutils configure_binutils
1456cmd_build_binutils ()
1457{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001458 cd $(build_dir_for binutils) &&
David Turner0c7a4a92014-03-12 14:58:19 +08001459 make $MAKE_FLAGS
1460}
1461
1462task2_define install_binutils "Install binutils-$BINUTILS_VERSION"
1463task2_depends2 install_binutils build_binutils
1464cmd_install_binutils ()
1465{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001466 cd $(build_dir_for binutils) &&
David Turner0c7a4a92014-03-12 14:58:19 +08001467 make install
1468}
1469
1470task2_define extract_gmp "Extract sources for gmp-$GMP_VERSION"
1471task2_depends1 extract_gmp prepare_toolchain_sources
1472cmd_extract_gmp ()
1473{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001474 OUT_DIR=$(build_dir_for gmp)
David Turner0c7a4a92014-03-12 14:58:19 +08001475 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
1486task2_define configure_gmp "Configure gmp-$GMP_VERSION"
1487task2_depends2 configure_gmp extract_gmp install_binutils
1488cmd_configure_gmp ()
1489{
1490 export ABI=$GMP_ABI &&
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001491 cd $(build_dir_for gmp) && mkdir -p build && cd build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001492 ../gmp-$GMP_VERSION/configure \
1493 --prefix=$(install_dir) \
1494 --host=$GMP_TARGET \
1495 --with-sysroot=$(install_dir) \
1496 --disable-shared
1497}
1498
1499task2_define build_gmp "Build gmp-$GMP_VERSION"
1500task2_depends2 build_gmp configure_gmp
1501cmd_build_gmp ()
1502{
1503 export ABI=$GMP_ABI &&
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001504 cd $(build_dir_for gmp)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001505 make $MAKE_FLAGS
1506}
1507
1508task2_define install_gmp "Install gmp-$GMP_VERSION"
1509task2_depends2 install_gmp build_gmp
1510cmd_install_gmp ()
1511{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001512 cd $(build_dir_for gmp)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001513 make install
1514}
1515
1516# Third, build mpfr
1517task2_define extract_mpfr "Extract sources from mpfr-$MPFR_VERSION"
1518task2_depends1 extract_mpfr prepare_toolchain_sources
1519cmd_extract_mpfr ()
1520{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001521 OUT_DIR=$(build_dir_for mpfr)
David Turner0c7a4a92014-03-12 14:58:19 +08001522 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
1533task2_define configure_mpfr "Configure mpfr-$MPFR_VERSION"
1534task2_depends2 configure_mpfr extract_mpfr install_gmp
1535cmd_configure_mpfr ()
1536{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001537 cd $(build_dir_for mpfr) && mkdir -p build && cd build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001538 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
1546task2_define build_mpfr "Build mpfr-$MPFR_VERSION"
1547task2_depends2 build_mpfr configure_mpfr
1548cmd_build_mpfr ()
1549{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001550 cd $(build_dir_for mpfr)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001551 run make $MAKE_FLAGS
1552}
1553
1554task2_define install_mpfr "Install mpfr-$MPFR_VERSION"
1555task2_depends2 install_mpfr build_mpfr
1556cmd_install_mpfr ()
1557{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001558 cd $(build_dir_for mpfr)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001559 run make install
1560}
1561
1562task2_define extract_mpc "Extract sources for mpc-$MPC_VERSION"
1563task2_depends1 extract_mpc prepare_toolchain_sources
1564cmd_extract_mpc ()
1565{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001566 OUT_DIR=$(build_dir_for mpc)
David Turner0c7a4a92014-03-12 14:58:19 +08001567 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
1578task2_define configure_mpc "Configure mpc-$MPC_VERSION"
1579task2_depends2 configure_mpc extract_mpc install_mpfr
1580cmd_configure_mpc ()
1581{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001582 cd $(build_dir_for mpc) && mkdir -p build && cd build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001583 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
1591task2_define build_mpc "Build mpc-$MPC_VERSION"
1592task2_depends2 build_mpc configure_mpc
1593cmd_build_mpc ()
1594{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001595 cd $(build_dir_for mpc)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001596 run make $MAKE_FLAGS
1597}
1598
1599task2_define install_mpc "Install mpc-$MPC_VERSION"
1600task2_depends2 install_mpc build_mpc
1601cmd_install_mpc ()
1602{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001603 cd $(build_dir_for mpc)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001604 run make install
1605}
1606
1607task2_define extract_isl "Extract sources for isl-$ISL_VERSION"
1608task2_depends2 extract_isl prepare_toolchain_sources
1609cmd_extract_isl ()
1610{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001611 OUT_DIR=$(build_dir_for isl)
David Turner0c7a4a92014-03-12 14:58:19 +08001612 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
1620task2_define configure_isl "Configuring isl-$ISL_VERSION"
1621task2_depends2 configure_isl extract_isl install_gmp
1622cmd_configure_isl ()
1623{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001624 cd $(build_dir_for isl) && mkdir -p build && cd build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001625 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
1633task2_define build_isl "Building isl-$ISL_VERSION"
1634task2_depends2 build_isl configure_isl
1635cmd_build_isl ()
1636{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001637 cd $(build_dir_for isl)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001638 run make $MAKE_FLAGS
1639}
1640
1641task2_define install_isl "Installing isl-$ISL_VERSION"
1642task2_depends2 install_isl build_isl
1643cmd_install_isl ()
1644{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001645 cd $(build_dir_for isl)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001646 make install
1647}
1648
David Turner0c7a4a92014-03-12 14:58:19 +08001649task2_define configure_cloog "Configure Cloog-$CLOOG_VERSION"
1650task2_depends2 configure_cloog prepare_toolchain_sources install_gmp install_isl
1651cmd_configure_cloog () {
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001652 mkdir -p $(build_dir_for cloog)/build && cd $(build_dir_for cloog)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001653 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
1661task2_define build_cloog "Building Cloog-$CLOOG_VERSION"
1662task2_depends2 build_cloog configure_cloog
1663cmd_build_cloog ()
1664{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001665 cd $(build_dir_for cloog)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001666 run make $MAKE_FLAGS
1667}
1668
1669task2_define install_cloog "Installing Cloog-$CLOOG_VERSION"
1670task2_depends2 install_cloog build_cloog
1671cmd_install_cloog ()
1672{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001673 cd $(build_dir_for cloog)/build &&
David Turner0c7a4a92014-03-12 14:58:19 +08001674 run make install
1675}
1676
1677# Fourth, the compiler itself
1678task2_define configure_gcc "Configure gcc-$GCC_VERSION"
1679task2_depends1 configure_gcc prepare_toolchain_sources
1680task2_depends2 configure_gcc install_binutils install_gmp install_mpfr install_mpc install_cloog
1681cmd_configure_gcc ()
1682{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001683 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)
David Turner0c7a4a92014-03-12 14:58:19 +08001688 mkdir -p $OUT_DIR && cd $OUT_DIR &&
David Turner0c7a4a92014-03-12 14:58:19 +08001689 export CC=$HOST_CC &&
1690 export CC_FOR_TARGET="$HOST_CC" &&
David Turner0c7a4a92014-03-12 14:58:19 +08001691 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) \
David Turner0c7a4a92014-03-12 14:58:19 +08001698 --target=$GCC_TARGET \
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001699 --with-arch=x86-64 \
1700 --with-multilib-list=m32,m64 \
David Turner0c7a4a92014-03-12 14:58:19 +08001701 --disable-plugin \
1702 --disable-docs \
David Turner0c7a4a92014-03-12 14:58:19 +08001703 --disable-bootstrap \
1704 --disable-libgomp \
1705 --disable-libmudflap \
1706 --disable-libquadmath \
1707 --enable-target-optspace \
1708 --enable-gold=default \
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001709 --enable-languages=c,c++ \
1710 $EXTRA_CONFIGURE_FLAGS
David Turner0c7a4a92014-03-12 14:58:19 +08001711}
1712
1713task2_define build_gcc "Build gcc-$GCC_VERSION"
1714task2_depends2 build_gcc configure_gcc
1715cmd_build_gcc ()
1716{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001717 cd $(build_dir_for gcc) &&
David Turner0c7a4a92014-03-12 14:58:19 +08001718 make $MAKE_FLAGS
1719}
1720
1721task2_define install_gcc "Install gcc-$GCC_VERSION"
1722task2_depends2 install_gcc build_gcc
1723cmd_install_gcc ()
1724{
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001725 cd $(build_dir_for gcc) &&
David Turner0c7a4a92014-03-12 14:58:19 +08001726 make install
1727}
1728
1729task2_define cleanup_toolchain "Cleanup toolchain"
1730task2_depends2 cleanup_toolchain install_gcc
1731cmd_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 Turner0c7a4a92014-03-12 14:58:19 +08001737 rm -rf $(install_dir)/libexec/*/*/install-tools
1738 #rm -rf $(install_dir)/$GCC_TARGET/bin
Andrew Hsieh22bcfb62014-03-12 15:14:24 +08001739 find $(install_dir) -name "*.la" -exec rm -f {} \;
David Turner0c7a4a92014-03-12 14:58:19 +08001740
1741 (strip $(install_dir)/bin/*)
1742 (strip $(install_dir)/libexec/gcc/$GCC_TARGET/*/*)
1743 true
1744}
1745
1746task2_define package_toolchain "Package final toolchain"
1747task2_depends2 package_toolchain cleanup_toolchain
1748cmd_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
1769task2_define install_toolchain "Install final toolchain"
1770task2_depends2 install_toolchain cleanup_toolchain
1771cmd_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
1778task_depends configure_binutils_2 install_gcc_1
1779
1780if [ "$ONLY_SYSROOT" = "yes" ]; then
1781 MAIN_TASK=copy_sysroot
1782 COMPLETION_TEXT="Done, see sysroot files in $(sysroot_dir)"
1783elif [ -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"
1790else
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"
1797fi
1798
1799if [ "$LIST_TASKS" ]; then
1800 task_dump
1801else
1802 run_task $MAIN_TASK
1803 echo "$COMPLETION_TEXT"
1804fi