| #!/bin/sh |
| |
| # Copyright 2014 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. |
| |
| . $(dirname "$0")/common.shi |
| shell_import build-defaults.shi |
| |
| OPT_AOSP_DIR= |
| OPT_BINPREFIX= |
| OPT_CCACHE= |
| OPT_HELP= |
| OPT_HOST= |
| OPT_NO_CCACHE= |
| OPT_PREFIX= |
| |
| for OPT; do |
| OPTARG=$(expr "x$OPT" : "x[^=]*=\\(.*\\)" || true) |
| case $OPT in |
| --aosp-dir=*) |
| OPT_AOSP_DIR=$OPTARG |
| ;; |
| --binprefix=*) |
| OPT_BINPREFIX=$OPTARG |
| ;; |
| --ccache=*) |
| OPT_CCACHE=$OPTARG |
| ;; |
| --help|-?) |
| OPT_HELP=true |
| ;; |
| --host=*) |
| OPT_HOST=$OPTARG |
| ;; |
| --no-ccache) |
| OPT_NO_CCACHE=true |
| ;; |
| --prefix=*) |
| OPT_PREFIX=$OPTARG |
| ;; |
| --quiet) |
| decrement_verbosity |
| ;; |
| --verbose) |
| increment_verbosity |
| ;; |
| -*) |
| panic "Unknown option '$OPT', see --help." |
| ;; |
| *) |
| PARAM_COUNT=$(( $PARAM_COUNT + 1)) |
| var_assign PARAM_${PARAM_COUNT} "$OPT" |
| ;; |
| esac |
| done |
| |
| if [ "$OPT_HELP" ]; then |
| cat <<EOF |
| Usage: $(program_name) [options] <install-dir> |
| |
| Generate a special toolchain wrapper that can be used to build binaries to be |
| included with the Android SDK. These binaries are guaranteed to run on systems |
| older than the build machine. |
| |
| This is achieved by using the prebuilt toolchains found under: |
| |
| \$AOSP/prebuilts/gcc/<system>/host/ |
| |
| Where \$AOSP is the path to an AOSP checkout, and <system> corresponds to the |
| host system this script runs on (i.e. linux-x86 or darwin-x86). |
| |
| If you have the 'ccache' program installed, the wrapper will use it |
| automatically unless you use the --no-ccache option. |
| |
| The script will put under <install-dir>/bin/ various |
| |
| Valid options: |
| --help|-? Print this message. |
| --verbose Increase verbosity. |
| --quiet Decrease verbosity. |
| --aosp-dir=<path> Path to root AOSP checkout. |
| --binprefix=<prefix> Specify toolchain binprefix [autodetected]. |
| --host=<system> Host system to support. |
| --prefix=<prefix> Specify extra include/lib prefix. |
| --ccache=<program> Use specific ccache binary [autodetected]. |
| --no-ccache Don't try to probe and use ccache. |
| |
| EOF |
| exit 0 |
| fi |
| |
| if [ "$PARAM_COUNT" != 1 ]; then |
| panic "This script requires a single parameter! See --help." |
| fi |
| |
| INSTALL_DIR=$PARAM_1 |
| |
| # Save original PATH for later. |
| ORIGINAL_PATH=$PATH |
| |
| # Determine host system type. |
| BUILD_HOST=$(get_build_os) |
| BUILD_ARCH=$(get_build_arch) |
| BUILD_HOST_TAG=${BUILD_HOST}-${BUILD_ARCH} |
| log "Found current build machine: $BUILD_HOST_TAG" |
| |
| # Handle CCACHE related arguments. |
| CCACHE= |
| if [ "$OPT_CCACHE" ]; then |
| if [ "$OPT_NO_CCACHE" ]; then |
| panic "You cannot use both --ccache=<program> and --no-ccache at the same time." |
| fi |
| CCACHE=$(which "$OPT_CCACHE" 2>/dev/null) |
| if [ -z "$CCACHE" ]; then |
| panic "Missing ccache program: $OPT_CCACHE" |
| fi |
| elif [ -z "$OPT_NO_CCACHE" ]; then |
| CCACHE=$(which ccache 2>/dev/null) |
| if [ "$CCACHE" ]; then |
| log "Auto-config: --ccache=$CCACHE" |
| fi |
| fi |
| |
| # Handle --aosp-dir option. |
| if [ "$OPT_AOSP_DIR" ]; then |
| if [ ! -d "$OPT_AOSP_DIR" ]; then |
| panic "Not a directory: $OPT_AOSP_DIR" |
| fi |
| AOSP_DIR=$OPT_AOSP_DIR |
| else # !OPT_AOSP_DIR |
| panic "Please use --aosp-dir=<path> to set the path to the root AOSP checkout." |
| fi |
| AOSP_PREBUILTS_GCC_DIR=$AOSP_DIR/prebuilts/gcc |
| if [ ! -d "$AOSP_PREBUILTS_GCC_DIR" ]; then |
| panic "Missing directory: $AOSP_PREBUILTS_GCC_DIR" |
| fi |
| |
| # Handle --host option. |
| if [ "$OPT_HOST" ]; then |
| case $OPT_HOST in |
| linux-*|darwin-*|windows-*) |
| ;; |
| *) |
| panic "Invalid --host value: $OPT_HOST" |
| ;; |
| esac |
| case $OPT_HOST in |
| *-x86|*-x86_64) |
| ;; |
| *) |
| panic "Invalid --host value: $OPT_HOST" |
| ;; |
| esac |
| HOST=$OPT_HOST |
| else |
| HOST=$BUILD_HOST_TAG |
| log "Auto-config: --host=$HOST" |
| fi |
| |
| # Handle --binprefix option. |
| BINPREFIX= |
| if [ "$OPT_BINPREFIX" ]; then |
| # Allow a final - after the binprefix |
| BINPREFIX=${OPT_BINPREFIX%%-} |
| if [ "$BINPREFIX" ]; then |
| BINPREFIX=${BINPREFIX}- |
| fi |
| fi |
| |
| # Generate a small toolchain wrapper program |
| # |
| # $1: program name, without any prefix (e.g. gcc, g++, ar, etc..) |
| # $2: source prefix (e.g. 'i586-mingw32msvc-') |
| # $3: destination prefix (e.g. 'i586-px-mingw32msvc-') |
| # $4: destination directory for the generated program |
| # |
| # You may also define the following variables to pass extra tool flags: |
| # |
| # EXTRA_CFLAGS |
| # EXTRA_CXXFLAGS |
| # EXTRA_LDFLAGS |
| # EXTRA_ARFLAGS |
| # EXTRA_ASFLAGS |
| # EXTRA_WINDRESFLAGS |
| # |
| # As well as a special variable containing commands to setup the |
| # environment before tool invokation: |
| # |
| # EXTRA_ENV_SETUP |
| # |
| gen_wrapper_program () |
| { |
| local PROG="$1" |
| local SRC_PREFIX="$2" |
| local DST_PREFIX="$3" |
| local DST_FILE="$4/${SRC_PREFIX}$PROG" |
| local FLAGS="" |
| local LDFLAGS="" |
| |
| case $PROG in |
| cc|gcc|cpp) |
| FLAGS=$FLAGS" $EXTRA_CFLAGS" |
| ;; |
| c++|g++) |
| FLAGS=$FLAGS" $EXTRA_CXXFLAGS" |
| ;; |
| ar) FLAGS=$FLAGS" $EXTRA_ARFLAGS";; |
| as) FLAGS=$FLAGS" $EXTRA_ASFLAGS";; |
| ld|ld.bfd|ld.gold) FLAGS=$FLAGS" $EXTRA_LDFLAGS";; |
| windres) FLAGS=$FLAGS" $EXTRA_WINDRESFLAGS";; |
| esac |
| |
| if [ "$CCACHE" ]; then |
| DST_PREFIX="$CCACHE $DST_PREFIX" |
| fi |
| |
| cat > "$DST_FILE" << EOF |
| #!/bin/sh |
| # Auto-generated by $(program_name), DO NOT EDIT!! |
| |
| # Environment setup |
| $EXTRA_ENV_SETUP |
| |
| # Tool invokation. |
| ${DST_PREFIX}$PROG $FLAGS "\$@" $LDFLAGS |
| EOF |
| chmod +x "$DST_FILE" |
| log " Generating: ${SRC_PREFIX}$PROG" |
| } |
| |
| # $1: source prefix |
| # $2: destination prefix |
| # $3: destination directory. |
| gen_wrapper_toolchain () { |
| local SRC_PREFIX="$1" |
| local DST_PREFIX="$2" |
| local DST_DIR="$3" |
| local PROG |
| local PROGRAMS="cc gcc c++ g++ cpp as ld ar ranlib strip strings nm objdump objcopy dlltool" |
| |
| log "Generating toolchain wrappers in: $DST_DIR" |
| run mkdir -p "$DST_DIR" |
| |
| if [ -n "$SRC_PREFIX" ]; then |
| SRC_PREFIX=${SRC_PREFIX%%-}- |
| fi |
| |
| case $SRC_PREFIX in |
| *mingw*) |
| PROGRAMS="$PROGRAMS windres" |
| case $CURRENT_HOST in |
| windows-x86) |
| EXTRA_WINDRESFLAGS="--target=pe-i386" |
| ;; |
| esac |
| ;; |
| esac |
| |
| if [ "$CCACHE" ]; then |
| # If this is clang, disable ccache-induced warnings and |
| # restore colored diagnostics. |
| # http://petereisentraut.blogspot.fr/2011/05/ccache-and-clang.html |
| if (${DST_PREFIX}gcc --version 2>/dev/null | grep -q clang); then |
| EXTRA_CLANG_FLAGS="-Qunused-arguments -fcolor-diagnostics" |
| EXTRA_CFLAGS="$EXTRA_CFLAGS $EXTRA_CLANG_FLAGS" |
| EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $EXTRA_CLANG_FLAGS" |
| fi |
| fi |
| |
| for PROG in $PROGRAMS; do |
| gen_wrapper_program $PROG "$SRC_PREFIX" "$DST_PREFIX" "$DST_DIR" |
| done |
| |
| EXTRA_CFLAGS= |
| EXTRA_CXXFLAGS= |
| EXTRA_LDFLAGS= |
| EXTRA_ARFLAGS= |
| EXTRA_ASFLAGS= |
| EXTRA_WINDRESFLAGS= |
| EXTRA_ENV_SETUP= |
| } |
| |
| # Prepare the build for a given host system. |
| # $1: Host system tag (e.g. linux-x86_64) |
| prepare_build_for_host () { |
| local CURRENT_HOST=$1 |
| |
| CURRENT_TEXT="[$CURRENT_HOST]" |
| |
| PREBUILT_TOOLCHAIN_DIR= |
| TOOLCHAIN_PREFIX= |
| EXTRA_ENV_SETUP= |
| case $CURRENT_HOST in |
| linux-*) |
| PREBUILT_TOOLCHAIN_DIR=$AOSP_PREBUILTS_GCC_DIR/linux-x86/host/x86_64-linux-glibc2.11-4.8 |
| TOOLCHAIN_PREFIX=x86_64-linux- |
| ;; |
| windows-*) |
| PREBUILT_TOOLCHAIN_DIR=$AOSP_PREBUILTS_GCC_DIR/linux-x86/host/x86_64-w64-mingw32-4.8 |
| TOOLCHAIN_PREFIX=x86_64-w64-mingw32- |
| ;; |
| darwin-*) |
| # Use host GCC for now. |
| PREBUILT_TOOLCHAIN_DIR= |
| TOOLCHAIN_PREFIX= |
| # Ensure we use the 10.8 SDK or else. |
| OSX_VERSION=$(sw_vers -productVersion) |
| OSX_SDK_SUPPORTED="10.6 10.7 10.8" |
| OSX_SDK_INSTALLED_LIST=$(xcodebuild -showsdks 2>/dev/null | grep macosx | sed -e "s/.*macosx//g" | sort -n | tr '\n' ' ') |
| if [ -z "$OSX_SDK_INSTALLED_LIST" ]; then |
| panic "Please install XCode on this machine!" |
| fi |
| log "OSX: Installed SDKs: $OSX_SDK_INSTALLED_LIST" |
| |
| OSX_SDK_VERSION=$(echo "$OSX_SDK_INSTALLED_LIST" | tr ' ' '\n' | head -1) |
| log "OSX: Using SDK version $OSX_SDK_VERSION" |
| |
| XCODE_PATH=$(xcode-select -print-path 2>/dev/null) |
| log "OSX: XCode path: $XCODE_PATH" |
| |
| OSX_SDK_ROOT=$XCODE_PATH/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk |
| log "OSX: Looking for $OSX_SDK_ROOT" |
| if [ ! -d "$OSX_SDK_ROOT" ]; then |
| OSX_SDK_ROOT=/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk |
| log "OSX: Looking for $OSX_SDK_ROOT" |
| if [ ! -d "$OSX_SDK_ROOT" ]; then |
| panic "Could not find SDK $OSX_SDK_VERSION at $OSX_SDK_ROOT" |
| fi |
| fi |
| log "OSX: Using SDK at $OSX_SDK_ROOT" |
| EXTRA_ENV_SETUP="export SDKROOT=$OSX_SDK_ROOT" |
| ;; |
| *) |
| panic "Host system '$CURRENT_HOST' is not supported by this script!" |
| ;; |
| esac |
| |
| if [ -z "$OPT_BINPREFIX" ]; then |
| BINPREFIX=$TOOLCHAIN_PREFIX |
| fi |
| |
| case $CURRENT_HOST in |
| linux-x86_64) |
| GNU_CONFIG_HOST=x86_64-linux |
| ;; |
| linux-x86) |
| GNU_CONFIG_HOST=i686-linux |
| ;; |
| windows-x86) |
| GNU_CONFIG_HOST=i686-w64-mingw32 |
| ;; |
| windows-x86_64) |
| GNU_CONFIG_HOST=x86_64-w64-mingw32 |
| ;; |
| darwin-*) |
| # Use host compiler. |
| GNU_CONFIG_HOST= |
| ;; |
| *) |
| panic "Host system '$CURRENT_HOST' is not supported by this script!" |
| ;; |
| esac |
| |
| if [ "$OPT_BINPREFIX" ]; then |
| BINPREFIX=${OPT_BINPREFIX%%-} |
| else |
| BINPREFIX=$GNU_CONFIG_HOST |
| fi |
| |
| case $CURRENT_HOST in |
| *-x86) |
| EXTRA_CFLAGS="-m32" |
| EXTRA_CXXFLAGS="-m32" |
| EXTRA_LDFLAGS="-m32" |
| ;; |
| *-x86_64) |
| EXTRA_CFLAGS="-m64" |
| EXTRA_CXXFLAGS="-m64" |
| EXTRA_LDFLAGS="-m64" |
| ;; |
| *) |
| panic "Host system '$CURRENT_HOST' is not supported by this script!" |
| ;; |
| esac |
| |
| CROSS_PREFIX=${GNU_CONFIG_HOST}- |
| |
| PATH=$ORIGINAL_PATH |
| |
| if [ "$OPT_PREFIX" ]; then |
| EXTRA_CFLAGS="$EXTRA_CFLAGS -I$OPT_PREFIX/include" |
| EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -I$OPT_PREFIX/include" |
| EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L$OPT_PREFIX/lib" |
| fi |
| |
| if [ "$BINPREFIX" ]; then |
| log "$CURRENT_TEXT Generating ${BINPREFIX%%-} wrapper toolchain in $INSTALL_DIR" |
| else |
| log "$CURRENT_TEXT Generating host wrapper toolchain in $INSTALL_DIR" |
| fi |
| gen_wrapper_toolchain "$BINPREFIX" "$PREBUILT_TOOLCHAIN_DIR/bin/$TOOLCHAIN_PREFIX" "$INSTALL_DIR" |
| } |
| |
| prepare_build_for_host $HOST |