Home | History | Annotate | Download | only in tools
      1 # Copyright (C) 2010 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 #
     15 
     16 # Create a standalone toolchain package for Android.
     17 
     18 . `dirname $0`/prebuilt-common.sh
     19 
     20 PROGRAM_PARAMETERS=""
     21 PROGRAM_DESCRIPTION=\
     22 "Generate a customized Android toolchain installation that includes
     23 a working sysroot. The result is something that can more easily be
     24 used as a standalone cross-compiler, e.g. to run configure and
     25 make scripts."
     26 
     27 # For now, this is the only toolchain that works reliably.
     28 TOOLCHAIN_NAME=
     29 register_var_option "--toolchain=<name>" TOOLCHAIN_NAME "Specify toolchain name"
     30 
     31 LLVM_VERSION=
     32 register_var_option "--llvm-version=<ver>" LLVM_VERSION "Specify LLVM version"
     33 
     34 STL=gnustl
     35 register_var_option "--stl=<name>" STL "Specify C++ STL"
     36 
     37 ARCH=
     38 register_var_option "--arch=<name>" ARCH "Specify target architecture"
     39 
     40 # Grab the ABIs that match the architecture.
     41 ABIS=
     42 register_var_option "--abis=<list>" ABIS "Specify list of target ABIs."
     43 
     44 NDK_DIR=`dirname $0`
     45 NDK_DIR=`dirname $NDK_DIR`
     46 NDK_DIR=`dirname $NDK_DIR`
     47 register_var_option "--ndk-dir=<path>" NDK_DIR "Take source files from NDK at <path>"
     48 
     49 if [ -d "$NDK_DIR/prebuilt/$HOST_TAG" ]; then
     50   SYSTEM=$HOST_TAG
     51 else
     52   SYSTEM=$HOST_TAG32
     53 fi
     54 register_var_option "--system=<name>" SYSTEM "Specify host system"
     55 
     56 PACKAGE_DIR=/tmp/ndk-$USER
     57 register_var_option "--package-dir=<path>" PACKAGE_DIR "Place package file in <path>"
     58 
     59 INSTALL_DIR=
     60 register_var_option "--install-dir=<path>" INSTALL_DIR "Don't create package, install files to <path> instead."
     61 
     62 PLATFORM=
     63 register_option "--platform=<name>" do_platform "Specify target Android platform/API level." "android-3"
     64 do_platform () { PLATFORM=$1; }
     65 
     66 extract_parameters "$@"
     67 
     68 # Check NDK_DIR
     69 if [ ! -d "$NDK_DIR/build/core" ] ; then
     70     echo "Invalid source NDK directory: $NDK_DIR"
     71     echo "Please use --ndk-dir=<path> to specify the path of an installed NDK."
     72     exit 1
     73 fi
     74 
     75 # Check ARCH
     76 if [ -z "$ARCH" ]; then
     77     case $TOOLCHAIN_NAME in
     78         arm-*)
     79             ARCH=arm
     80             ;;
     81         x86-*)
     82             ARCH=x86
     83             ;;
     84         mipsel-*)
     85             ARCH=mips
     86             ;;
     87         aarch64-*)
     88             ARCH=arm64
     89             ;;
     90         x86_64-linux-android-*)
     91             ARCH=x86_64
     92             TOOLCHAIN_NAME=$(echo "$TOOLCHAIN_NAME" | sed -e 's/-linux-android//')
     93             echo "Auto-truncate: --toolchain=$TOOLCHAIN_NAME"
     94             ;;
     95         x86_64-*)
     96             ARCH=x86_64
     97             ;;
     98         mips64el-*)
     99             ARCH=mips64
    100             ;;
    101         *)
    102             ARCH=arm
    103             ;;
    104     esac
    105     ARCH_INC=$ARCH
    106     log "Auto-config: --arch=$ARCH"
    107 else
    108     ARCH_INC=$ARCH
    109     case $ARCH in
    110         *arm)
    111             ARCH=arm
    112             ;;
    113         *x86)
    114             ARCH=x86
    115             ;;
    116         *mips)
    117             ARCH=mips
    118             ;;
    119         *arm64)
    120             ARCH=arm64
    121             ;;
    122         *x86_64)
    123             ARCH=x86_64
    124             ;;
    125         *mips64)
    126             ARCH=mips64
    127             ;;
    128         *)
    129             ARCH=arm
    130             ;;
    131     esac
    132 
    133 fi
    134 
    135 if [ -z "$ABIS" ]; then
    136     ABIS=$(convert_arch_to_abi $ARCH)
    137 fi
    138 
    139 if [ -z "$ABIS" ]; then
    140     dump "ERROR: No ABIS. Possibly unsupported NDK architecture $ARCH?"
    141     exit 1
    142 fi
    143 
    144 ARCH_LIB=$ARCH
    145 ARCH_STL=$ARCH
    146 if [ "$ARCH_INC" != "$ARCH" ]; then
    147     test -n "`echo $ARCH_INC | grep bc$ARCH`" && NEED_BC2NATIVE=yes
    148     test -z "`echo $ARCH_INC | grep $ARCH`" && NEED_BC_LIB=yes
    149     ARCH_INC=$(find_ndk_unknown_archs)
    150     test -z "$ARCH_INC" && ARCH_INC="$ARCH"
    151     test "$NEED_BC_LIB" = "yes" && ARCH_LIB=$ARCH_INC
    152     test "$NEED_BC_LIB" = "yes" -o "$NEED_BC2NATIVE" = "yes" && ARCH_STL=$ARCH_INC
    153 fi
    154 
    155 # Check toolchain name
    156 if [ -z "$TOOLCHAIN_NAME" ]; then
    157     TOOLCHAIN_NAME=$(get_default_toolchain_name_for_arch $ARCH)
    158     echo "Auto-config: --toolchain=$TOOLCHAIN_NAME"
    159 fi
    160 
    161 if [ "$ARCH_STL" != "$ARCH" ]; then
    162     if [ "$STL" != stlport ]; then
    163         echo "Force-config: --stl=stlport"
    164         STL=stlport
    165     fi
    166 fi
    167 
    168 if [ "$ARCH_INC" != "$ARCH" ]; then
    169     TARGET_ABI=$(convert_arch_to_abi $ARCH | tr ',' '\n' | tail -n 1)
    170     if [ -z "$LLVM_VERSION" ]; then
    171         LLVM_VERSION=$DEFAULT_LLVM_VERSION
    172     fi
    173 fi
    174 
    175 # Detect LLVM version from toolchain name with *clang*
    176 LLVM_VERSION_EXTRACT=$(echo "$TOOLCHAIN_NAME" | grep 'clang[0-9]\.[0-9]$' | sed -e 's/.*-clang//')
    177 if [ -n "$LLVM_VERSION_EXTRACT" ]; then
    178     NEW_TOOLCHAIN_NAME=${TOOLCHAIN_NAME%-clang${LLVM_VERSION_EXTRACT}}
    179     if [ -z "$LLVM_VERSION" ]; then
    180         LLVM_VERSION=$LLVM_VERSION_EXTRACT
    181         echo "Auto-config: --toolchain=$NEW_TOOLCHAIN_NAME, --llvm-version=$LLVM_VERSION"
    182     else
    183         if [ "$LLVM_VERSION" != "$LLVM_VERSION_EXTRACT" ]; then
    184             echo "Conflict llvm-version: --llvm-version=$LLVM_VERSION and as implied by --toolchain=$TOOLCHAIN_NAME"
    185             exit 1
    186 	fi
    187     fi
    188     TOOLCHAIN_NAME=$NEW_TOOLCHAIN_NAME
    189 fi
    190 
    191 # Check PLATFORM
    192 if [ -z "$PLATFORM" -a "$ARCH_INC" = "$ARCH" ] ; then
    193     case $ARCH in
    194         arm) PLATFORM=android-3
    195             ;;
    196         x86|mips)
    197             PLATFORM=android-9
    198             ;;
    199         arm64|x86_64|mips64)
    200             PLATFORM=android-$FIRST_API64_LEVEL
    201             ;;
    202         *)
    203             dump "ERROR: Unsupported NDK architecture $ARCH!"
    204     esac
    205     log "Auto-config: --platform=$PLATFORM"
    206 elif [ -z "$PLATFORM" ] ; then
    207     PLATFORM=android-9
    208     log "Auto-config: --platform=$PLATFORM"
    209 fi
    210 
    211 if [ ! -d "$NDK_DIR/platforms/$PLATFORM" ] ; then
    212     echo "Invalid platform name: $PLATFORM"
    213     echo "Please use --platform=<name> with one of:" `(cd "$NDK_DIR/platforms" && ls)`
    214     exit 1
    215 fi
    216 
    217 # Check toolchain name
    218 TOOLCHAIN_PATH="$NDK_DIR/toolchains/$TOOLCHAIN_NAME"
    219 if [ ! -d "$TOOLCHAIN_PATH" ] ; then
    220     echo "Invalid toolchain name: $TOOLCHAIN_NAME"
    221     echo "Please use --toolchain=<name> with the name of a toolchain supported by the source NDK."
    222     echo "Try one of: " `(cd "$NDK_DIR/toolchains" && ls)`
    223     exit 1
    224 fi
    225 
    226 # Extract architecture from platform name
    227 parse_toolchain_name $TOOLCHAIN_NAME
    228 
    229 case "$TOOLCHAIN_NAME" in
    230   *4.9l)
    231     GCC_VERSION=4.9l
    232     ;;
    233   *4.8l)
    234     GCC_VERSION=4.8l
    235     ;;
    236 esac
    237 
    238 # Check that there are any platform files for it!
    239 (cd $NDK_DIR/platforms && ls -d */arch-$ARCH_INC >/dev/null 2>&1 )
    240 if [ $? != 0 ] ; then
    241     echo "Platform $PLATFORM doesn't have any files for this architecture: $ARCH_INC"
    242     echo "Either use --platform=<name> or --toolchain=<name> to select a different"
    243     echo "platform or arch-dependent toolchain name (respectively)!"
    244     exit 1
    245 fi
    246 
    247 # Compute source sysroot
    248 SRC_SYSROOT_INC="$NDK_DIR/platforms/$PLATFORM/arch-$ARCH_INC/usr/include"
    249 SRC_SYSROOT_LIB="$NDK_DIR/platforms/$PLATFORM/arch-$ARCH_LIB/usr/lib"
    250 if [ ! -d "$SRC_SYSROOT_INC" -o ! -d "$SRC_SYSROOT_LIB" ] ; then
    251     echo "No platform files ($PLATFORM) for this architecture: $ARCH"
    252     exit 1
    253 fi
    254 
    255 # Check that we have any prebuilts GCC toolchain here
    256 if [ ! -d "$TOOLCHAIN_PATH/prebuilt" ]; then
    257     echo "Toolchain is missing prebuilt files: $TOOLCHAIN_NAME"
    258     echo "You must point to a valid NDK release package!"
    259     exit 1
    260 fi
    261 
    262 if [ ! -d "$TOOLCHAIN_PATH/prebuilt/$SYSTEM" ] ; then
    263     echo "Host system '$SYSTEM' is not supported by the source NDK!"
    264     echo "Try --system=<name> with one of: " `(cd $TOOLCHAIN_PATH/prebuilt && ls) | grep -v gdbserver`
    265     exit 1
    266 fi
    267 
    268 TOOLCHAIN_PATH="$TOOLCHAIN_PATH/prebuilt/$SYSTEM"
    269 TOOLCHAIN_GCC=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET-gcc
    270 
    271 if [ ! -f "$TOOLCHAIN_GCC" ] ; then
    272     echo "Toolchain $TOOLCHAIN_GCC is missing!"
    273     exit 1
    274 fi
    275 
    276 if [ -n "$LLVM_VERSION" ]; then
    277     LLVM_TOOLCHAIN_PATH="$NDK_DIR/toolchains/llvm-$LLVM_VERSION"
    278     # Check that we have any prebuilts LLVM toolchain here
    279     if [ ! -d "$LLVM_TOOLCHAIN_PATH/prebuilt" ] ; then
    280         echo "LLVM Toolchain is missing prebuilt files"
    281         echo "You must point to a valid NDK release package!"
    282         exit 1
    283     fi
    284 
    285     if [ ! -d "$LLVM_TOOLCHAIN_PATH/prebuilt/$SYSTEM" ] ; then
    286         echo "Host system '$SYSTEM' is not supported by the source NDK!"
    287         echo "Try --system=<name> with one of: " `(cd $LLVM_TOOLCHAIN_PATH/prebuilt && ls)`
    288         exit 1
    289     fi
    290     LLVM_TOOLCHAIN_PATH="$LLVM_TOOLCHAIN_PATH/prebuilt/$SYSTEM"
    291 fi
    292 
    293 # Get GCC_BASE_VERSION.  Note that GCC_BASE_VERSION may be slightly different from GCC_VERSION.
    294 # eg. In gcc4.6 GCC_BASE_VERSION is "4.6.x-google"
    295 LIBGCC_PATH=`$TOOLCHAIN_GCC -print-libgcc-file-name`
    296 LIBGCC_BASE_PATH=${LIBGCC_PATH%/*}         # base path of libgcc.a
    297 GCC_BASE_VERSION=${LIBGCC_BASE_PATH##*/}   # stuff after the last /
    298 
    299 # Create temporary directory
    300 TMPDIR=$NDK_TMPDIR/standalone/$TOOLCHAIN_NAME
    301 
    302 dump "Copying prebuilt binaries..."
    303 # Now copy the GCC toolchain prebuilt binaries
    304 run copy_directory "$TOOLCHAIN_PATH" "$TMPDIR"
    305 
    306 # Replace soft-link mcld by real file
    307 ALL_LDS=`find $TMPDIR -name "*mcld"`
    308 for LD in $ALL_LDS; do
    309   rm -f "$LD"
    310   cp -a "$NDK_DIR/toolchains/llvm-$DEFAULT_LLVM_VERSION/prebuilt/$SYSTEM/bin/ld.mcld" "$LD"
    311 done
    312 
    313 # Copy python-related to for gdb.exe
    314 PYTHON=python
    315 PYTHON_x=python$(echo "$DEFAULT_PYTHON_VERSION" | cut -d . -f 1)
    316 PYTHON_xdotx=python$(echo "$DEFAULT_PYTHON_VERSION" | cut -d . -f 1).$(echo "$DEFAULT_PYTHON_VERSION" | cut -d . -f 2)
    317 copy_directory "$NDK_DIR/prebuilt/$SYSTEM/include/$PYTHON_xdotx" "$TMPDIR/include/$PYTHON_xdotx"
    318 copy_directory "$NDK_DIR/prebuilt/$SYSTEM/lib/$PYTHON_xdotx" "$TMPDIR/lib/$PYTHON_xdotx"
    319 copy_file_list "$NDK_DIR/prebuilt/$SYSTEM/bin" "$TMPDIR/bin" "$PYTHON$HOST_EXE" "$PYTHON_x$HOST_EXE" "$PYTHON_xdotx$HOST_EXE"
    320 if [ "$HOST_TAG32" = "windows" ]; then
    321   copy_file_list "$NDK_DIR/prebuilt/$SYSTEM/bin" "$TMPDIR/bin" lib$PYTHON_xdotx.dll
    322 fi
    323 
    324 # Copy yasm for x86
    325 if [ "$ARCH" = "x86" ]; then
    326   copy_file_list "$NDK_DIR/prebuilt/$SYSTEM/bin" "$TMPDIR/bin" "yasm$HOST_EXE"
    327 fi
    328 
    329 # Clang stuff
    330 
    331 dump_extra_compile_commands () {
    332   if [ "$NEED_BC2NATIVE" != "yes" ]; then
    333     return
    334   fi
    335 
    336   if [ -z "$HOST_EXE" ]; then
    337     echo '# Call bc2native if needed'
    338     echo ''
    339     echo 'if [ -n "`echo $@ | grep '\'\\ \\-c\''`" ] || [ "$1" = "-c" ]; then'
    340     echo '  exit'
    341     echo 'fi'
    342 
    343     echo 'while [ -n "$1" ]; do'
    344     echo '  if [ "$1" = "-o" ]; then'
    345     echo '    output="$2"'
    346     echo '    break'
    347     echo '  fi'
    348     echo '  shift'
    349     echo 'done'
    350     echo 'test -z "$output" && output=a.out'
    351     echo 'if [ -f "`dirname $0`/ndk-bc2native" ]; then'
    352     echo '  `dirname $0`/ndk-bc2native --sysroot=`dirname $0`/../sysroot --abi='$TARGET_ABI' --platform='$PLATFORM' --file $output $output'
    353     echo 'else'
    354     echo '  export PYTHONPATH=`dirname $0`/../lib/python2.7/'
    355     echo '  `dirname $0`/python `dirname $0`/ndk-bc2native.py --sysroot=`dirname $0`/../sysroot --abi='$TARGET_ABI' --platform='$PLATFORM' --file $output $output'
    356     echo 'fi'
    357   else
    358     echo 'rem Call bc2native if needed'
    359     echo ''
    360     echo '  if not "%1" == "-c" goto :keep_going'
    361     echo '  echo %* | grep "\\ \\-c"'
    362     echo '  if ERRORLEVEL 1 goto :keep_going'
    363     echo '  exit'
    364     echo ':keep_going'
    365 
    366     echo ':keep_find_output'
    367     echo '  if not "%1" == "-o" goto :check_next'
    368     echo '  set output=%2'
    369     echo ':check_next'
    370     echo '  shift'
    371     echo '  if "%1" == "" goto :keep_find_output'
    372     echo '  if not "%output%" == "" goto :check_done'
    373     echo '  set output=a.out'
    374     echo ':check_done'
    375     echo 'if exist %~dp0\\ndk-bc2native'$HOST_EXE' ('
    376     echo '  %~dp0\\ndk-bc2native'$HOST_EXE' --sysroot=%~dp0\\.\\sysroot --abi='$TARGET_ABI' --platform='$PLATFORM' --file %output% %output'
    377     echo 'else ('
    378     echo '  set PYTHONPATH=%~dp0\\..\\lib\\python2.7\\'
    379     echo '  %~dp0\\python'$HOST_EXE' %~dp0\\ndk-bc2native.py --sysroot=%~dp0\\..\\sysroot --abi='$TARGET_ABI' --platform='$PLATFORM' --file %output% %output%'
    380     echo ')'
    381   fi
    382 }
    383 
    384 if [ -n "$LLVM_VERSION" ]; then
    385   # Copy the clang/llvm toolchain prebuilt binaries
    386   run copy_directory "$LLVM_TOOLCHAIN_PATH" "$TMPDIR"
    387 
    388   # Move clang and clang++ to clang${LLVM_VERSION} and clang${LLVM_VERSION}++,
    389   # then create scripts linking them with predefined -target flag.  This is to
    390   # make clang/++ easier drop-in replacement for gcc/++ in NDK standalone mode.
    391   # Note that the file name of "clang" isn't important, and the trailing
    392   # "++" tells clang to compile in C++ mode
    393   LLVM_TARGET=
    394   case "$ARCH" in
    395       arm) # NOte: -target may change by clang based on the
    396            #        presence of subsequent -march=armv7-a and/or -mthumb
    397           LLVM_TARGET=armv5te-none-linux-androideabi
    398           TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm
    399           ;;
    400       x86)
    401           LLVM_TARGET=i686-none-linux-android
    402           TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86
    403           ;;
    404       mips)
    405           LLVM_TARGET=mipsel-none-linux-android
    406           TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips
    407           ;;
    408       arm64)
    409           LLVM_TARGET=aarch64-none-linux-android
    410           TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm64
    411           ;;
    412       x86_64)
    413           LLVM_TARGET=x86_64-none-linux-android
    414           TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86_64
    415           ;;
    416       mips64)
    417           LLVM_TARGET=mips64el-none-linux-android
    418           TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips64
    419           ;;
    420       *)
    421         dump "ERROR: Unsupported NDK architecture $ARCH!"
    422   esac
    423   # Need to remove '.' from LLVM_VERSION when constructing new clang name,
    424   # otherwise clang3.3++ may still compile *.c code as C, not C++, which
    425   # is not consistent with g++
    426   LLVM_VERSION_WITHOUT_DOT=$(echo "$LLVM_VERSION" | sed -e "s!\.!!")
    427   mv "$TMPDIR/bin/clang${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}"
    428   if [ -h "$TMPDIR/bin/clang++${HOST_EXE}" ] ; then
    429     ## clang++ is a link to clang.  Remove it and reconstruct
    430     rm "$TMPDIR/bin/clang++${HOST_EXE}"
    431     ln -sf "clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE}"
    432   else
    433     mv "$TMPDIR/bin/clang++${HOST_EXE}" "$TMPDIR/bin/clang$LLVM_VERSION_WITHOUT_DOT++${HOST_EXE}"
    434   fi
    435 
    436   EXTRA_CLANG_FLAGS=
    437   EXTRA_CLANGXX_FLAGS=
    438   if [ "$ARCH_STL" != "$ARCH" ]; then
    439     LLVM_TARGET=le32-none-ndk
    440     EXTRA_CLANG_FLAGS="-emit-llvm"
    441     EXTRA_CLANGXX_FLAGS="$EXTRA_CLANG_FLAGS -I\`dirname \$0\`/../include/c++/$GCC_BASE_VERSION"
    442   fi
    443 
    444   cat > "$TMPDIR/bin/clang" <<EOF
    445 if [ "\$1" != "-cc1" ]; then
    446     \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT -target $LLVM_TARGET "\$@" $EXTRA_CLANG_FLAGS
    447     $(dump_extra_compile_commands)
    448 else
    449     # target/triple already spelled out.
    450     \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT "\$@" $EXTRA_CLANG_FLAGS
    451 fi
    452 EOF
    453   cat > "$TMPDIR/bin/clang++" <<EOF
    454 if [ "\$1" != "-cc1" ]; then
    455     \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT++ -target $LLVM_TARGET "\$@" $EXTRA_CLANGXX_FLAGS
    456     $(dump_extra_compile_commands)
    457 else
    458     # target/triple already spelled out.
    459     \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT++ "\$@" $EXTRA_CLANGXX_FLAGS
    460 fi
    461 EOF
    462   chmod 0755 "$TMPDIR/bin/clang" "$TMPDIR/bin/clang++"
    463   cp -a "$TMPDIR/bin/clang" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang"
    464   cp -a "$TMPDIR/bin/clang++" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang++"
    465 
    466   if [ -n "$HOST_EXE" ] ; then
    467     cat > "$TMPDIR/bin/clang.cmd" <<EOF
    468 @echo off
    469 if "%1" == "-cc1" goto :L
    470 %~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE} -target $LLVM_TARGET %* $EXTRA_CLANG_FLAGS
    471 $(dump_extra_compile_commands)
    472 if ERRORLEVEL 1 exit /b 1
    473 goto :done
    474 :L
    475 rem target/triple already spelled out.
    476 %~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE} %* $EXTRA_CLANG_FLAGS
    477 if ERRORLEVEL 1 exit /b 1
    478 :done
    479 EOF
    480     cat > "$TMPDIR/bin/clang++.cmd" <<EOF
    481 @echo off
    482 if "%1" == "-cc1" goto :L
    483 %~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE} -target $LLVM_TARGET %* $EXTRA_CLANGXX_FLAGS
    484 $(dump_extra_compile_commands)
    485 if ERRORLEVEL 1 exit /b 1
    486 goto :done
    487 :L
    488 rem target/triple already spelled out.
    489 %~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE} %* $EXTRA_CLANGXX_FLAGS
    490 if ERRORLEVEL 1 exit /b 1
    491 :done
    492 EOF
    493     chmod 0755 "$TMPDIR/bin/clang.cmd" "$TMPDIR/bin/clang++.cmd"
    494     cp -a "$TMPDIR/bin/clang.cmd" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang.cmd"
    495     cp -a "$TMPDIR/bin/clang++.cmd" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang++.cmd"
    496   fi
    497 fi
    498 
    499 dump "Copying sysroot headers and libraries..."
    500 # Copy the sysroot under $TMPDIR/sysroot. The toolchain was built to
    501 # expect the sysroot files to be placed there!
    502 run copy_directory_nolinks "$SRC_SYSROOT_INC" "$TMPDIR/sysroot/usr/include"
    503 run copy_directory_nolinks "$SRC_SYSROOT_LIB" "$TMPDIR/sysroot/usr/lib"
    504 # x86_64 and mips64el toolchain are built multilib.
    505 if [ "$ARCH" = "x86_64" -o "$ARCH" = "mips64" ]; then
    506     run copy_directory_nolinks "$SRC_SYSROOT_LIB/../lib64" "$TMPDIR/sysroot/usr/lib64"
    507     if [ "$ARCH" = "x86_64" ]; then
    508         run copy_directory_nolinks "$SRC_SYSROOT_LIB/../libx32" "$TMPDIR/sysroot/usr/libx32"
    509     else
    510         run copy_directory_nolinks "$SRC_SYSROOT_LIB/../lib32" "$TMPDIR/sysroot/usr/lib32"
    511     fi
    512 fi
    513 if [ "$ARCH_INC" != "$ARCH" ]; then
    514     cp -a $NDK_DIR/$GABIXX_SUBDIR/libs/$ABI/* $TMPDIR/sysroot/usr/lib
    515     cp -a $NDK_DIR/$LIBPORTABLE_SUBDIR/libs/$ABI/* $TMPDIR/sysroot/usr/lib
    516     cp -a $NDK_DIR/$GCCUNWIND_SUBDIR/libs/$ABI/* $TMPDIR/sysroot/usr/lib
    517     if [ "$ARCH" = "${ARCH%%64*}" ]; then
    518         cp -a $NDK_DIR/$COMPILER_RT_SUBDIR/libs/$ABI/* $TMPDIR/sysroot/usr/lib
    519     fi
    520 fi
    521 
    522 if [ "$ARCH_LIB" != "$ARCH" ]; then
    523     cp -a $NDK_DIR/platforms/$PLATFORM/arch-$ARCH/usr/lib/crt* $TMPDIR/sysroot/usr/lib
    524 fi
    525 
    526 GNUSTL_DIR=$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION
    527 GNUSTL_LIBS=$GNUSTL_DIR/libs
    528 
    529 STLPORT_DIR=$NDK_DIR/$STLPORT_SUBDIR
    530 STLPORT_LIBS=$STLPORT_DIR/libs
    531 
    532 LIBCXX_DIR=$NDK_DIR/$LIBCXX_SUBDIR
    533 LIBCXX_LIBS=$LIBCXX_DIR/libs
    534 case $ARCH in
    535     x86|x86_64|mips|mips64)
    536         LIBCXX_SUPPORT_LIB=gabi++
    537         ;;
    538     *)
    539         LIBCXX_SUPPORT_LIB=libc++abi
    540         ;;
    541 esac
    542 
    543 SUPPORT_DIR=$NDK_DIR/$SUPPORT_SUBDIR
    544 
    545 COMPILER_RT_DIR=$NDK_DIR/$COMPILER_RT_SUBDIR
    546 COMPILER_RT_LIBS=$COMPILER_RT_DIR/libs
    547 
    548 if [ "$STL" = "libcxx" -o "$STL" = "libc++" ]; then
    549     dump "Copying c++ runtime headers and libraries (with $LIBCXX_SUPPORT_LIB)..."
    550 else
    551     dump "Copying c++ runtime headers and libraries..."
    552 fi
    553 
    554 ABI_STL="$TMPDIR/$ABI_CONFIGURE_TARGET"
    555 ABI_STL_INCLUDE="$TMPDIR/include/c++/$GCC_BASE_VERSION"
    556 ABI_STL_INCLUDE_TARGET="$ABI_STL_INCLUDE/$ABI_CONFIGURE_TARGET"
    557 
    558 # $1: filenames of headers
    559 copy_abi_headers () {
    560   local ABI_NAME=$1
    561   shift
    562 
    563   for header in $@; do
    564     (set -e; cd $ABI_STL_INCLUDE && cp -a ../../$ABI_NAME/include/$header $header) || exit 1
    565   done
    566 }
    567 
    568 # Copy common STL headers (i.e. the non-arch-specific ones)
    569 copy_stl_common_headers () {
    570     case $STL in
    571         gnustl)
    572             copy_directory "$GNUSTL_DIR/include" "$ABI_STL_INCLUDE"
    573             ;;
    574         libcxx|libc++)
    575             copy_directory "$LIBCXX_DIR/libcxx/include" "$ABI_STL_INCLUDE"
    576             copy_directory "$SUPPORT_DIR/include" "$ABI_STL_INCLUDE"
    577             if [ "$LIBCXX_SUPPORT_LIB" = "gabi++" ]; then
    578                 copy_directory "$STLPORT_DIR/../gabi++/include" "$ABI_STL_INCLUDE/../../gabi++/include"
    579                 copy_abi_headers gabi++ cxxabi.h unwind.h unwind-arm.h unwind-itanium.h gabixx_config.h
    580             elif [ "$LIBCXX_SUPPORT_LIB" = "libc++abi" ]; then
    581                 copy_directory "$LIBCXX_DIR/../llvm-libc++abi/libcxxabi/include" "$ABI_STL_INCLUDE/../../llvm-libc++abi/include"
    582                 copy_abi_headers llvm-libc++abi cxxabi.h libunwind.h unwind.h
    583             else
    584                 dump "ERROR: Unknown libc++ support lib: $LIBCXX_SUPPORT_LIB"
    585                 exit 1
    586             fi
    587             ;;
    588         stlport)
    589             copy_directory "$STLPORT_DIR/stlport" "$ABI_STL_INCLUDE"
    590             copy_directory "$STLPORT_DIR/../gabi++/include" "$ABI_STL_INCLUDE/../../gabi++/include"
    591             copy_abi_headers gabi++ cxxabi.h unwind.h unwind-arm.h unwind-itanium.h gabixx_config.h
    592             ;;
    593     esac
    594 }
    595 
    596 # $1: Source ABI (e.g. 'armeabi')
    597 # #2  Optional destination path of additional header to copy (eg. include/bits), default to empty
    598 # $3: Optional source path of additional additional header to copy, default to empty
    599 # $4: Optional destination directory, default to empty (e.g. "", "thumb", "armv7-a/thumb")
    600 # $5: Optional source directory, default to empty (e.g. "", "thumb", "armv7-a/thumb")
    601 copy_stl_libs () {
    602     local ABI=$1
    603     local HEADER_DST=$2
    604     local HEADER_SRC=$3
    605     local DEST_DIR=$4
    606     local SRC_DIR=$5
    607     local ABI_SRC_DIR=$ABI
    608 
    609     if [ -n "$SRC_DIR" ]; then
    610         ABI_SRC_DIR=$ABI/$SRC_DIR
    611     else
    612         if [ "$DEST_DIR" != "${DEST_DIR%%/*}" ] ; then
    613             ABI_SRC_DIR=$ABI/`basename $DEST_DIR`
    614         fi
    615     fi
    616 
    617     case $STL in
    618         gnustl)
    619             if [ "$HEADER_SRC" != "" ]; then
    620                 copy_directory "$GNUSTL_LIBS/$ABI/include/$HEADER_SRC" "$ABI_STL_INCLUDE_TARGET/$HEADER_DST"
    621             fi
    622             copy_file_list "$GNUSTL_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libgnustl_shared.so"
    623             copy_file_list "$GNUSTL_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libsupc++.a"
    624             cp -p "$GNUSTL_LIBS/$ABI_SRC_DIR/libgnustl_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
    625             ;;
    626         libcxx|libc++)
    627             if [ "$ARCH" = "${ARCH%%64*}" ]; then
    628                 copy_file_list "$COMPILER_RT_LIBS/$ABI" "$ABI_STL/lib/$DEST_DIR" "libcompiler_rt_shared.so" "libcompiler_rt_static.a"
    629             fi
    630             copy_file_list "$LIBCXX_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libc++_shared.so"
    631             cp -p "$LIBCXX_LIBS/$ABI_SRC_DIR/libc++_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
    632             ;;
    633         stlport)
    634             if [ "$ARCH_STL" != "$ARCH" ]; then
    635               tmp_lib_dir=$TMPDIR/stl
    636               $NDK_DIR/build/tools/build-cxx-stl.sh --stl=stlport --out-dir=$tmp_lib_dir --abis=unknown
    637               cp -p "`ls $tmp_lib_dir/sources/cxx-stl/stlport/libs/*/libstlport_static.a`" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
    638               cp -p "`ls $tmp_lib_dir/sources/cxx-stl/stlport/libs/*/libstlport_shared.bc`" "$ABI_STL/lib/$DEST_DIR/libstlport_shared.so"
    639               rm -rf $tmp_lib_dir
    640             else
    641               copy_file_list "$STLPORT_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libstlport_shared.so"
    642               cp -p "$STLPORT_LIBS/$ABI_SRC_DIR/libstlport_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
    643             fi
    644             ;;
    645         *)
    646             dump "ERROR: Unsupported STL: $STL"
    647             exit 1
    648             ;;
    649     esac
    650 }
    651 
    652 # $1: Source ABI (e.g. 'armeabi')
    653 copy_stl_libs_for_abi () {
    654     local ABI=$1
    655 
    656     if [ "$(convert_abi_to_arch "$ABI")" != "$ARCH" ]; then
    657         dump "ERROR: ABI '$ABI' does not match ARCH '$ARCH'"
    658         exit 1
    659     fi
    660 
    661     case $ABI in
    662         armeabi)
    663             copy_stl_libs armeabi          "bits"                "bits"
    664             copy_stl_libs armeabi          "thumb/bits"          "bits"       "/thumb"
    665             ;;
    666         armeabi-v7a)
    667             copy_stl_libs armeabi-v7a      "armv7-a/bits"        "bits"       "armv7-a"
    668             copy_stl_libs armeabi-v7a      "armv7-a/thumb/bits"  "bits"       "armv7-a/thumb"
    669             ;;
    670         armeabi-v7a-hard)
    671             copy_stl_libs armeabi-v7a-hard ""                    ""           "armv7-a/hard"       "."
    672             copy_stl_libs armeabi-v7a-hard ""                    ""           "armv7-a/thumb/hard" "thumb"
    673             ;;
    674         x86_64)
    675             if [ "$STL" = "gnustl" ]; then
    676                 copy_stl_libs x86_64       "32/bits"             "32/bits"    ""                   "lib"
    677                 copy_stl_libs x86_64       "bits"                "bits"       "../lib64"           "lib64"
    678                 copy_stl_libs x86_64       "x32/bits"            "x32/bits"   "../libx32"          "libx32"
    679             else
    680                 copy_stl_libs "$ABI"
    681             fi
    682             ;;
    683         mips64)
    684             if [ "$STL" = "gnustl" ]; then
    685                 copy_stl_libs mips64       "32/bits"             "32/bits"    ""                   "lib"
    686                 copy_stl_libs mips64       "bits"                "bits"       "../lib64"           "lib64"
    687                 copy_stl_libs mips64       "n32/bits"            "n32/bits"   "../lib32"           "lib32"
    688             else
    689                 copy_stl_libs "$ABI"
    690             fi
    691             ;;
    692         *)
    693             copy_stl_libs "$ABI"           "bits"                "bits"
    694             ;;
    695     esac
    696 }
    697 
    698 mkdir -p "$ABI_STL_INCLUDE_TARGET"
    699 fail_panic "Can't create directory: $ABI_STL_INCLUDE_TARGET"
    700 copy_stl_common_headers
    701 for ABI in $(tr ',' ' ' <<< $ABIS); do
    702   copy_stl_libs_for_abi "$ABI"
    703 done
    704 
    705 # Install or Package
    706 if [ -n "$INSTALL_DIR" ] ; then
    707     dump "Copying files to: $INSTALL_DIR"
    708     if [ ! -d "$INSTALL_DIR" ]; then
    709         run move_directory "$TMPDIR" "$INSTALL_DIR"
    710     else
    711         run copy_directory "$TMPDIR" "$INSTALL_DIR"
    712     fi
    713 else
    714     PACKAGE_FILE="$PACKAGE_DIR/$TOOLCHAIN_NAME.tar.bz2"
    715     dump "Creating package file: $PACKAGE_FILE"
    716     pack_archive "$PACKAGE_FILE" "`dirname $TMPDIR`" "$TOOLCHAIN_NAME"
    717     fail_panic "Could not create tarball from $TMPDIR"
    718 fi
    719 dump "Cleaning up..."
    720 run rm -rf $TMPDIR
    721 
    722 dump "Done."
    723