#!/bin/sh
#
# Copyright (C) 2011 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.
#
# Rebuild all host toolchains and programs
#
PROGDIR=$(dirname $0)
. $PROGDIR/prebuilt-common.sh
NDK_DIR=$ANDROID_NDK_ROOT
register_var_option "--ndk-dir=<path>" NDK_DIR "NDK installation directory"
SYSTEMS=$HOST_TAG
# Replace x86_64 by x86 at the end of SYSTEMS since we will produce
# 32-bit toolchains by default, i.e. unless you use the --try-64 flag
if [ "${SYSTEMS%%x86_64}" != "$SYSTEMS" ]; then
SYSTEMS=${SYSTEMS%%x86_64}x86
fi
# If we are on Linux, we are able to generate the Windows binaries
# with the mingw32 cross-toolchain.
if [ "$SYSTEMS" = "linux-x86" ]; then
SYSTEMS=$SYSTEMS",windows"
fi
CUSTOM_SYSTEMS=
register_option "--systems=<names>" do_SYSTEMS "List of host systems to build for"
do_SYSTEMS () { CUSTOM_SYSTEMS=true; SYSTEMS=$1; }
ARCHS=$DEFAULT_ARCHS
register_var_option "--arch=<list>" ARCHS "List of target archs to build for"
PACKAGE_DIR=
register_var_option "--package-dir=<path>" PACKAGE_DIR "Package toolchain into this directory"
DARWIN_SSH=
register_var_option "--darwin-ssh=<hostname>" DARWIN_SSH "Generate darwin packages on remote host"
NO_GEN_PLATFORMS=
register_var_option "--no-gen-platforms" NO_GEN_PLATFORMS "Don't generate platforms/ directory, use existing one"
register_try64_option
PROGRAM_PARAMETERS="<toolchain-src-dir>"
PROGRAM_DESCRIPTION=\
"This script can be used to rebuild all the host NDK toolchains at once.
You need to give it the path to the toolchain source directory, as
downloaded by the 'download-toolchain-sources.sh' dev-script."
extract_parameters "$@"
# Check toolchain source path
SRC_DIR="$PARAMETERS"
if [ -z "$SRC_DIR" ]; then
echo "ERROR: Please provide the path to the toolchain source tree. See --help"
exit 1
fi
if [ ! -d "$SRC_DIR" ]; then
echo "ERROR: Not a directory: '$SRC_DIR'"
exit 1
fi
if [ ! -f "$SRC_DIR/build/configure" -o ! -d "$SRC_DIR/gcc/gcc-$DEFAULT_GCC_VERSION" ]; then
echo "ERROR: The file $SRC_DIR/build/configure or"
echo " the directory $SRC_DIR/gcc/gcc-$DEFAULT_GCC_VERSION does not exist"
echo "This is not the top of a toolchain tree: $SRC_DIR"
echo "You must give the path to a copy of the toolchain source directories"
echo "created by 'download-toolchain-sources.sh."
exit 1
fi
# Now we can do the build
BUILDTOOLS=$ANDROID_NDK_ROOT/build/tools
if [ -z "$NO_GEN_PLATFORMS" ]; then
echo "Preparing the build..."
run $BUILDTOOLS/gen-platforms.sh --minimal --dst-dir=$NDK_DIR --ndk-dir=$NDK_DIR --arch=$(spaces_to_commas $ARCHS)
fail_panic "Could not generate minimal sysroot!"
else
if [ ! -d "$NDK_DIR/platforms" ]; then
echo "ERROR: --no-gen-platforms used but directory missing: $NDK_DIR/platforms"
exit 1
fi
fi
SYSTEMS=$(commas_to_spaces $SYSTEMS)
ARCHS=$(commas_to_spaces $ARCHS)
if [ "$DARWIN_SSH" -a -z "$CUSTOM_SYSTEMS" ]; then
SYSTEMS=" darwin-x86"
fi
FLAGS=
if [ "$VERBOSE" = "yes" ]; then
FLAGS=$FLAGS" --verbose"
fi
if [ "$VERBOSE2" = "yes" ]; then
FLAGS=$FLAGS" --verbose"
fi
if [ "$TRY64" = "yes" ]; then
FLAGS=$FLAGS" --try64"
else
force_32bit_binaries
fi
if [ "$PACKAGE_DIR" ]; then
mkdir -p "$PACKAGE_DIR"
fail_panic "Could not create package directory: $PACKAGE_DIR"
FLAGS=$FLAGS" --package-dir=$PACKAGE_DIR"
fi
do_remote_host_build ()
{
local SYSTEM="$1"
local ARCH="$2"
local REMOTE_HOST="$3"
# 1/ Copy the NDK toolchain build scripts
# 2/ Copy the toolchain sources/package
# 3/ Ssh to unpack the build scripts, and run them
# 4/ Copy back the generated prebuilt binaries
#
dump "Preparing remote build on $REMOTE_HOST..."
# First try to create a remote temp directory on the remote host
# Do it first so we can fail fast, not after spending time preparing
# large tarballs.
dump "Creating remote temp directory"
TMPREMOTE=/tmp/ndk-$USER/darwin-prebuild
run ssh $REMOTE_HOST "mkdir -p $TMPREMOTE && rm -rf $TMPREMOTE/*"
fail_panic "Could not create temporary build directory on $REMOTE_HOST"
# Now, package all the stuff we're going to send in a temporary
# directory here on the machine, except toolchain sources
TMPDARWIN=$NDK_TMPDIR/darwin # Where we're going to package stuff
log "Using temporary work directory: $TMPDARWIN"
mkdir -p "$TMPDARWIN"
dump "Prepare NDK build scripts"
copy_directory "$ANDROID_NDK_ROOT/build" "$TMPDARWIN/ndk/build"
copy_file_list "$ANDROID_NDK_ROOT" "$TMPDARWIN/ndk" sources/android/libthread_db
copy_file_list "$ANDROID_NDK_ROOT" "$TMPDARWIN/ndk" "$STLPORT_SUBDIR"
copy_file_list "$ANDROID_NDK_ROOT" "$TMPDARWIN/ndk" "$GABIXX_SUBDIR"
copy_file_list "$ANDROID_NDK_ROOT" "$TMPDARWIN/ndk" sources/host-tools
dump "Prepare platforms files"
copy_directory "$NDK_DIR/platforms" "$TMPDARWIN/ndk/platforms"
dump "Copying NDK build scripts and platform files to remote..."
(cd "$TMPDARWIN" && tar czf - ndk) | (ssh $REMOTE_HOST tar xzf - -C $TMPREMOTE)
fail_panic "Could not copy!"
rm -rf $TMPDARWIN
# Copy the toolchain sources
dump "Copy toolchain sources to remote"
ssh $REMOTE_HOST mkdir -p $TMPREMOTE/toolchain &&
(cd "$SRC_DIR" && tar czf - .) | (ssh $REMOTE_HOST tar xzf - -C $TMPREMOTE/toolchain)
fail_panic "Could not copy toolchain!"
# Time to run the show :-)
for ARCH in $(commas_to_spaces $ARCHS); do
dump "Running remote $ARCH toolchain build..."
SYSROOT=$TMPREMOTE/ndk/platforms/android-$(get_default_api_level_for_arch $ARCH)/arch-$ARCH
run ssh $REMOTE_HOST "$TMPREMOTE/ndk/build/tools/build-host-prebuilts.sh $TMPREMOTE/toolchain --package-dir=$TMPREMOTE/packages --arch=$ARCH --ndk-dir=$TMPREMOTE/ndk --no-gen-platforms"
fail_panic "Could not build prebuilt $ARCH toolchain on Darwin!"
done
# Get the results
dump "Copying back Darwin prebuilt packages..."
mkdir -p $TMPDARWIN/packages && rm -rf $TMPDARWIN/packages/*
run scp $REMOTE_HOST:$TMPREMOTE/packages/*-darwin-* $TMPDARWIN/packages
fail_panic "Could not grab Darwin packages!"
for PACK in $TMPDARWIN/packages/*; do
if [ "$PACKAGE_DIR" ]; then
echo "Copying $(basename $PACK) to $PACKAGE_DIR..."
cp $PACK $PACKAGE_DIR/
else
echo "Unpacking $(basename $PACK) into $NDK_DIR..."
unpack_archive $PACK $NDK_DIR
fi
fail_panic ""
done
dump "Cleaning up remote machine..."
run ssh $REMOTE_HOST rm -rf $TMPREMOTE
}
for SYSTEM in $SYSTEMS; do
# First, build the toolchains
TOOLCHAIN_FLAGS=$FLAGS
if [ "$HOST_TAG" = "linux-x86" -a "$SYSTEM" = "windows" ]; then
TOOLCHAIN_FLAGS=$TOOLCHAIN_FLAGS" --mingw"
fi
# Should we do a remote build?
if [ "$SYSTEM" != "$HOST_TAG" ]; then
case $SYSTEM in
darwin-*)
if [ "$DARWIN_SSH" ]; then
do_remote_host_build "$SYSTEM" "$ARCH" "$DARWIN_SSH"
else
echo "WARNING: Can't build $SYSTEM binaries on this system!"
echo "Consider using the --darwin-ssh option."
fi
continue
esac
fi
# First, ndk-stack
echo "Building $SYSTEM ndk-stack"
run $BUILDTOOLS/build-ndk-stack.sh $TOOLCHAIN_FLAGS
fail_panic "ndk-stack build failure!"
echo "Building $SYSTEM ndk-make"
run $BUILDTOOLS/build-host-make.sh $TOOLCHAIN_FLAGS
fail_panic "make build failure!"
echo "Building $SYSTEM ndk-awk"
run $BUILDTOOLS/build-host-awk.sh $TOOLCHAIN_FLAGS
fail_panic "awk build failure!"
echo "Building $SYSTEM ndk-sed"
run $BUILDTOOLS/build-host-sed.sh $TOOLCHAIN_FLAGS
fail_panic "sed build failure!"
if [ "$SYSTEM" = "windows" ]; then
run $BUILDTOOLS/build-host-toolbox.sh $FLAGS
fail_panic "Windows toolbox build failure!"
fi
# Then the toolchains
for ARCH in $ARCHS; do
TOOLCHAIN_NAMES=$(get_toolchain_name_list_for_arch $ARCH)
if [ -z "$TOOLCHAIN_NAMES" ]; then
echo "ERROR: Invalid architecture name: $ARCH"
exit 1
fi
for TOOLCHAIN_NAME in $TOOLCHAIN_NAMES; do
echo "Building $SYSTEM toolchain for $ARCH architecture: $TOOLCHAIN_NAME"
run $BUILDTOOLS/build-gcc.sh "$SRC_DIR" "$NDK_DIR" $TOOLCHAIN_NAME $TOOLCHAIN_FLAGS
fail_panic "Could not build $TOOLCHAIN_NAME-$SYSTEM!"
done
done
# We're done for this system
done
if [ "$PACKAGE_DIR" ]; then
echo "Done, please look at $PACKAGE_DIR"
else
echo "Done"
fi
exit 0