#!/bin/sh # # Copyright (C) 2010 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This script is used to rebuild the Linux 32-bit cross-toolchain # that allows you to generate 32-bit binaries that target Ubuntu 8.04 # (a.k.a. Hardy Heron) instead of the host system (which usually is 10.04, # a.k.a. Lucid Lynx) # # You will need a working NDK install or working directory (which is used # to download and patch the toolchain sources from android.git.kernel.org) # # Define the NDK variable in your environment before calling this script, # or it will complain loudly. For example, you can invoke it as: # # export NDK=/path/to/ndk # ./uild-hardy-toolchain.sh # # Then *wait* for a very long time (about 13minutes on an 8-core HP z600) # A package file will be generated in /tmp, its name dumped by the script # in case of success. # # There are no command-line options right now, modify the definitions under # the "CONFIGURATION" section below if you want to change stuff. # ########################################################################### ########################################################################### ##### ##### C O N F I G U R A T I O N ##### ########################################################################### ########################################################################### # We only support running this script on Linux OS=`uname -s` case "$OS" in Linux) OS=linux ;; *) echo "ERROR: This script can only run on Linux!" exit 1 ;; esac # Set V to 1 to enable verbose mode V=${V:-0} # Location of temporary directory where everything will be downloaded # configured, built and installed before we generate the final # package archive ROOT_DIR=/tmp/gcc-hardy32 mkdir -p $ROOT_DIR # Location where we download packages from the Ubuntu servers DOWNLOAD_DIR=$ROOT_DIR/download # Location of the Android NDK if [ -z "$NDK" ] ; then echo "ERROR: Please define the NDK variable to point to a valid" echo " NDK directory (installation or git repository)." echo " This is needed to download the toolchain sources." exit 1 fi NDK_DOWNLOAD_TOOLCHAIN_SOURCES_SH="$NDK/build/tools/download-toolchain-sources.sh" if [ ! -f "$NDK_DOWNLOAD_TOOLCHAIN_SOURCES_SH" ] ; then\ echo "ERROR: Missing script: $NDK_DOWNLOAD_TOOLCHAIN_SOURCES_SH" echo "Your NDK variable probably points to an invalid directory!" exit 1 fi # Versions of various toolchain components, do not touch unless you know # what you're doing! BINUTILS_VERSION=2.19 GMP_VERSION=4.2.4 MPFR_VERSION=2.4.1 GCC_VERSION=4.4.3 GCC_TARGET=i686-linux GMP_TARGET=i386-linux # Location where we will download the toolchain sources TOOLCHAIN_SRC_DIR=$ROOT_DIR/toolchain-src # Location of original sysroot # You must create it with the "hardy-sysroot.sh" script ORG_SYSROOT_DIR=$ROOT_DIR/sysroot # Name of the final generated toolchain TOOLCHAIN_NAME=$GCC_TARGET-glibc2.7-$GCC_VERSION # Name of the final toolchain binary tarball that this script will create TOOLCHAIN_ARCHIVE=/tmp/$TOOLCHAIN_NAME.tar.bz2 # Location where we're going to install the toolchain INSTALL_DIR=$ROOT_DIR/$TOOLCHAIN_NAME # Location of the final sysroot. This must be a sub-directory of INSTALL_DIR # to ensure that the toolchain binaries are properly relocatable (i.e. can # be used when moved to another directory). SYSROOT_DIR=$INSTALL_DIR/sysroot # Try to parallelize the build for faster performance. NUM_CPUS=`cat /proc/cpuinfo | grep processor | wc -l` MAKE_FLAGS="-j$NUM_CPUS" # The list of packages we need to download from the Ubuntu servers and # extract into the original sysroot UBUNTU_PACKAGES= add_ubuntu_package () { UBUNTU_PACKAGES="$UBUNTU_PACKAGES $@" } # The package files containing kernel headers for Hardy and the C # library headers and binaries add_ubuntu_package \ http://mirrors.us.kernel.org/ubuntu//pool/main/l/linux/linux-libc-dev_2.6.24-28.81_i386.deb \ http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.7-10ubuntu7_i386.deb \ http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6-dev_2.7-10ubuntu7_i386.deb # The X11 headers and binaries (for the emulator) add_ubuntu_package \ http://mirrors.us.kernel.org/ubuntu//pool/main/libx/libx11/libx11-6_1.1.3-1ubuntu2_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/libx/libx11/libx11-dev_1.1.3-1ubuntu2_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/x/x11proto-core/x11proto-core-dev_7.0.11-1_all.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/x/x11proto-xext/x11proto-xext-dev_7.0.2-5ubuntu1_all.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/x/x11proto-input/x11proto-input-dev_1.4.2-1_all.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/x/x11proto-kb/x11proto-kb-dev_1.0.3-2ubuntu1_all.deb # Audio libraries (required by the emulator) add_ubuntu_package \ http://mirrors.us.kernel.org/ubuntu//pool/main/a/alsa-lib/libasound2_1.0.15-3ubuntu4_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/a/alsa-lib/libasound2-dev_1.0.15-3ubuntu4_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/e/esound/libesd-alsa0_0.2.38-0ubuntu9_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/e/esound/libesd0-dev_0.2.38-0ubuntu9_i386.deb \ http://security.ubuntu.com/ubuntu/pool/main/a/audiofile/libaudiofile-dev_0.2.6-7ubuntu1.8.04.1_i386.deb \ http://security.ubuntu.com/ubuntu/pool/main/p/pulseaudio/libpulse0_0.9.10-1ubuntu1.1_i386.deb \ http://security.ubuntu.com/ubuntu/pool/main/p/pulseaudio/libpulse-dev_0.9.10-1ubuntu1.1_i386.deb # ZLib add_ubuntu_package \ http://mirrors.us.kernel.org/ubuntu//pool/main/z/zlib/zlib1g_1.2.3.3.dfsg-7ubuntu1_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/z/zlib/zlib1g-dev_1.2.3.3.dfsg-7ubuntu1_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/n/ncurses/libncurses5_5.6+20071124-1ubuntu2_i386.deb \ http://mirrors.us.kernel.org/ubuntu//pool/main/n/ncurses/libncurses5-dev_5.6+20071124-1ubuntu2_i386.deb ########################################################################### ########################################################################### ##### ##### E N D O F C O N F I G U R A T I O N ##### ########################################################################### ########################################################################### panic () { echo "ERROR: $@" exit 1 } fail_panic () { if [ $? != 0 ] ; then echo "ERROR: $@" exit 1 fi } if [ "$V" != 0 ] ; then run () { echo "## COMMAND: $@" $@ } else run () { $@ >>$TMPLOG 2>&1 } fi OLD_PATH="$PATH" OLD_LD_LIBRARY_PATH="$LD_LIBRARY_PATH" BUILD_DIR=$ROOT_DIR/build mkdir -p $BUILD_DIR TMPLOG=$BUILD_DIR/build.log rm -rf $TMPLOG && touch $TMPLOG BUILD_BINUTILS_DIR=$BUILD_DIR/binutils BUILD_GMP_DIR=$BUILD_DIR/gmp BUILD_MPFR_DIR=$BUILD_DIR/mpfr BUILD_GCC_DIR=$BUILD_DIR/gcc TIMESTAMPS_DIR=$BUILD_DIR/timestamps mkdir -p $TIMESTAMPS_DIR if [ "$V" = 0 ] ; then echo "To follow build, run: tail -F $TMPLOG" fi # returns 0 iff the string in $2 matches the pattern in $1 # $1: pattern # $2: string pattern_match () { echo "$2" | grep -q -E -e "$1" } # Find if a given shell program is available. # We need to take care of the fact that the 'which <foo>' command # may return either an empty string (Linux) or something like # "no <foo> in ..." (Darwin). Also, we need to redirect stderr # to /dev/null for Cygwin # # $1: variable name # $2: program name # # Result: set $1 to the full path of the corresponding command # or to the empty/undefined string if not available # find_program () { local PROG PROG=`which $2 2>/dev/null` if [ -n "$PROG" ] ; then if pattern_match '^no ' "$PROG"; then PROG= fi fi eval $1="$PROG" } # Copy a directory, create target location if needed # # $1: source directory # $2: target directory location # copy_directory () { local SRCDIR="$1" local DSTDIR="$2" if [ ! -d "$SRCDIR" ] ; then panic "Can't copy from non-directory: $SRCDIR" fi mkdir -p "$DSTDIR" && (cd "$SRCDIR" && tar cf - *) | (tar xf - -C "$DSTDIR") fail_panic "Cannot copy to directory: $DSTDIR" } find_program CMD_WGET wget find_program CMD_CURL curl find_program CMD_SCRP scp # Download a file with either 'curl', 'wget' or 'scp' # # $1: source URL (e.g. http://foo.com, ssh://blah, /some/path) # $2: target file download_file () { # Is this HTTP, HTTPS or FTP ? if pattern_match "^(http|https|ftp):.*" "$1"; then if [ -n "$CMD_WGET" ] ; then run $CMD_WGET -O $2 $1 elif [ -n "$CMD_CURL" ] ; then run $CMD_CURL -o $2 $1 else echo "Please install wget or curl on this machine" exit 1 fi return fi # Is this SSH ? # Accept both ssh://<path> or <machine>:<path> # if pattern_match "^(ssh|[^:]+):.*" "$1"; then if [ -n "$CMD_SCP" ] ; then scp_src=`echo $1 | sed -e s%ssh://%%g` run $CMD_SCP $scp_src $2 else echo "Please install scp on this machine" exit 1 fi return fi # Is this a file copy ? # Accept both file://<path> or /<path> # if pattern_match "^(file://|/).*" "$1"; then cp_src=`echo $1 | sed -e s%^file://%%g` run cp -f $cp_src $2 return fi # Unknown schema echo "ERROR: Unsupported source URI: $1" exit 1 } # A variant of 'download_file' used to specify the target directory # $1: source URL # $2: target directory download_file_to () { local URL="$1" local DIR="$2" local DST="$DIR/`basename $URL`" mkdir -p $DIR download_file "$URL" "$DST" } # Pack a given archive # # $1: archive file path (including extension) # $2: source directory for archive content # $3+: list of files (including patterns), all if empty pack_archive () { local ARCHIVE="$1" local SRCDIR="$2" local SRCFILES local TARFLAGS ZIPFLAGS shift; shift; if [ -z "$1" ] ; then SRCFILES="*" else SRCFILES="$@" fi if [ "`basename $ARCHIVE`" = "$ARCHIVE" ] ; then ARCHIVE="`pwd`/$ARCHIVE" fi mkdir -p `dirname $ARCHIVE` if [ "$VERBOSE2" = "yes" ] ; then TARFLAGS="vcf" ZIPFLAGS="-9r" else TARFLAGS="cf" ZIPFLAGS="-9qr" fi case "$ARCHIVE" in *.zip) (cd $SRCDIR && run zip $ZIPFLAGS "$ARCHIVE" $SRCFILES) ;; *.tar) (cd $SRCDIR && run tar $TARFLAGS "$ARCHIVE" $SRCFILES) ;; *.tar.gz) (cd $SRCDIR && run tar z$TARFLAGS "$ARCHIVE" $SRCFILES) ;; *.tar.bz2) (cd $SRCDIR && run tar j$TARFLAGS "$ARCHIVE" $SRCFILES) ;; *) panic "Unsupported archive format: $ARCHIVE" ;; esac } # Does the host compiler generate 32-bit machine code? # If not, add the -m32 flag to the compiler name to ensure this. # compute_host_flags () { HOST_CC=${CC:-gcc} HOST_CXX=${CXX-g++} echo -n "Checking for ccache..." find_program CMD_CCACHE ccache if [ -n "$CMD_CCACHE" ] ; then echo "$HOST_CC" | tr ' ' '\n' | grep -q -e "ccache" if [ $? = 0 ] ; then echo "yes (ignored)" else echo "yes" HOST_CC="ccache $HOST_CC" HOST_CXX="ccache $HOST_CXX" fi else echo "no" fi echo -n "Checking whether the compiler generates 32-bit code... " cat > $BUILD_DIR/conftest.c << EOF /* This will fail to compile if void* is not 32-bit */ int test_array[1 - 2*(sizeof(void*) != 4)]; EOF $HOST_CC -o $BUILD_DIR/conftest.o -c $BUILD_DIR/conftest.c > $BUILD_DIR/conftest.log 2>&1 if [ $? != 0 ] ; then echo "no" HOST_CC="$HOST_CC -m32" HOST_CXX="$HOST_CXX -m32" else echo "yes" fi export CC="$HOST_CC" export CXX="$HOST_CXX" } compute_host_flags # Return the value of a given named variable # $1: variable name # # example: # FOO=BAR # BAR=ZOO # echo `var_value $FOO` # will print 'ZOO' # var_value () { # find a better way to do that ? eval echo "$`echo $1`" } var_list_append () { local VARNAME=$1 local VARVAL=`var_value $VARNAME` shift if [ -z "$VARVAL" ] ; then eval $VARNAME=\"$@\" else eval $VARNAME=\"$VARVAL $@\" fi } var_list_prepend () { local VARNAME=$1 local VARVAL=`var_value $VARNAME` shift if [ -z "$VARVAL" ] ; then eval $VARNAME=\"$@\" else eval $VARNAME=\"$@ $VARVAL\" fi } _list_first () { echo $1 } _list_rest () { shift echo "$@" } var_list_pop_first () { local VARNAME=$1 local VARVAL=`var_value $VARNAME` local FIRST=`_list_first $VARVAL` eval $VARNAME=\"`_list_rest $VARVAL`\" echo "$FIRST" } _list_first () { echo $1 } _list_rest () { shift echo "$@" } var_list_first () { local VAL=`var_value $1` _list_first $VAL } var_list_rest () { local VAL=`var_value $1` _list_rest $VAL } ALL_TASKS= # Define a new task for this build script # $1: Task name (e.g. build_stuff) # $2: Task description # $3: Optional: command name (will be cmd_$1 by default) # task_define () { local TASK="$1" local DESCR="$2" local COMMAND="${3:-cmd_$1}" var_list_append ALL_TASKS $TASK task_set $TASK name "$TASK" task_set $TASK descr "$DESCR" task_set $TASK cmd "$COMMAND" task_set $TASK deps "" } task_set () { local TASK="$1" local FIELD="$2" shift; shift; eval TASK_${TASK}__${FIELD}=\"$@\" } task_get () { var_value TASK_$1__$2 } # return the list of dependencies for a given task task_get_deps () { task_get $1 deps } task_get_cmd () { task_get $1 cmd } task_get_descr () { task_get $1 descr } # $1: task name # $2+: other tasks this task depends on. task_depends () { local TASK="$1" shift; var_list_append TASK_${TASK}__deps $@ } task_dump () { local TASK for TASK in $ALL_TASKS; do local DEPS="`task_get_deps $TASK`" local CMD="`task_get_cmd $TASK`" local DESCR="`task_get_descr $TASK`" echo "TASK $TASK: $DESCR: $CMD" echo "> $DEPS" done } task_visit () { task_set $TASK visit 1 } task_unvisit () { task_set $TASK visit 0 } task_is_visited () { [ `task_get $TASK visit` = 1 ] } task_queue_reset () { TASK_QUEUE= } task_queue_push () { var_list_append TASK_QUEUE $1 } task_queue_pop () { local FIRST=`var_list_first TASK_QUEUE` TASK_QUEUE=`var_list_rest TASK_QUEUE` } do_all_tasks () { local TASK local TASK_LIST= task_queue_reset # Clear visit flags for TASK in $ALL_TASKS; do task_unvisit $TASK done task_queue_push $1 while [ -n "$TASK_QUEUE" ] ; do TASK=`task_queue_pop` if task_is_visited $TASK; then continue fi # Prepend the task to the list if its timestamp is not set if [ ! -f $TIMESTAMPS_DIR/$TASK ]; then var_list_prepend TASK_LIST $TASK fi # Add all dependencies to the work-queue local SUBTASK for SUBTASK in `task_get_deps $TASK`; do task_queue_push $SUBTASK done task_visit $TASK done # Now, TASK_LIST contains the } do_task () { local TASK="$1" local DEPS="`task_get_deps $TASK`" local DESCR="`task_get_descr $TASK`" local DEP #echo ">> $TASK: $DEPS" if [ -f "$TIMESTAMPS_DIR/$TASK" ] ; then echo "Skipping $1: already done." return 0 fi # do_task for any dependents for DEP in $DEPS; do #echo " ? $DEP" if [ ! -f "$TIMESTAMPS_DIR/$DEP" ] ; then do_task $DEP fi done echo "Running: $DESCR" if [ "$V" != 0 ] ; then eval `task_get_cmd $TASK` else eval `task_get_cmd $TASK` >> $TMPLOG 2>&1 fi if [ $? != 0 ] ; then echo "ERROR: Cannot $DESCR" exit 1 fi touch "$TIMESTAMPS_DIR/$TASK" } task_define download_toolchain_sources "Download toolchain sources from android.git.kernel.org" cmd_download_toolchain_sources () { $NDK_DOWNLOAD_TOOLCHAIN_SOURCES_SH $TOOLCHAIN_SRC_DIR } task_define download_packages "Download Ubuntu packages" cmd_download_packages () { local PACKAGE mkdir -p $DOWNLOAD_DIR && for PACKAGE in $UBUNTU_PACKAGES; do echo "Downloading $PACKAGE" download_file_to $PACKAGE $DOWNLOAD_DIR done } task_define build_sysroot "Build sysroot" task_depends build_sysroot download_packages cmd_build_sysroot () { local PACKAGE for PACKAGE in $UBUNTU_PACKAGES; do local SRC_PKG=$DOWNLOAD_DIR/`basename $PACKAGE` echo "Extracting $SRC_PKG" dpkg -x $SRC_PKG $ORG_SYSROOT_DIR/ done } # Now, we need to patch libc.so which is actually a linker script # referencing /lib and /usr/lib. Do the same for libpthread.so patch_library () { echo "Patching $1" sed -i -e "s! /lib/! !g" -e "s! /usr/lib/! !g" $1 } task_define copy_sysroot "Fix and copy sysroot" task_depends copy_sysroot build_sysroot cmd_copy_sysroot () { local SL # Copy the content of $BUILD_DIR/lib to $SYSROOT_DIR/usr/lib copy_directory $ORG_SYSROOT_DIR/lib $SYSROOT_DIR/usr/lib copy_directory $ORG_SYSROOT_DIR/usr/lib $SYSROOT_DIR/usr/lib copy_directory $ORG_SYSROOT_DIR/usr/include $SYSROOT_DIR/usr/include # We need to fix the symlink like librt.so -> /lib/librt.so.1 # in $SYSROOT_DIR/usr/lib, they should point to librt.so.1 instead now. SYMLINKS=`ls -l $SYSROOT_DIR/usr/lib | grep /lib/ | awk '{ print $11; }'` cd $SYSROOT_DIR/usr/lib for SL in $SYMLINKS; do # convert /lib/libfoo.so.<n> into 'libfoo.so.<n>' for the target local DST=`echo $SL | sed -e 's!^/lib/!!g'` # convery libfoo.so.<n> into libfoo.so for the source local SRC=`echo $DST | sed -e 's!\.[0-9]*$!!g'` echo "Fixing symlink $SRC --> $DST" ln -sf $DST $SRC done patch_library $SYSROOT_DIR/usr/lib/libc.so patch_library $SYSROOT_DIR/usr/lib/libpthread.so } task_define configure_binutils "Configure binutils-$BINUTILS_VERSION" task_depends configure_binutils download_toolchain_sources copy_sysroot cmd_configure_binutils () { OUT_DIR=$BUILD_BINUTILS_DIR mkdir -p $OUT_DIR && cd $OUT_DIR && $TOOLCHAIN_SRC_DIR/binutils/binutils-$BINUTILS_VERSION/configure \ --prefix=$INSTALL_DIR \ --with-sysroot=$SYSROOT_DIR \ --target=$GCC_TARGET } task_define build_binutils "Build binutils-$BINUTILS_VERSION" task_depends build_binutils configure_binutils cmd_build_binutils () { cd $BUILD_BINUTILS_DIR && make $MAKE_FLAGS } task_define install_binutils "Install binutils-$BINUTILS_VERSION" task_depends install_binutils build_binutils cmd_install_binutils () { cd $BUILD_BINUTILS_DIR && make install } task_define extract_gmp "Extract sources for gmp-$GMP_VERSION" task_depends extract_gmp download_toolchain_sources cmd_extract_gmp () { OUT_DIR=$BUILD_GMP_DIR mkdir -p $OUT_DIR && cd $OUT_DIR && tar xjf $TOOLCHAIN_SRC_DIR/gmp/gmp-$GMP_VERSION.tar.bz2 } task_define configure_gmp "Configure gmp-$GMP_VERSION" task_depends configure_gmp extract_gmp install_binutils cmd_configure_gmp () { export ABI=32 && cd $BUILD_GMP_DIR && mkdir -p build && cd build && ../gmp-$GMP_VERSION/configure --prefix=$INSTALL_DIR --host=$GMP_TARGET --disable-shared } task_define build_gmp "Build gmp-$GMP_VERSION" task_depends build_gmp configure_gmp cmd_build_gmp () { export ABI=32 && cd $BUILD_GMP_DIR/build && make $MAKE_FLAGS } task_define install_gmp "Install gmp-$GMP_VERSION" task_depends install_gmp build_gmp cmd_install_gmp () { cd $BUILD_GMP_DIR/build && make install } # Third, build mpfr task_define extract_mpfr "Extract sources from mpfr-$MPFR_VERSION" task_depends extract_mpfr download_toolchain_sources cmd_extract_mpfr () { OUT_DIR=$BUILD_MPFR_DIR mkdir -p $OUT_DIR && cd $OUT_DIR && tar xjf $TOOLCHAIN_SRC_DIR/mpfr/mpfr-$MPFR_VERSION.tar.bz2 } task_define configure_mpfr "Configure mpfr-$MPFR_VERSION" task_depends configure_mpfr extract_mpfr install_gmp cmd_configure_mpfr () { cd $BUILD_MPFR_DIR && mkdir -p build && cd build && ../mpfr-$MPFR_VERSION/configure \ --prefix=$INSTALL_DIR \ --host=$GMP_TARGET \ --with-gmp=$INSTALL_DIR \ --with-sysroot=$SYSROOT_DIR \ --disable-shared } task_define build_mpfr "Build mpfr-$MPFR_VERSION" task_depends build_mpfr configure_mpfr cmd_build_mpfr () { cd $BUILD_MPFR_DIR/build && make $MAKE_FLAGS } task_define install_mpfr "Install mpfr-$MPFR_VERSION" task_depends install_mpfr build_mpfr cmd_install_mpfr () { cd $BUILD_MPFR_DIR/build && make install } # Fourth, the compiler itself task_define configure_gcc "Configure gcc-$GCC_VERSION" task_depends configure_gcc download_toolchain_sources install_binutils install_gmp install_mpfr cmd_configure_gcc () { OUT_DIR=$BUILD_GCC_DIR mkdir -p $OUT_DIR && cd $OUT_DIR && export PATH=$INSTALL_DIR/bin:$OLD_PATH && export CFLAGS="-m32" && export CC_FOR_TARGET="$HOST_CC" && export LD_LIBRARY_PATH=$INSTALL_DIR/lib:$OLD_LD_LIBRARY_PATH && export LDFLAGS="-L$INSTALL_DIR/lib" && $TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION/configure \ --prefix=$INSTALL_DIR \ --with-sysroot=$SYSROOT_DIR \ --disable-nls \ --with-gmp=$INSTALL_DIR \ --with-mpfr=$INSTALL_DIR \ --target=$GCC_TARGET \ --disable-plugin \ --enable-languages=c,c++ } task_define build_gcc "Build gcc-$GCC_VERSION" task_depends build_gcc configure_gcc cmd_build_gcc () { export PATH=$INSTALL_DIR/bin:$OLD_PATH && export LD_LIBRARY_PATH=$INSTALL_DIR/lib:$OLD_LD_LIBRARY_PATH && cd $BUILD_GCC_DIR && make $MAKE_FLAGS } task_define install_gcc "Install gcc-$GCC_VERSION" task_depends install_gcc build_gcc cmd_install_gcc () { export PATH=$INSTALL_DIR/bin:$OLD_PATH && export LD_LIBRARY_PATH=$INSTALL_DIR/lib:$OLD_LD_LIBRARY_PATH && cd $BUILD_GCC_DIR && make install } task_define cleanup_toolchain "Cleanup toolchain" task_depends cleanup_toolchain install_gcc cmd_cleanup_toolchain () { # Remove un-needed directories and files rm -rf $INSTALL_DIR/share rm -rf $INSTALL_DIR/man rm -rf $INSTALL_DIR/info rm -rf $INSTALL_DIR/lib32 rm -rf $INSTALL_DIR/libexec/*/*/install-tools (strip $INSTALL_DIR/bin/*) true } task_define package_toolchain "Package final toolchain" task_depends package_toolchain cleanup_toolchain cmd_package_toolchain () { pack_archive $TOOLCHAIN_ARCHIVE "`dirname $INSTALL_DIR`" "`basename $INSTALL_DIR`" } #do_task package_toolchain do_task package_toolchain echo "Done, see $TOOLCHAIN_ARCHIVE"