diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/build-apk.sh | 1 | ||||
-rw-r--r-- | scripts/build-boost.sh | 44 | ||||
-rwxr-xr-x | scripts/compile_androidviper.sh | 7 | ||||
-rwxr-xr-x | scripts/compile_iget.sh (renamed from scripts/compile_androidiget.sh) | 8 | ||||
-rwxr-xr-x | scripts/compile_metisforwarder.sh (renamed from scripts/compile_androidmetis.sh) | 8 | ||||
-rwxr-xr-x | scripts/init.sh | 110 | ||||
-rwxr-xr-x | scripts/init_qt.sh | 46 | ||||
-rw-r--r-- | scripts/install_script.sh | 2 | ||||
-rwxr-xr-x | scripts/tools/build-target-openssl.sh | 392 | ||||
-rw-r--r-- | scripts/tools/dev-defaults.sh | 355 | ||||
-rw-r--r-- | scripts/tools/ndk-common.sh | 1048 | ||||
-rwxr-xr-x | scripts/tools/prebuilt-common.sh | 1607 | ||||
-rwxr-xr-x | scripts/update.sh | 2 |
13 files changed, 3561 insertions, 69 deletions
diff --git a/scripts/build-apk.sh b/scripts/build-apk.sh index e8298a28..d86c176f 100644 --- a/scripts/build-apk.sh +++ b/scripts/build-apk.sh @@ -175,5 +175,4 @@ make android_iget # Compile viper make android_viper -mv build/viper/viper-armv7//build/outputs/apk/viper-armv7-release-signed.apk iget_android/app/build/outputs/apk/ popd diff --git a/scripts/build-boost.sh b/scripts/build-boost.sh new file mode 100644 index 00000000..38b45db0 --- /dev/null +++ b/scripts/build-boost.sh @@ -0,0 +1,44 @@ +#!/bin/bash +rm -rf bin.v2/libs +rm -rf stage/lib +rm -rf install_boost +PREFIX=`pwd`/install_boost + +if [ $ABI = armeabi-v7a ]; then + ./b2 link=static threading=multi threadapi=pthread target-os=android --with-system\ + toolset=gcc-arm architecture=arm address-model=32 \ + abi=aapcs binary-format=elf define=BOOST_MATH_DISABLE_FLOAT128 \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/include \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/${ABI}/include \ + include=$NDK/platforms/android-24/arch-arm/usr/include \ + --prefix=$PREFIX \ + install +elif [ $ABI = x86 ]; then + ./b2 link=static threading=multi threadapi=pthread target-os=android --with-system\ + toolset=gcc-x86 architecture=x86 address-model=32 \ + abi=aapcs binary-format=elf define=BOOST_MATH_DISABLE_FLOAT128 \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/include \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/${ABI}/include \ + include=$NDK/platforms/android-24/arch-x86/usr/include \ + --prefix=$PREFIX \ + install +elif [ $ABI = x86_64 ]; then + ./b2 link=static threading=multi threadapi=pthread target-os=android --with-system\ + toolset=gcc-x86_64 architecture=x86_64 address-model=64 \ + abi=aapcs binary-format=elf define=BOOST_MATH_DISABLE_FLOAT128 \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/include \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/${ABI}/include \ + include=$NDK/platforms/android-24/arch-x86_64/usr/include \ + --prefix=$PREFIX \ + install +else + ./b2 link=static threading=multi threadapi=pthread target-os=android --with-system\ + toolset=gcc-arm64 architecture=arm64-v8a address-model=64 \ + abi=aapcs binary-format=elf define=BOOST_MATH_DISABLE_FLOAT128 \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/include \ + include=$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/${ABI}/include \ + include=$NDK/platforms/android-24/arch-arm64/usr/include \ + --prefix=$PREFIX \ + install +fi + diff --git a/scripts/compile_androidviper.sh b/scripts/compile_androidviper.sh index 518580bd..e3f6b0b7 100755 --- a/scripts/compile_androidviper.sh +++ b/scripts/compile_androidviper.sh @@ -14,6 +14,9 @@ ############################################################################## #!/bin/bash + + +#!/bin/bash set -e export ANDROID_HOME=${SDK} export ANDROID_NDK_HOST=${OS}-${ARCH} @@ -29,10 +32,10 @@ echo $QT_HOME cd ${DISTILLERY_ROOT_DIR} mkdir -p ${DISTILLERY_BUILD_DIR}/viper cd ${DISTILLERY_BUILD_DIR}/viper -${QT_HOME}/5.7/android_${ANDROID_ARCH}/bin/qmake -r -spec android-g++ ${DISTILLERY_ROOT_DIR}/src/viper/viper.pro +${QT_HOME}/5.7/android_${ANDROID_ARCH}/bin/qmake -r -spec android-g++ ${DISTILLERY_ROOT_DIR}/src/viper/viper.pro "TRANSPORT_LIBRARY = ICNET" make make install INSTALL_ROOT=viper-${ANDROID_ARCH} -if [ "$1" == "DEBUG" ]; then +if [ "$1" = "DEBUG" ]; then ${QT_HOME}/5.7/android_${ANDROID_ARCH}/bin/androiddeployqt --output viper-${ANDROID_ARCH} --verbose --input android-libviper.so-deployment-settings.json --gradle --android-platform android-23 --stacktrace --debug --target android-23 --debug --sign ${DISTILLERY_ROOT_DIR}/src/viper/android/viper.keystore viper --storepass icn_viper else ${QT_HOME}/5.7/android_${ANDROID_ARCH}/bin/androiddeployqt --output viper-${ANDROID_ARCH} --verbose --input android-libviper.so-deployment-settings.json --gradle --android-platform android-23 --stacktrace --debug --target android-23 --release --sign ${DISTILLERY_ROOT_DIR}/src/viper/android/viper.keystore viper --storepass icn_viper diff --git a/scripts/compile_androidiget.sh b/scripts/compile_iget.sh index 499df54a..984dae07 100755 --- a/scripts/compile_androidiget.sh +++ b/scripts/compile_iget.sh @@ -1,16 +1,16 @@ #!/bin/bash -cd iget_android +cd iGetAndroid if [ ! -f local.properties ]; then echo sdk.dir=${SDK} > local.properties echo ndk.dir=${NDK} >> local.properties fi -if [ "$1" == "DEBUG" ]; then +if [ "$1" = "DEBUG" ]; then ./gradlew assembleDebug else ./gradlew assembleRelease fi -echo "Apks are inside iget_android/app/build/outputs/apk" -cd ..
\ No newline at end of file +echo "Apks are inside iGetAndroid/app/build/outputs/apk" +cd .. diff --git a/scripts/compile_androidmetis.sh b/scripts/compile_metisforwarder.sh index 2d80653c..7632149c 100755 --- a/scripts/compile_androidmetis.sh +++ b/scripts/compile_metisforwarder.sh @@ -1,16 +1,16 @@ #!/bin/bash -cd ccnxandroidmetis +cd MetisForwarder if [ ! -f local.properties ]; then echo sdk.dir=${SDK} > local.properties echo ndk.dir=${NDK} >> local.properties fi -if [ "$1" == "DEBUG" ]; then +if [ "$1" = "DEBUG" ]; then ./gradlew assembleDebug else ./gradlew assembleRelease fi -echo "Apks are inside ccnxandroidmetis/MetisControl/build/outputs/apk/" -cd ..
\ No newline at end of file +echo "Apks are inside MetisForwarder/app/build/outputs/apk" +cd .. diff --git a/scripts/init.sh b/scripts/init.sh index 6324c6b0..39d8e668 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -18,29 +18,33 @@ set -e ABI=$1 + INSTALLATION_DIR=$2 OS=`echo $OS | tr '[:upper:]' '[:lower:]'` +BASE_DIR=`pwd` echo "SDK_PATH ${SDK}" if [ -z ${SDK_PATH} ]; then mkdir -p sdk cd sdk if [ ! -d sdk ]; then - if [ $OS == darwin ]; then - if [ ! -f android-sdk_r23.0.2-macosx.zip ]; then - wget http://dl.google.com/android/android-sdk_r23.0.2-macosx.zip + if [ $OS = darwin ]; then + if [ ! -f android-sdk_r24.4.1-macosx.zip ]; then + wget http://dl.google.com/android/android-sdk_r24.4.1-macosx.zip fi - unzip -q android-sdk_r23.0.2-macosx.zip + unzip -q android-sdk_r24.4.1-macosx.zip mv android-sdk-macosx sdk else - if [ ! -f android-sdk_r23.0.2-linux.zip ]; then - wget http://dl.google.com/android/android-sdk_r23.0.2-linux.tgz + if [ ! -f android-sdk_r24.4.1-linux.zip ]; then + wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz fi - tar zxf android-sdk_r23.0.2-linux.tgz + tar zxf android-sdk_r24.4.1-linux.tgz mv android-sdk-linux sdk fi - mkdir "sdk/licenses" || true + mkdir -p sdk/licenses echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "sdk/licenses/android-sdk-license" echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "sdk/licenses/android-sdk-preview-license" + echo "y" | ./sdk/tools/android update sdk --filter platform-tools,build-tools-23.0.2,android-23,extra-android-m2repository,extra-google-m2repository --no-ui --all --force + echo "y" | ./sdk/tools/android update sdk --filter "android-23" --no-ui --all --forceecho y | ./sdk/tools/android update sdk --no-ui --all --filter build-tools-23.0.2 fi cd .. fi @@ -49,11 +53,11 @@ if [ -z ${NDK_PATH} ]; then mkdir -p sdk cd sdk if [ ! -d ndk-bundle ]; then - if [ ! -f android-ndk-r13b-${OS}-${ARCH}.zip ]; then - wget https://dl.google.com/android/repository/android-ndk-r13b-${OS}-${ARCH}.zip + if [ ! -f android-ndk-r14b-${OS}-${ARCH}.zip ]; then + wget https://dl.google.com/android/repository/android-ndk-r14b-${OS}-${ARCH}.zip fi - unzip -q android-ndk-r13b-${OS}-${ARCH}.zip - mv android-ndk-r13b ndk-bundle + unzip -q android-ndk-r14b-${OS}-${ARCH}.zip + mv android-ndk-r14b ndk-bundle fi cd .. fi @@ -71,8 +75,9 @@ if [ -z ${CMAKE_PATH} ]; then fi - +mkdir -p src cd src + if [ ! -d ccnxlibs ]; then echo "ccnxlibs not found" git clone -b ccnxlibs/master https://gerrit.fd.io/r/cicn ccnxlibs @@ -97,16 +102,12 @@ fi cd ../ cd external -if [ ! -d crystax-ndk-10.3.2 ]; then - echo "Crystax Directory not found!" - if [ ! -f crystax-ndk-10.3.2-${OS}-${ARCH}.tar.xz ]; then - echo "CrystaX Ndk not found!" - wget https://www.crystax.net/download/crystax-ndk-10.3.2-"${OS}"-${ARCH}.tar.xz - fi - tar xpf crystax-ndk-10.3.2-${OS}-${ARCH}.tar.xz -fi -if [ ! -d crystax-ndk-10.3.2/sources/openssl/1.0.2k ]; then +mkdir -p ${INSTALLATION_DIR} +mkdir -p ${INSTALLATION_DIR}/include +mkdir -p ${INSTALLATION_DIR}/lib + +if [ ! -d ${INSTALLATION_DIR}/include/openssl ]; then echo "OpenSSL Libs not found!" if [ ! -d openssl-1.0.2k ]; then echo "OpenSSL Directory not found" @@ -116,29 +117,60 @@ if [ ! -d crystax-ndk-10.3.2/sources/openssl/1.0.2k ]; then fi tar -xzf openssl-1.0.2k.tar.gz fi - ./crystax-ndk-10.3.2/build/tools/build-target-openssl.sh --abis=$ABI openssl-1.0.2k -fi - -mkdir -p ${INSTALLATION_DIR} -mkdir -p ${INSTALLATION_DIR}/include -mkdir -p ${INSTALLATION_DIR}/lib - -echo "Copy libssl and libcrypto in workspace" -if [ ! -d ${INSTALLATION_DIR}/include/openssl ]; then - cp -rf crystax-ndk-10.3.2/sources/openssl/1.0.2k/include/* ${INSTALLATION_DIR}/include/ + echo "Compile OpenSSL" + if [ ! -d ${NDK}/sources/openssl/1.0.2 ]; then + export ANDROID_NDK_ROOT=$NDK + bash ${BASE_DIR}/scripts/tools/build-target-openssl.sh --abis=$ABI openssl-1.0.2k --ndk-dir=${NDK} + fi + echo "Copy libssl and libcrypto in workspace" + cp -rf ${NDK}/sources/openssl/1.0.2k/include/* ${INSTALLATION_DIR}/include/ cp -f ${INSTALLATION_DIR}/include/openssl/opensslconf_armeabi_v7a.h ${INSTALLATION_DIR}/include/openssl/opensslconf_armeabi.h - cp -f crystax-ndk-10.3.2/sources/openssl/1.0.2k/libs/${ABI}/* ${INSTALLATION_DIR}/lib/ + cp -f ${NDK}/sources/openssl/1.0.2k/libs/${ABI}/*.a ${INSTALLATION_DIR}/lib/ + rm -rf ${NDK}/sources/openssl/1.0.2k fi -echo "Copy libboost in workspace" + if [ ! -d ${INSTALLATION_DIR}/include/boost ]; then - cp -rf crystax-ndk-10.3.2/sources/boost/1.59.0/include/* ${INSTALLATION_DIR}/include/ - cp -f crystax-ndk-10.3.2/sources/boost/1.59.0/libs/${ABI}/gnu-4.9/* ${INSTALLATION_DIR}/lib/ + echo "Boost Libs not found!" + if [ ! -d boost_1_63_0 ]; then + echo "Boost Directory not found" + if [ ! -f boost_1_63_0.tar.gz ]; then + echo "Boost Archive not found" + wget https://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.gz + fi + tar -xzf boost_1_63_0.tar.gz + fi + cd boost_1_63_0 + if [ ! -d install_boost ]; then + echo "Compile Boost" + ./bootstrap.sh + echo "import option ;" > project-config.jam + if [ $ABI = armeabi-v7a ]; then + echo "using gcc : arm : arm-linux-androideabi-g++ ;" >> project-config.jam + export PATH=$PATH:${NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/${OS}-${ARCH}/bin + elif [ $ABI = x86 ]; then + echo "using gcc : x86 : i686-linux-android-g++ ;" >> project-config.jam + export PATH=$PATH:${NDK}/toolchains/x86-4.9/prebuilt/${OS}-${ARCH}/bin + elif [ $ABI = x86_64 ]; then + echo "using gcc : x86_64 : x86_64-linux-android-g++ ;" >> project-config.jam + export PATH=$PATH:${NDK}/toolchains/x86_64-4.9/prebuilt/${OS}-${ARCH}/bin + else + echo "using gcc : arm64-v8a : aarch64-linux-android-g++ ;" >> project-config.jam + export PATH=$PATH:${NDK}/toolchains/aarch64-4.9/prebuilt/${OS}-${ARCH}/bin + fi + + echo "option.set keep-going : false ;" >> project-config.jam + echo "before compile" + bash ${BASE_DIR}/scripts/build-boost.sh + echo "after compile" + fi + echo "Copy boost libs in workspace" + cp -rf install_boost/include/* ${INSTALLATION_DIR}/include/ + cp -rf install_boost/lib/* ${INSTALLATION_DIR}/lib/ + cd .. + fi -echo "Copy libcrystax in workspace" -cp crystax-ndk-10.3.2/sources/crystax/libs/${ABI}/libcrystax.* ${INSTALLATION_DIR}/lib/ - echo "Create libevent" if [ ! -d ${INSTALLATION_DIR}/include/event2 ]; then diff --git a/scripts/init_qt.sh b/scripts/init_qt.sh index 065bffa6..62ba3ed0 100755 --- a/scripts/init_qt.sh +++ b/scripts/init_qt.sh @@ -17,35 +17,45 @@ set -e -if [ "$ARCH" == "x86" ]; then +if [ $ARCH = "x86" ]; then echo "Qt is not available for x86 systems" exit 1 fi + mkdir -p qt cd qt - +echo "####" +pwd +echo ${QT_HOME} +export QT_HOME=`pwd`/Qt +echo "####" if [ ! -d ${QT_HOME} ]; then - if [ "$OS" == "darwin" ]; then +echo ${QT_HOME} + if [ $OS = "darwin" ]; then if [ ! -f qt-opensource-mac-x64-android-5.7.1.dmg ]; then wget http://download.qt.io/archive/qt/5.7/5.7.1/qt-opensource-mac-x64-android-5.7.1.dmg fi + VOLUME=$(hdiutil attach qt-opensource-mac-x64-android-5.7.1.dmg | tail -1 | awk '{print $3}') + + echo "######" + pwd + echo "######" $VOLUME/qt-opensource-mac-x64-android-5.7.1.app/Contents/MacOS/qt-opensource-mac-x64-android-5.7.1 --script ../scripts/install_script.sh -platform minimal --verbose diskutil unmount $VOLUME else if [ ! -f qt-opensource-linux-x64-android-5.7.1.run ]; then wget http://download.qt.io/archive/qt/5.7/5.7.1/qt-opensource-linux-x64-android-5.7.1.run - chmod +x qt-opensource-linux-x64-android-5.7.1.run fi + chmod +x qt-opensource-linux-x64-android-5.7.1.run ./qt-opensource-linux-x64-android-5.7.1.run --script ../scripts/install_script.sh -platform minimal --verbose fi fi -cp -f $DISTILLERY_INSTALL_DIR/lib/libicnet.so ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/ -cp -f $DISTILLERY_INSTALL_DIR/lib/libcrystax.so ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/ + +echo $DISTILLERY_INSTALL_DIR cp -f $DISTILLERY_INSTALL_DIR/lib/libdash.so ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/ -cp -f $DISTILLERY_INSTALL_DIR/lib/libboost_system.so ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/ if [ ! -d ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/boost ]; then ln -s $DISTILLERY_INSTALL_DIR/include/ccnx ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/ @@ -53,30 +63,32 @@ if [ ! -d ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/boost ]; then ln -s $DISTILLERY_INSTALL_DIR/include/parc ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/ ln -s $DISTILLERY_INSTALL_DIR/include/LongBow ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/ ln -s $DISTILLERY_INSTALL_DIR/include/icnet ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/ - ln -s $DISTILLERY_INSTALL_DIR/include/libdash ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/ + ln -s $DISTILLERY_INSTALL_DIR/include/dash ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/ fi -if [ ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavcodec.so -o ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavfilter.so -o ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavformat.so -o ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavutil.so -o ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libswresample.so -o ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libswscale.so ]; then +if [[ ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavformat.so || ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavfilter.so || ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavformat.so || ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libavutil.so || ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libswresample.so || ! -f ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/libswscale.so ]]; then if [ ! -f ffmpeg-3.1.4-android.7z ]; then - wget https://downloads.sourceforge.net/project/qtav/depends/FFmpeg/android/ffmpeg-3.1.4-android.7z + wget https://downloads.sourceforge.net/project/qtav/depends/FFmpeg/android/ffmpeg-3.1.4-android.7z fi 7z x ffmpeg-3.1.4-android.7z -offmpeg + echo $QT_HOME cp ffmpeg/ffmpeg-3.1.4-android-armv7a/lib/lib* ${QT_HOME}/5.7/android_${ANDROID_ARCH}/lib/ cp -r ffmpeg/ffmpeg-3.1.4-android-armv7a/include/* ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/ fi export ANDROID_HOME=${SDK} export ANDROID_NDK_HOST=${OS}-${ARCH} -export ANDROID_NDK_PLATFORM=android-23 +export ANDROID_NDK_PLATFORM=${ANDROID_PLATFORM} export ANDROID_NDK_ROOT=${NDK} -export ANDROID_NDK_TOOLCHAIN_PREFIX=arm-linux-androideabi +export ANDROID_NDK_TOOLCHAIN_PREFIX=arm-linux-androideabi export ANDROID_NDK_TOOLCHAIN_VERSION=4.9 -export ANDROID_NDK_TOOLS_PREFIX=arm-linux-androideabi -export ANDROID_SDK_ROOT=${SDK} -export ANDROID_API_VERSION=android-23 +export ANDROID_NDK_TOOLS_PREFIX=arm-linux-androideabi +export ANDROID_SDK_ROOT=${SDK} +export ANDROID_API_VERSION=${ANDROID_PLATFORM} export PATH=$PATH:${ANDROID_HOME}/tools:${JAVA_HOME}/bin if [ ! -d ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/QtAV ]; then - git clone https://github.com/wang-bin/QtAV.git + pwd + git clone https://github.com/wang-bin/QtAV.git cd QtAV mkdir -p ${DISTILLERY_BUILD_DIR}/qtav cd ${DISTILLERY_BUILD_DIR}/qtav @@ -85,4 +97,4 @@ if [ ! -d ${QT_HOME}/5.7/android_${ANDROID_ARCH}/include/QtAV ]; then make install INSTALL_ROOT=android sh sdk_install.sh fi -cd ${DISTILLERY_ROOT_DIR} +cd ${DISTILLERY_ROOT_DIR}
\ No newline at end of file diff --git a/scripts/install_script.sh b/scripts/install_script.sh index b160b3c6..89f9eed0 100644 --- a/scripts/install_script.sh +++ b/scripts/install_script.sh @@ -26,7 +26,7 @@ gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.environmentVar Controller.prototype.ComponentSelectionPageCallback = function() { var widget = gui.currentPageWidget(); - widget.selectAll(); + widget.selectAll(); gui.clickButton(buttons.NextButton); } diff --git a/scripts/tools/build-target-openssl.sh b/scripts/tools/build-target-openssl.sh new file mode 100755 index 00000000..44de606a --- /dev/null +++ b/scripts/tools/build-target-openssl.sh @@ -0,0 +1,392 @@ +#!/bin/bash + +# Copyright (c) 2011-2015 CrystaX. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY CrystaX ''AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CrystaX OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are those of the +# authors and should not be interpreted as representing official policies, either expressed +# or implied, of CrystaX. + +# include common function and variable definitions +. `dirname $0`/prebuilt-common.sh +PROGRAM_PARAMETERS="<src-dir>" +PROGRAM_DESCRIPTION=\ +"Rebuild OpenSSL libraries for the Android NDK. + +This requires a temporary NDK installation containing +toolchain binaries for all target architectures. + +By default, this will try with the current NDK directory, unless +you use the --ndk-dir=<path> option. + +The output will be placed in appropriate sub-directories of +<ndk>/$OPENSSL_SUBDIR, but you can override this with the --out-dir=<path> +option. +" +PACKAGE_DIR= +register_var_option "--package-dir=<path>" PACKAGE_DIR "Put prebuilt tarballs into <path>" +NDK_DIR=$ANDROID_NDK_ROOT +register_var_option "--ndk-dir=<path>" NDK_DIR "Specify NDK root path for the build" + +BUILD_DIR= +OPTION_BUILD_DIR= +register_var_option "--build-dir=<path>" OPTION_BUILD_DIR "Specify temporary build dir" + +ABIS=$PREBUILT_ABIS +register_var_option "--abis=<list>" ABIS "Specify list of target ABIs" + +register_jobs_option + +extract_parameters "$@" + +OPENSSL_SRCDIR=$(echo $PARAMETERS | sed 1q) +if [ -z "$OPENSSL_SRCDIR" ]; then + echo "ERROR: Please provide the path to the OpenSSL source tree. See --help" + exit 1 +fi + +if [ ! -d "$OPENSSL_SRCDIR" ]; then + echo "ERROR: No such directory: '$OPENSSL_SRCDIR'" + exit 1 +fi + +OPENSSL_SRCDIR=$(cd $OPENSSL_SRCDIR && pwd) +OPENSSL_SRC_VERSION=\ +$(cat $OPENSSL_SRCDIR/crypto/opensslv.h | sed -n 's/#[ \t]*define[ \t]*OPENSSL_VERSION_TEXT[ \t]*"OpenSSL[ \t]*\([A-Za-z0-9\.]*\)[A-Za-z0-9 \.]*"/\1/p') + +if [ -z "$OPENSSL_SRC_VERSION" ]; then + echo "ERROR: Can't detect OpenSSL version." 1>&2 + exit 1 +fi + +OPENSSL_DSTDIR=$NDK_DIR/$OPENSSL_SUBDIR/$OPENSSL_SRC_VERSION +mkdir -p $OPENSSL_DSTDIR +fail_panic "Can't create OpenSSL destination directory: $OPENSSL_DSTDIR" + +ABIS=$(commas_to_spaces $ABIS) + +if [ -z "$OPTION_BUILD_DIR" ]; then + BUILD_DIR="$NDK_TMPDIR/build-openssl" +else + eval BUILD_DIR=$OPTION_BUILD_DIR +fi + +rm -rf "$BUILD_DIR" +mkdir -p "$BUILD_DIR" +fail_panic "Can't create build directory: $BUILD_DIR" + + +# $1: ABI +# $2: build directory +build_openssl_for_abi () +{ + dump "Building OpenSSL-$OPENSSL_SRC_VERSION for $ABI" + + local ABI="$1" + local BUILDDIR="$2" + + local ARCH + case $ABI in + armeabi*) + ARCH=arm + ;; + arm64*) + ARCH=arm64 + ;; + x86|x86_64|mips|mips64) + ARCH=$ABI + ;; + *) + echo "ERROR: Unknown ABI: '$ABI'" 1>&2 + exit 1 + esac + + local HOST + case $ABI in + armeabi*) + HOST=arm-linux-androideabi + ;; + arm64*) + HOST=aarch64-linux-android + ;; + x86) + HOST=i686-linux-android + ;; + x86_64) + HOST=x86_64-linux-android + ;; + mips) + HOST=mipsel-linux-android + ;; + mips64) + HOST=mips64el-linux-android + ;; + *) + echo "ERROR: Unknown ABI: '$ABI'" 1>&2 + exit 1 + esac + + local APILEVEL + case $ABI in + armeabi*|x86|mips) + APILEVEL=9 + ;; + arm64*|x86_64|mips64) + APILEVEL=21 + ;; + *) + echo "ERROR: Unknown ABI: '$ABI'" 1>&2 + exit 1 + esac + + local TOOLCHAIN + case $ABI in + armeabi*) + TOOLCHAIN=arm-linux-androideabi + ;; + x86) + TOOLCHAIN=x86 + OPENSSL_TARGET=linux-elf + ;; + mips) + TOOLCHAIN=mipsel-linux-android + ;; + arm64-v8a) + TOOLCHAIN=aarch64-linux-android + ;; + x86_64) + TOOLCHAIN=x86_64 + ;; + mips64) + TOOLCHAIN=mips64el-linux-android + ;; + *) + echo "ERROR: Unknown ABI: '$ABI'" 1>&2 + exit 1 + esac + + case $ABI in + armeabi) + CFLAGS="-march=armv5te -mtune=xscale -msoft-float" + ;; + armeabi-v7a) + CFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp" + ;; + armeabi-v7a-hard) + CFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mhard-float" + ;; + *) + CFLAGS="" + esac + + case $ABI in + armeabi*) + CFLAGS="$CFLAGS -mthumb" + esac + + + local LDFLAGS="" + if [ "$ABI" = "armeabi-v7a-hard" ]; then + LDFLAGS="$LDFLAGS -Wl,--no-warn-mismatch" + fi + + local TCPREFIX=$NDK_DIR/toolchains/${TOOLCHAIN}-4.9/prebuilt/$HOST_TAG + + local BIN_WRAP_DIR="$BUILDDIR/bin-ndk" + mkdir -p "$BIN_WRAP_DIR" + fail_panic "Can't create directory: $BIN_WRAP_DIR" + + # gcc wrapper + local MY_GCC="$BIN_WRAP_DIR/${HOST}-gcc" + { + echo '#!/bin/bash -e' + echo "MY_CFLAGS=\"$CFLAGS\"" + echo "MY_LDFLAGS=\"$LDFLAGS -L$NDK_DIR/sources/crystax/libs/$ABI\"" + echo 'ARGS=' + echo 'BUILD_DSO=yes' + echo 'for p in "$@"; do' + echo ' ARG_IS_SONAME=no' + echo ' ARG_IS_RPATH=no' + echo ' case $p in' + echo ' -c)' + echo ' BUILD_DSO=no' + echo ' ;;' + echo ' -Wl,-rpath,*)' + echo ' ARG_IS_RPATH=yes' + echo ' ;;' + echo ' -Wl,-soname=*)' + echo ' ARG_IS_SONAME=yes' + echo ' ;;' + echo ' esac' + echo ' if [ "$ARG_IS_RPATH" = "yes" ]; then' + echo ' p=' + echo ' fi' + echo ' if [ "$ARG_IS_SONAME" = "yes" ]; then' + echo ' p=$(echo $p | sed -n "s/\(.*\.so\).*/\1/p")' + echo ' fi' + echo ' if [ -n "$p" ]; then' + echo ' ARGS="$ARGS $p"' + echo ' fi' + echo 'done' + echo 'if [ "$BUILD_DSO" = "yes" ]; then' + echo ' ARGS="$ARGS $MY_LDFLAGS"' + echo 'else' + echo ' ARGS="$MY_CFLAGS $ARGS"' + echo 'fi' + echo 'set -x' + echo "exec $TCPREFIX/bin/${HOST}-gcc --sysroot=$NDK_DIR/platforms/android-$APILEVEL/arch-$ARCH \$ARGS" + } >$MY_GCC + fail_panic "Can't create gcc wrapper" + chmod +x $MY_GCC + fail_panic "Can't chmod +x gcc wrapper" + + # script to init obj-tree + local OBJTREE_WRAPPER=$BUILDDIR/mkobjtree.sh + { + echo '#!/bin/bash -e' + echo 'DIR_HERE=$(cd $(dirname $0) && pwd)' + echo "OPENSSL_SOURCE=\"$OPENSSL_SRCDIR\"" + echo 'mkdir -p $DIR_HERE/objtree' + echo 'cd $DIR_HERE/objtree' + echo 'echo "Preparing OpenSSL obj-tree in $(pwd) ..."' + echo '(cd $OPENSSL_SOURCE; find . -type f) | while read F; do' + echo ' mkdir -p $(dirname $F)' + echo ' rm -f $F' + echo ' if [ "$F" = "./crypto/opensslconf.h" ]; then' + echo ' cp -fpH $OPENSSL_SOURCE/crypto/opensslconf.h ./crypto' + echo ' elif [ "$F" = "./crypto/cryptlib.h" ]; then' + echo ' cp -fpH $OPENSSL_SOURCE/crypto/cryptlib.h ./crypto' + echo ' else' + echo ' ln -s $OPENSSL_SOURCE/$F $F' + echo ' fi' + echo 'done' + echo 'rm -rf engines' + } >$OBJTREE_WRAPPER + fail_panic "Can't create OpenSSL objtree wrapper" + chmod +x $OBJTREE_WRAPPER + fail_panic "Can't chmod +x OpenSSL objtree wrapper" + + local OPENSSL_TARGET + case $ABI in + x86) + OPENSSL_TARGET=linux-elf + ;; + x86_64) + OPENSSL_TARGET=linux-x86_64 + ;; + armeabi*) + OPENSSL_TARGET=linux-armv4 + ;; + arm64-v8a) + OPENSSL_TARGET=linux-generic64 + ;; + mips) + OPENSSL_TARGET=linux-generic32 + ;; + mips64) + OPENSSL_TARGET=linux-generic64 + ;; + *) + echo "ERROR: Unknown ABI: '$ABI'" 1>&2 + exit 1 + esac + local OPENSSL_OPTIONS='shared zlib-dynamic no-hw no-dso -DOPENSSL_NO_DEPRECATED' + + # script for build + local BUILD_WRAPPER=$BUILDDIR/build.sh + { + echo '#!/bin/bash -e' + echo 'DIR_HERE=$(cd $(dirname $0) && pwd)' + echo "export PATH=\"$BIN_WRAP_DIR:$TCPREFIX/bin:\$PATH\"" + echo 'cd $DIR_HERE' + echo './mkobjtree.sh' + echo 'cd objtree' + echo "perl ./Configure --openssldir=/system/etc/security --prefix=/pkg --cross-compile-prefix=\"${HOST}-\" $OPENSSL_OPTIONS $OPENSSL_TARGET" + echo "perl -p -i -e 's/^(#\\s*define\\s+ENGINESDIR\\s+).*$/\$1NULL/g' crypto/opensslconf.h" + echo "perl -p -i -e 's/^(#\\s*define\\s+X509_CERT_DIR\\s+OPENSSLDIR\\s+).*$/\$1\"\\/cacerts\"/g' crypto/cryptlib.h" + echo 'make' + echo "make INSTALL_PREFIX=$BUILDDIR/install install" + } >$BUILD_WRAPPER + fail_panic "Can't create OpenSSL build wrapper" + chmod +x $BUILD_WRAPPER + fail_panic "Can't chmod +x OpenSSL build wrapper" + + run $BUILD_WRAPPER + fail_panic "Can't make OpenSSL-$OPENSSL_SRC_VERSION for $ABI" + + local OPENSSL_ABI_CONFIG_MAKE="$BUILDDIR/install/pkg/include/openssl/opensslconf.h" + local OPENSSL_ABI_CONFIG="$BUILDDIR/install/pkg/include/openssl/opensslconf_$(echo $ABI | tr '-' '_').h" + mv $OPENSSL_ABI_CONFIG_MAKE $OPENSSL_ABI_CONFIG + fail_panic "Can't rename $OPENSSL_ABI_CONFIG_MAKE in $OPENSSL_ABI_CONFIG" + + local OPENSSL_HEADERS_DSTDIR="$OPENSSL_DSTDIR/include/openssl" + if [ "$OPENSSL_HEADERS_INSTALLED" != "yes" ]; then + log "Install OpenSSL headers into $OPENSSL_HEADERS_DSTDIR" + run rm -Rf $OPENSSL_HEADERS_DSTDIR && run mkdir -p $OPENSSL_HEADERS_DSTDIR + fail_panic "Can't create directory: $OPENSSL_HEADERS_DSTDIR" + { + echo '#if defined(__ARM_ARCH_5TE__)' + echo '#include "opensslconf_armeabi.h"' + echo '#elif defined(__ARM_ARCH_7A__) && !defined(__ARM_PCS_VFP)' + echo '#include "opensslconf_armeabi_v7a.h"' + echo '#elif defined(__ARM_ARCH_7A__) && defined(__ARM_PCS_VFP)' + echo '#include "opensslconf_armeabi_v7a_hard.h"' + echo '#elif defined(__aarch64__)' + echo '#include "opensslconf_arm64_v8a.h"' + echo '#elif defined(__i386__)' + echo '#include "opensslconf_x86.h"' + echo '#elif defined(__x86_64__)' + echo '#include "opensslconf_x86_64.h"' + echo '#elif defined(__mips__) && !defined(__mips64)' + echo '#include "opensslconf_mips.h"' + echo '#elif defined(__mips__) && defined(__mips64)' + echo '#include "opensslconf_mips64.h"' + echo '#else' + echo '#error "Unsupported ABI"' + echo '#endif' + } >"$OPENSSL_HEADERS_DSTDIR/opensslconf.h" + fail_panic "Can't generate $OPENSSL_HEADERS_DSTDIR/opensslconf.h" + run cp -p $BUILDDIR/install/pkg/include/openssl/*.h $OPENSSL_HEADERS_DSTDIR + fail_panic "Can't install OpenSSL headers" + OPENSSL_HEADERS_INSTALLED=yes + export OPENSSL_HEADERS_INSTALLED + else + run cp -p $OPENSSL_ABI_CONFIG $OPENSSL_HEADERS_DSTDIR + fail_panic "Can't install $OPENSSL_ABI_CONFIG" + fi + + log "Install OpenSSL binaries into $OPENSSL_DSTDIR" + run rm -Rf $OPENSSL_DSTDIR/libs/$ABI && \ + run mkdir -p $OPENSSL_DSTDIR/libs/$ABI && \ + run cp -p $BUILDDIR/install/pkg/lib/libcrypto.a \ + $BUILDDIR/install/pkg/lib/libcrypto.so \ + $BUILDDIR/install/pkg/lib/libssl.a \ + $BUILDDIR/install/pkg/lib/libssl.so \ + $OPENSSL_DSTDIR/libs/$ABI + fail_panic "Can't install OpenSSL binaries" +} + +for ABI in $ABIS; do + build_openssl_for_abi $ABI "$BUILD_DIR/$ABI" +done +log "Done!" diff --git a/scripts/tools/dev-defaults.sh b/scripts/tools/dev-defaults.sh new file mode 100644 index 00000000..d0ee700e --- /dev/null +++ b/scripts/tools/dev-defaults.sh @@ -0,0 +1,355 @@ +# Default values used by several dev-scripts. +# + +# Current list of platform levels we support +# +# Note: levels 6 and 7 are omitted since they have the same native +# APIs as level 5. Same for levels 10, 11 and 12 +# +API_LEVELS="3 4 5 8 9 12 13 14 15 16 17 18 19 21" + +FIRST_API64_LEVEL=21 + +# Default ABIs for the target prebuilt binaries. +PREBUILT_ABIS="armeabi armeabi-v7a x86 mips armeabi-v7a-hard arm64-v8a x86_64 mips64" + +# Location of the libcrystax sources, relative to the NDK root directory +CRYSTAX_SUBDIR=sources/crystax + +# Location of the STLport sources, relative to the NDK root directory +STLPORT_SUBDIR=sources/cxx-stl/stlport + +# Location of the GAbi++ sources, relative to the NDK root directory +GABIXX_SUBDIR=sources/cxx-stl/gabi++ + +# Location of the GNU libstdc++ headers and libraries, relative to the NDK +# root directory. +GNUSTL_SUBDIR=sources/cxx-stl/gnu-libstdc++ + +# Location of the LLVM libc++ headers and libraries, relative to the NDK +# root directory. +LIBCXX_SUBDIR=sources/cxx-stl/llvm-libc++ + +# Location of the LLVM libc++abi headers, relative to the NDK # root directory. +LIBCXXABI_SUBDIR=sources/cxx-stl/llvm-libc++abi/libcxxabi + +# Location of the GNUstep libobjc2 headers and libraries, relative to the NDK root directory +GNUSTEP_OBJC2_SUBDIR=sources/objc/gnustep-libobjc2 + +# Location of the Cocotron headers and libraries, relative to the NDK root directory +COCOTRON_SUBDIR=sources/objc/cocotron/0.1.0 + +# Location of the libportable sources, relative to the NDK root directory +LIBPORTABLE_SUBDIR=sources/android/libportable + +# Location of the gccunwind sources, relative to the NDK root directory +GCCUNWIND_SUBDIR=sources/android/gccunwind + +# Location of the compiler-rt sources, relative to the NDK root directory +COMPILER_RT_SUBDIR=sources/android/compiler-rt + +# Location of the boost sources, relative to the NDK root directory +BOOST_SUBDIR=sources/boost +BOOST_VERSIONS="1.59.0" + +# Location of the ICU sources, relative to the NDK root directory +ICU_SUBDIR=sources/icu +ICU_VERSIONS="56.1" + +# Location of the sqlite3 libraries, relative to the NDK root directory +SQLITE3_SUBDIR=sources/sqlite/3 + +# Location of the python libraries, relative to the NDK root directory +PYTHON_SUBDIR=sources/python +PYTHON_VERSIONS="2.7 3.5" + +# Location of the OpenSSL libraries, relative to the NDK root directory +OPENSSL_SUBDIR=sources/openssl +OPENSSL_VERSIONS="1.0.1p" +DEFAULT_OPENSSL_VERSION=$(echo $OPENSSL_VERSIONS | tr ' ' '\n' | head -n 1) + +# Location of the libpng libraries, relative to the NDK root directory +LIBPNG_SUBDIR=sources/libpng +LIBPNG_VERSIONS="1.6.19" + +# Location of the libjpeg libraries, relative to the NDK root directory +LIBJPEG_SUBDIR=sources/libjpeg +LIBJPEG_VERSIONS="9a" + +# Location of the libjpeg-turbo libraries, relative to the NDK root directory +LIBJPEGTURBO_SUBDIR=sources/libjpeg-turbo +LIBJPEGTURBO_VERSIONS="1.4.2" + +# Location of the libtiff libraries, relative to the NDK root directory +LIBTIFF_SUBDIR=sources/libtiff +LIBTIFF_VERSIONS="4.0.6" + +# Location of the gccunwind sources, relative to the NDK root directory +GCCUNWIND_SUBDIR=sources/android/gccunwind + +# Location of the support sources for libc++, relative to the NDK root directory +# zuav: todo: remove all references to the var +SUPPORT_SUBDIR=sources/android/support + +# The date to use when downloading toolchain sources from AOSP servers +# Leave it empty for tip of tree. +TOOLCHAIN_GIT_DATE=now + +# The space-separated list of all GCC versions we support in this NDK +DEFAULT_GCC_VERSION_LIST="4.9 5" + +DEFAULT_GCC_VERSION=$(echo $DEFAULT_GCC_VERSION_LIST | tr ' ' '\n' | head -n 1) + +DEFAULT_GCC32_VERSION=$DEFAULT_GCC_VERSION +DEFAULT_GCC64_VERSION=$DEFAULT_GCC_VERSION +FIRST_GCC32_VERSION=4.9 +FIRST_GCC64_VERSION=4.9 +DEFAULT_LLVM_GCC32_VERSION=$DEFAULT_GCC_VERSION +DEFAULT_LLVM_GCC64_VERSION=$DEFAULT_GCC_VERSION + +DEFAULT_BINUTILS_VERSION=2.25 +DEFAULT_GDB_VERSION=7.10 +DEFAULT_MPFR_VERSION=3.1.2 +DEFAULT_GMP_VERSION=6.0.0 +DEFAULT_MPC_VERSION=1.0.3 +DEFAULT_CLOOG_VERSION=0.18.0 +DEFAULT_CLOOG_VERSION_FOR_GCC5=0.18.3 +DEFAULT_ISL_VERSION=0.11.1 +DEFAULT_PPL_VERSION=1.1 +DEFAULT_PYTHON_VERSION=2.7.5 +DEFAULT_PERL_VERSION=5.16.2 +DEFAULT_EXPAT_VERSION=2.0.1 + +# Default platform to build target binaries against. +DEFAULT_PLATFORM=android-9 + +# The list of default CPU architectures we support +DEFAULT_ARCHS="arm x86 mips arm64 x86_64 mips64" + +# Default toolchain names and prefix +# +# This is used by get_default_toolchain_name_for_arch and get_default_toolchain_prefix_for_arch +# defined below +DEFAULT_ARCH_TOOLCHAIN_NAME_arm=arm-linux-androideabi +DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm=arm-linux-androideabi + +DEFAULT_ARCH_TOOLCHAIN_NAME_arm64=aarch64-linux-android +DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm64=aarch64-linux-android + +DEFAULT_ARCH_TOOLCHAIN_NAME_x86=x86 +DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86=i686-linux-android + +DEFAULT_ARCH_TOOLCHAIN_NAME_x86_64=x86_64 +DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86_64=x86_64-linux-android + +DEFAULT_ARCH_TOOLCHAIN_NAME_mips=mipsel-linux-android +DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips=mipsel-linux-android + +DEFAULT_ARCH_TOOLCHAIN_NAME_mips64=mips64el-linux-android +DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips64=mips64el-linux-android + +# The space-separated list of all LLVM versions we support in NDK +DEFAULT_LLVM_VERSION_LIST="3.6 3.7" + +# The default LLVM version (first item in the list) +DEFAULT_LLVM_VERSION=$(echo "$DEFAULT_LLVM_VERSION_LIST" | tr ' ' '\n' | head -n 1) + +# The default URL to download the LLVM tar archive +DEFAULT_LLVM_URL="http://llvm.org/releases" + +# The list of default host NDK systems we support +DEFAULT_SYSTEMS="linux-x86 windows darwin-x86" + +# The default issue tracker URL +DEFAULT_ISSUE_TRACKER_URL="https://tracker.crystax.net/projects/ndk" + +# Return the default gcc version for a given architecture +# $1: Architecture name (e.g. 'arm') +# Out: default arch-specific gcc version +get_default_gcc_version_for_arch () +{ + case $1 in + *64) echo $DEFAULT_GCC64_VERSION ;; + *) echo $DEFAULT_GCC32_VERSION ;; + esac +} + +# Return the first gcc version for a given architecture +# $1: Architecture name (e.g. 'arm') +# Out: default arch-specific gcc version +get_first_gcc_version_for_arch () +{ + case $1 in + *64) echo $FIRST_GCC64_VERSION ;; + *) echo $FIRST_GCC32_VERSION ;; + esac +} + +# Return default NDK ABI for a given architecture name +# $1: Architecture name +# Out: ABI name +get_default_abi_for_arch () +{ + local RET + case $1 in + arm) + RET="armeabi" + ;; + arm64) + RET="arm64-v8a" + ;; + x86|x86_64|mips|mips64) + RET="$1" + ;; + mips32r6) + RET="mips" + ;; + *) + 2> echo "ERROR: Unsupported architecture name: $1, use one of: arm arm64 x86 x86_64 mips mips64" + exit 1 + ;; + esac + echo "$RET" +} + + +# Retrieve the list of default ABIs supported by a given architecture +# $1: Architecture name +# Out: space-separated list of ABI names +get_default_abis_for_arch () +{ + local RET + case $1 in + arm) + RET="armeabi armeabi-v7a armeabi-v7a-hard" + ;; + arm64) + RET="arm64-v8a" + ;; + x86|x86_64|mips|mips32r6|mips64) + RET="$1" + ;; + *) + 2> echo "ERROR: Unsupported architecture name: $1, use one of: arm arm64 x86 x86_64 mips mips64" + exit 1 + ;; + esac + echo "$RET" +} + +# Return toolchain name for given architecture and GCC version +# $1: Architecture name (e.g. 'arm') +# $2: optional, GCC version (e.g. '4.8') +# Out: default arch-specific toolchain name (e.g. 'arm-linux-androideabi-$GCC_VERSION') +# Return empty for unknown arch +get_toolchain_name_for_arch () +{ + if [ ! -z "$2" ] ; then + eval echo \"\${DEFAULT_ARCH_TOOLCHAIN_NAME_$1}-$2\" + else + eval echo \"\${DEFAULT_ARCH_TOOLCHAIN_NAME_$1}\" + fi +} + +# Return the default toolchain name for a given architecture +# $1: Architecture name (e.g. 'arm') +# Out: default arch-specific toolchain name (e.g. 'arm-linux-androideabi-$GCCVER') +# Return empty for unknown arch +get_default_toolchain_name_for_arch () +{ + local GCCVER=$(get_default_gcc_version_for_arch $1) + eval echo \"\${DEFAULT_ARCH_TOOLCHAIN_NAME_$1}-$GCCVER\" +} + +# Return the default toolchain program prefix for a given architecture +# $1: Architecture name +# Out: default arch-specific toolchain prefix (e.g. arm-linux-androideabi) +# Return empty for unknown arch +get_default_toolchain_prefix_for_arch () +{ + eval echo "\$DEFAULT_ARCH_TOOLCHAIN_PREFIX_$1" +} + +# Get the list of all toolchain names for a given architecture +# $1: architecture (e.g. 'arm') +# $2: comma separated versions (optional) +# Out: list of toolchain names for this arch (e.g. arm-linux-androideabi-4.8 arm-linux-androideabi-4.9) +# Return empty for unknown arch +get_toolchain_name_list_for_arch () +{ + local PREFIX VERSION RET ADD FIRST_GCC_VERSION VERSIONS + PREFIX=$(eval echo \"\$DEFAULT_ARCH_TOOLCHAIN_NAME_$1\") + if [ -z "$PREFIX" ]; then + return 0 + fi + RET="" + FIRST_GCC_VERSION=$(get_first_gcc_version_for_arch $1) + ADD="" + VERSIONS=$(commas_to_spaces $2) + if [ -z "$VERSIONS" ]; then + VERSIONS=$DEFAULT_GCC_VERSION_LIST + else + ADD="yes" # include everything we passed explicitly + fi + for VERSION in $VERSIONS; do + if [ -z "$ADD" -a "$VERSION" = "$FIRST_GCC_VERSION" ]; then + ADD="yes" + fi + if [ -z "$ADD" ]; then + continue + fi + RET=$RET" $PREFIX-$VERSION" + done + RET=${RET## } + echo "$RET" +} + +# Return the binutils version to be used by default when +# building a given version of GCC. This is needed to ensure +# we use binutils-2.19 when building gcc-4.4.3 for ARM and x86, +# and later binutils in other cases (mips, or gcc-4.6+). +# +# Note that technically, we could use latest binutils for all versions of +# GCC, however, in NDK r7, we did build GCC 4.4.3 with binutils-2.20.1 +# and this resulted in weird C++ debugging bugs. For NDK r7b and higher, +# binutils was reverted to 2.19, to ensure at least +# feature/bug compatibility. +# +# $1: toolchain with version number (e.g. 'arm-linux-androideabi-4.8') +# +get_default_binutils_version_for_gcc () +{ + echo "$DEFAULT_BINUTILS_VERSION" +} + +# Return the binutils version to be used by default when +# building a given version of llvm. For llvm-3.4 or later, +# we use binutils-2.23+ to ensure the LLVMgold.so could be +# built properly. For llvm-3.3, we use binutils-2.21 as default. +# +# $1: toolchain with version numer (e.g. 'llvm-3.3') +# +get_default_binutils_version_for_llvm () +{ + echo "$DEFAULT_BINUTILS_VERSION" +} + +# Return the gdb version to be used by default when building a given +# version of GCC. +# +# $1: toolchain with version number (e.g. 'arm-linux-androideabi-4.8') +# +get_default_gdb_version_for_gcc () +{ + echo "$DEFAULT_GDB_VERSION" +} + +# Return the gdbserver version to be used by default when building a given +# version of GCC. +# +# $1: toolchain with version number (e.g. 'arm-linux-androideabi-4.8') +# +get_default_gdbserver_version_for_gcc () +{ + echo "$DEFAULT_GDB_VERSION" +} diff --git a/scripts/tools/ndk-common.sh b/scripts/tools/ndk-common.sh new file mode 100644 index 00000000..f6b447cf --- /dev/null +++ b/scripts/tools/ndk-common.sh @@ -0,0 +1,1048 @@ +# Copyright (C) 2009, 2014, 2015 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. +# + +# A collection of shell function definitions used by various build scripts +# in the Android NDK (Native Development Kit) +# + +# Get current script name into PROGNAME +PROGNAME=`basename $0` + +# Set package cache directory +NDK_CACHE_DIR="/var/tmp/ndk-cache-$USER" +if [ ! -d "$NDK_CACHE_DIR" ]; then + mkdir -p "$NDK_CACHE_DIR" + if [ $? != 0 ]; then + echo "Failed to create cache dir $NDK_CACHE_DIR" + exit 1 + fi +fi + +export TMPDIR=/tmp/ndk-$USER + +OS=`uname -s` +if [ "$OS" == "Darwin" -a -z "$MACOSX_DEPLOYMENT_TARGET" ]; then + export MACOSX_DEPLOYMENT_TARGET="10.8" +fi + +# Find the Android NDK root, assuming we are invoked from a script +# within its directory structure. +# +# $1: Variable name that will receive the path +# $2: Path of invoking script +find_ndk_root () +{ + # Try to auto-detect the NDK root by walking up the directory + # path to the current script. + local PROGDIR="`dirname \"$2\"`" + while [ -n "1" ] ; do + if [ -d "$PROGDIR/build/core" ] ; then + break + fi + if [ -z "$PROGDIR" -o "$PROGDIR" = '/' ] ; then + return 1 + fi + PROGDIR="`cd \"$PROGDIR/..\" && pwd`" + done + eval $1="$PROGDIR" +} + +# Put location of Android NDK into ANDROID_NDK_ROOT and +# perform a tiny amount of sanity check +# +if [ -z "$ANDROID_NDK_ROOT" ] ; then + find_ndk_root ANDROID_NDK_ROOT "$0" + if [ $? != 0 ]; then + echo "Please define ANDROID_NDK_ROOT to point to the root of your" + echo "Android NDK installation." + exit 1 + fi +fi + +echo "$ANDROID_NDK_ROOT" | grep -q -e " " +if [ $? = 0 ] ; then + echo "ERROR: The Android NDK installation path contains a space !" + echo "Please install to a different location." + exit 1 +fi + +if [ ! -d $ANDROID_NDK_ROOT ] ; then + echo "ERROR: Your ANDROID_NDK_ROOT variable does not point to a directory." + exit 1 +fi + +if [ ! -f $ANDROID_NDK_ROOT/build/tools/ndk-common.sh ] ; then + echo "ERROR: Your ANDROID_NDK_ROOT variable does not point to a valid directory." + exit 1 +fi + +## Use DRYRUN to find out top-level commands. +DRYRUN=${DRYRUN-no} + +## Logging support +## +VERBOSE=${VERBOSE-yes} + + +# If NDK_LOGFILE is defined in the environment, use this as the log file +TMPLOG= +if [ -n "$NDK_LOGFILE" ] ; then + mkdir -p `dirname "$NDK_LOGFILE"` && touch "$NDK_LOGFILE" + TMPLOG="$NDK_LOGFILE" +fi + +# Setup a log file where all log() output will be sent +# +# $1: log file path (optional) +# +setup_default_log_file () +{ + if [ -n "$NDK_LOGFILE" ] ; then + return + fi + if [ -n "$1" ] ; then + NDK_LOGFILE="$1" + else + NDK_LOGFILE=$TMPDIR/ndk-log-$$.txt + fi + export NDK_LOGFILE + TMPLOG="$NDK_LOGFILE" + rm -rf "$TMPLOG" && mkdir -p `dirname "$TMPLOG"` && touch "$TMPLOG" + echo "To follow build in another terminal, please use: tail -F $TMPLOG" +} + +dump () +{ + if [ -n "$TMPLOG" ] ; then + echo "$@" >> $TMPLOG + fi + echo "$@" +} + +dump_n () +{ + if [ -n "$TMPLOG" ] ; then + printf %s "$@" >> $TMPLOG + fi + printf %s "$@" +} + +log () +{ + if [ "$VERBOSE" = "yes" ] ; then + echo "$@" + else + if [ -n "$TMPLOG" ] ; then + echo "$@" >> $TMPLOG + fi + fi +} + +log_n () +{ + if [ "$VERBOSE" = "yes" ] ; then + printf %s "$@" + else + if [ -n "$TMPLOG" ] ; then + printf %s "$@" >> $TMPLOG + fi + fi +} + +run () +{ + if [ "$DRYRUN" = "yes" ] ; then + echo "## SKIP COMMAND: $@" + elif [ "$VERBOSE" = "yes" ] ; then + echo "## COMMAND: $@" + "$@" 2>&1 + else + if [ -n "$TMPLOG" ] ; then + echo "## COMMAND: $@" >> $TMPLOG + "$@" >>$TMPLOG 2>&1 + else + "$@" > /dev/null 2>&1 + fi + fi +} + +panic () +{ + dump "ERROR: $@" + exit 1 +} + +fail_panic () +{ + if [ $? != 0 ] ; then + dump "ERROR: $@" + exit 1 + fi +} + +fail_warning () +{ + if [ $? != 0 ] ; then + dump "WARNING: $@" + fi +} + + +## Utilities +## + +# 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`" +} + +# convert to uppercase +# assumes tr is installed on the platform ? +# +to_uppercase () +{ + echo $1 | tr "[:lower:]" "[:upper:]" +} + +## First, we need to detect the HOST CPU, because proper HOST_ARCH detection +## requires platform-specific tricks. +## +HOST_EXE="" +HOST_OS=`uname -s` +case "$HOST_OS" in + Darwin) + HOST_OS=darwin + ;; + Linux) + # note that building 32-bit binaries on x86_64 is handled later + HOST_OS=linux + ;; + FreeBsd) # note: this is not tested + HOST_OS=freebsd + ;; + CYGWIN*|*_NT-*) + HOST_OS=windows + HOST_EXE=.exe + if [ "x$OSTYPE" = xcygwin ] ; then + HOST_OS=cygwin + fi + ;; +esac + +#log "HOST_OS=$HOST_OS" +#log "HOST_EXE=$HOST_EXE" + +## Now find the host architecture. This must correspond to the bitness of +## the binaries we're going to run with this NDK. Certain platforms allow +## you to use a 64-bit kernel with a 32-bit userland, and unfortunately +## commands like 'uname -m' only report the kernel bitness. +## +HOST_ARCH=`uname -m` +case "$HOST_ARCH" in + i?86) HOST_ARCH=x86 + # "uname -m" reports i386 on Snow Leopard even though its architecture is + # 64-bit. In order to use it to build 64-bit toolchains we need to fix the + # reporting anomoly here. + if [ "$HOST_OS" = darwin ] ; then + if ! echo __LP64__ | (CCOPTS= gcc -E - 2>/dev/null) | grep -q __LP64__ ; then + # or if gcc -dM -E - < /dev/null | grep -q __LP64__; then + HOST_ARCH=x86_64 + fi + fi + ;; + amd64) HOST_ARCH=x86_64 + ;; + powerpc) HOST_ARCH=ppc + ;; +esac + +HOST_FILE_PROGRAM="file" +case "$HOST_OS-$HOST_ARCH" in + linux-x86_64|darwin-x86_64) + ## On Linux or Darwin, a 64-bit kernel doesn't mean that the user-land + ## is always 32-bit, so use "file" to determine the bitness of the shell + ## that invoked us. The -L option is used to de-reference symlinks. + ## + ## Note that on Darwin, a single executable can contain both x86 and + ## x86_64 machine code, so just look for x86_64 (darwin) or x86-64 (Linux) + ## in the output. + ## + ## Also note that some versions of 'file' in MacPort may report erroneous + ## result. See http://b.android.com/53769. Use /usr/bin/file if exists. + if [ "$HOST_OS" = "darwin" ]; then + SYSTEM_FILE_PROGRAM="/usr/bin/file" + test -x "$SYSTEM_FILE_PROGRAM" && HOST_FILE_PROGRAM="$SYSTEM_FILE_PROGRAM" + fi + "$HOST_FILE_PROGRAM" -L "$SHELL" | grep -q "x86[_-]64" + if [ $? != 0 ]; then + # $SHELL is not a 64-bit executable, so assume our userland is too. + log "Detected 32-bit userland on 64-bit kernel system!" + HOST_ARCH=x86 + fi + ;; +esac + +#log "HOST_ARCH=$HOST_ARCH" + +# at this point, the supported values for HOST_ARCH are: +# x86 +# x86_64 +# ppc +# +# other values may be possible but haven't been tested +# +# at this point, the value of HOST_OS should be one of the following: +# linux +# darwin +# windows (MSys) +# cygwin +# +# Note that cygwin is treated as a special case because it behaves very differently +# for a few things. Other values may be possible but have not been tested +# + +# define HOST_TAG as a unique tag used to identify both the host OS and CPU +# supported values are: +# +# linux-x86 +# linux-x86_64 +# darwin-x86 +# darwin-x86_64 +# darwin-ppc +# windows +# windows-x86_64 +# +# other values are possible but were not tested. +# +compute_host_tag () +{ + HOST_TAG=${HOST_OS}-${HOST_ARCH} + # Special case for windows-x86 => windows + case $HOST_TAG in + windows-x86|cygwin-x86) + HOST_TAG="windows" + ;; + esac + #log "HOST_TAG=$HOST_TAG" +} + +compute_host_tag + +# Compute the number of host CPU cores an HOST_NUM_CPUS +# +case "$HOST_OS" in + linux) + HOST_NUM_CPUS=`cat /proc/cpuinfo | grep processor | wc -l` + ;; + darwin|freebsd) + HOST_NUM_CPUS=`sysctl -n hw.ncpu` + ;; + windows|cygwin) + HOST_NUM_CPUS=$NUMBER_OF_PROCESSORS + if [ -z "$HOST_NUM_CPUS" ]; then + # In case we're running shell from Cygwin SSH, we have no $NUMBER_OF_PROCESSORS + # In such case detect it in another way + HOST_NUM_CPUS=`cmd /c "echo %NUMBER_OF_PROCESSORS%" 2>/dev/null | tr -d '\r'` + fi + ;; + *) # let's play safe here + HOST_NUM_CPUS=1 +esac + +test -z "$HOST_NUM_CPUS" && HOST_NUM_CPUS=1 +test $HOST_NUM_CPUS -lt 1 && HOST_NUM_CPUS=1 + +#log "HOST_NUM_CPUS=$HOST_NUM_CPUS" + +# If BUILD_NUM_CPUS is not already defined in your environment, +# define it as the double of HOST_NUM_CPUS. This is used to +# run Make commands in parralles, as in 'make -j$BUILD_NUM_CPUS' +# +if [ -z "$BUILD_NUM_CPUS" ] ; then + BUILD_NUM_CPUS=`expr $HOST_NUM_CPUS \* 2` +fi + +#log "BUILD_NUM_CPUS=$BUILD_NUM_CPUS" + + +## HOST TOOLCHAIN SUPPORT +## + +# force the generation of 32-bit binaries on 64-bit systems +# +FORCE_32BIT=no +force_32bit_binaries () +{ + if [ "$HOST_ARCH" = x86_64 ] ; then + log "Forcing generation of 32-bit host binaries on $HOST_ARCH" + FORCE_32BIT=yes + HOST_ARCH=x86 + log "HOST_ARCH=$HOST_ARCH" + compute_host_tag + fi +} + +# On Windows, cygwin binaries will be generated by default, but +# you can force mingw ones that do not link to cygwin.dll if you +# call this function. +# +disable_cygwin () +{ + if [ $HOST_OS = cygwin ] ; then + log "Disabling cygwin binaries generation" + CFLAGS="$CFLAGS -mno-cygwin" + LDFLAGS="$LDFLAGS -mno-cygwin" + HOST_OS=windows + compute_host_tag + fi +} + +# Various probes are going to need to run a small C program +mkdir -p $TMPDIR/tmp/tests + +TMPC=$TMPDIR/tmp/tests/test-$$.c +TMPO=$TMPDIR/tmp/tests/test-$$.o +TMPE=$TMPDIR/tmp/tests/test-$$$EXE +TMPL=$TMPDIR/tmp/tests/test-$$.log + +# cleanup temporary files +clean_temp () +{ + rm -f $TMPC $TMPO $TMPL $TMPE +} + +# cleanup temp files then exit with an error +clean_exit () +{ + clean_temp + exit 1 +} + +# this function will setup the compiler and linker and check that they work as advertised +# note that you should call 'force_32bit_binaries' before this one if you want it to +# generate 32-bit binaries on 64-bit systems (that support it). +# +setup_toolchain () +{ + if [ -z "$CC" ] ; then + CC=gcc + fi + if [ -z "$CXX" ] ; then + CXX=g++ + fi + if [ -z "$CXXFLAGS" ] ; then + CXXFLAGS="$CFLAGS" + fi + if [ -z "$LD" ] ; then + LD="$CC" + fi + + log "Using '$CC' as the C compiler" + + # check that we can compile a trivial C program with this compiler + mkdir -p $(dirname "$TMPC") + cat > $TMPC <<EOF +int main(void) {} +EOF + + if [ "$FORCE_32BIT" = yes ] ; then + CC="$CC -m32" + CXX="$CXX -m32" + LD="$LD -m32" + compile + if [ $? != 0 ] ; then + # sometimes, we need to also tell the assembler to generate 32-bit binaries + # this is highly dependent on your GCC installation (and no, we can't set + # this flag all the time) + CFLAGS="$CFLAGS -Wa,--32" + compile + fi + fi + + compile + if [ $? != 0 ] ; then + echo "your C compiler doesn't seem to work:" + cat $TMPL + clean_exit + fi + log "CC : compiler check ok ($CC)" + + # check that we can link the trivial program into an executable + link + if [ $? != 0 ] ; then + OLD_LD="$LD" + LD="$CC" + compile + link + if [ $? != 0 ] ; then + LD="$OLD_LD" + echo "your linker doesn't seem to work:" + cat $TMPL + clean_exit + fi + fi + log "Using '$LD' as the linker" + log "LD : linker check ok ($LD)" + + # check the C++ compiler + log "Using '$CXX' as the C++ compiler" + + cat > $TMPC <<EOF +#include <iostream> +using namespace std; +int main() +{ + cout << "Hello World!" << endl; + return 0; +} +EOF + + compile_cpp + if [ $? != 0 ] ; then + echo "your C++ compiler doesn't seem to work" + cat $TMPL + clean_exit + fi + + log "CXX : C++ compiler check ok ($CXX)" + + # XXX: TODO perform AR checks + AR=ar + ARFLAGS= +} + +# try to compile the current source file in $TMPC into an object +# stores the error log into $TMPL +# +compile () +{ + log "Object : $CC -o $TMPO -c $CFLAGS $TMPC" + $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL +} + +compile_cpp () +{ + log "Object : $CXX -o $TMPO -c $CXXFLAGS $TMPC" + $CXX -o $TMPO -c $CXXFLAGS $TMPC 2> $TMPL +} + +# try to link the recently built file into an executable. error log in $TMPL +# +link() +{ + log "Link : $LD -o $TMPE $TMPO $LDFLAGS" + $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL +} + +# run a command +# +execute() +{ + log "Running: $*" + $* +} + +# perform a simple compile / link / run of the source file in $TMPC +compile_exec_run() +{ + log "RunExec : $CC -o $TMPE $CFLAGS $TMPC" + compile + if [ $? != 0 ] ; then + echo "Failure to compile test program" + cat $TMPC + cat $TMPL + clean_exit + fi + link + if [ $? != 0 ] ; then + echo "Failure to link test program" + cat $TMPC + echo "------" + cat $TMPL + clean_exit + fi + $TMPE +} + +pattern_match () +{ + echo "$2" | grep -q -E -e "$1" +} + +# Let's check that we have a working md5sum here +check_md5sum () +{ + A_MD5=`echo "A" | md5sum | cut -d' ' -f1` + if [ "$A_MD5" != "bf072e9119077b4e76437a93986787ef" ] ; then + echo "Please install md5sum on this machine" + exit 2 + fi +} + +# 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 RET + PROG=`which $2 2>/dev/null` + RET=$? + if [ $RET != 0 ]; then + PROG= + fi + eval $1=\"$PROG\" + return $RET +} + +prepare_download () +{ + find_program CMD_WGET wget + find_program CMD_CURL curl + find_program CMD_SCRP scp +} + +find_pbzip2 () +{ + if [ -z "$_PBZIP2_initialized" ] ; then + find_program PBZIP2 pbzip2 + _PBZIP2_initialized="yes" + fi +} + +# 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 +} + +# Form the relative path between from one abs path to another +# +# $1 : start path +# $2 : end path +# +# From: +# http://stackoverflow.com/questions/2564634/bash-convert-absolute-path-into-relative-path-given-a-current-directory +relpath () +{ + [ $# -ge 1 ] && [ $# -le 2 ] || return 1 + current="${2:+"$1"}" + target="${2:-"$1"}" + [ "$target" != . ] || target=/ + target="/${target##/}" + [ "$current" != . ] || current=/ + current="${current:="/"}" + current="/${current##/}" + appendix="${target##/}" + relative='' + while appendix="${target#"$current"/}" + [ "$current" != '/' ] && [ "$appendix" = "$target" ]; do + if [ "$current" = "$appendix" ]; then + relative="${relative:-.}" + echo "${relative#/}" + return 0 + fi + current="${current%/*}" + relative="$relative${relative:+/}.." + done + relative="$relative${relative:+${appendix:+/}}${appendix#/}" + echo "$relative" +} + +# Unpack a given archive +# +# $1: archive file path +# $2: optional target directory (current one if omitted) +# +unpack_archive () +{ + local ARCHIVE="$1" + local DIR=${2-.} + local RESULT TARFLAGS ZIPFLAGS + mkdir -p "$DIR" + TARFLAGS="xpf" + # todo: zuav: ZIPFLAGS="-qo" + ZIPFLAGS="q" + case "$ARCHIVE" in + *.zip) + (cd $DIR && run unzip $ZIPFLAGS "$ARCHIVE") + ;; + *.tar) + run tar $TARFLAGS "$ARCHIVE" -C $DIR + ;; + *.tar.gz) + run tar z$TARFLAGS "$ARCHIVE" -C $DIR + ;; + *.tar.bz2) + find_pbzip2 + if [ -n "$PBZIP2" ] ; then + run tar --use-compress-prog=pbzip2 -$TARFLAGS "$ARCHIVE" -C $DIR + else + run tar j$TARFLAGS "$ARCHIVE" -C $DIR + fi + # remove ._* files by MacOSX to preserve resource forks we don't need + find $DIR -name "\._*" -exec rm {} \; + ;; + *.tar.xz) + run tar J$TARFLAGS "$ARCHIVE" -C $DIR + ;; + *) + panic "Cannot unpack archive with unknown extension: $ARCHIVE" + ;; + esac +} + +# 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` + TARFLAGS="cf" + ZIPFLAGS="-9qr" + # Ensure symlinks are stored as is in zip files. for toolchains + # this can save up to 7 MB in the size of the final archive + #ZIPFLAGS="$ZIPFLAGS --symlinks" + 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) + find_pbzip2 + if [ -n "$PBZIP2" ] ; then + (cd $SRCDIR && run tar --use-compress-prog=pbzip2 -$TARFLAGS "$ARCHIVE" $SRCFILES) + else + (cd $SRCDIR && run tar j$TARFLAGS "$ARCHIVE" $SRCFILES) + fi + ;; + *.tar.xz) + (cd $SRCDIR && run tar J$TARFLAGS "$ARCHIVE" $SRCFILES) + ;; + *) + panic "Unsupported archive format: $ARCHIVE" + ;; + esac +} + +# 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 + log "Copying directory: " + log " from $SRCDIR" + log " to $DSTDIR" + mkdir -p "$DSTDIR" && (cd "$SRCDIR" && 2>/dev/null tar cf - *) | (tar xf - -C "$DSTDIR") + fail_panic "Cannot copy to directory: $DSTDIR" +} + +# Move a directory, create target location if needed +# +# $1: source directory +# $2: target directory location +# +move_directory () +{ + local SRCDIR="$1" + local DSTDIR="$2" + if [ ! -d "$SRCDIR" ] ; then + panic "Can't move from non-directory: $SRCDIR" + fi + log "Move directory: " + log " from $SRCDIR" + log " to $DSTDIR" + mkdir -p "$DSTDIR" && (mv "$SRCDIR"/* "$DSTDIR") + fail_panic "Cannot move to directory: $DSTDIR" +} + +# This is the same than copy_directory(), but symlinks will be replaced +# by the file they actually point to instead. +copy_directory_nolinks () +{ + local SRCDIR="$1" + local DSTDIR="$2" + if [ ! -d "$SRCDIR" ] ; then + panic "Can't copy from non-directory: $SRCDIR" + fi + log "Copying directory (without symlinks): " + log " from $SRCDIR" + log " to $DSTDIR" + mkdir -p "$DSTDIR" && (cd "$SRCDIR" && tar chf - *) | (tar xf - -C "$DSTDIR") + fail_panic "Cannot copy to directory: $DSTDIR" +} + +# Copy certain files from one directory to another one +# $1: source directory +# $2: target directory +# $3+: file list (including patterns) +copy_file_list () +{ + local SRCDIR="$1" + local DSTDIR="$2" + shift; shift; + if [ ! -d "$SRCDIR" ] ; then + panic "Cant' copy from non-directory: $SRCDIR" + fi + # todo zuav: check for number of arguments? + #log "Copying file: $@" + log "Copying file: $1 $2 $3 ..." + log " from $SRCDIR" + log " to $DSTDIR" + + mkdir -p "$DSTDIR" && (cd "$SRCDIR" && (echo $@ | tr ' ' '\n' | tar cf - -T -)) | (tar xf - -C "$DSTDIR") + fail_panic "Cannot copy files to directory: $DSTDIR" +} + +# Rotate a log file +# If the given log file exist, add a -1 to the end of the file. +# If older log files exist, rename them to -<n+1> +# $1: log file +# $2: maximum version to retain [optional] +rotate_log () +{ + # Default Maximum versions to retain + local MAXVER="5" + local LOGFILE="$1" + shift; + if [ ! -z "$1" ] ; then + local tmpmax="$1" + shift; + tmpmax=`expr $tmpmax + 0` + if [ $tmpmax -lt 1 ] ; then + panic "Invalid maximum log file versions '$tmpmax' invalid; defaulting to $MAXVER" + else + MAXVER=$tmpmax; + fi + fi + + # Do Nothing if the log file does not exist + if [ ! -f "${LOGFILE}" ] ; then + return + fi + + # Rename existing older versions + ver=$MAXVER + while [ $ver -ge 1 ] + do + local prev=$(( $ver - 1 )) + local old="-$prev" + + # Instead of old version 0; use the original filename + if [ $ver -eq 1 ] ; then + old="" + fi + + if [ -f "${LOGFILE}${old}" ] ; then + mv -f "${LOGFILE}${old}" "${LOGFILE}-${ver}" + fi + + ver=$prev + done +} + +# Copy a given package to the cache directory +# +# $1: package dir +# $2: archive file name +cache_package () +{ + local package_dir=$1 + local archive=$2 + log "Copying $package_dir/$archive to cache dir $NDK_CACHE_DIR." + cp "$package_dir/$archive" "$NDK_CACHE_DIR" + fail_panic "Could not cache package: $archive" +} + +# Copy a given cached package if found to the given package directory +# NB +# This function will exit a script on succes! +# +# $1: package dir +# $2: archive file name +# $3: optional, can be anything, prevents exit +try_cached_package () +{ + local package_dir=$1 + local archive=$2 + + if [ "$package_dir" -a -e "$NDK_CACHE_DIR/$archive" ]; then + dump "Found cached package: $NDK_CACHE_DIR/$archive" + mkdir -p "$package_dir" + cp "$NDK_CACHE_DIR/$archive" "$package_dir" + fail_panic "Could not copy $archive from cache directory." + if [ -n "$3" ]; then + return 0 + else + log "Done" + exit 0 + fi + fi + + return 1 +} + +# check that every member of the specified list is a member +# of the second list +# +# $1: list of strings separated by blanks +# $2: list of standard (permitted) values separated by blanks +# $3: error message, optional +check_list_values () +{ + #echo "1: $1" + #echo "2: $2" + #echo "3: $3" + + local list=$1 + local standard_list=$2 + local err_msg="bad value" + + if [ -n "$3" ]; then + err_msg=$3 + fi + + local val= + local defval= + local good= + local defsys= + for val in $list ; do + good="" + for defval in $standard_list ; do + if [ "$val" = "$defval" ] ; then + good="yes" + break + fi + done + if [ "$good" != "yes" ] ; then + panic "$err_msg: $val" + fi + done +} + +# Dereference symlink +# $1+: directories +dereference_symlink () +{ + local DIRECTORY SYMLINKS DIR FILE LINK + for DIRECTORY in "$@"; do + if [ -d "$DIRECTORY" ]; then + while true; do + # Find all symlinks in this directory. + SYMLINKS=`find $DIRECTORY -type l` + if [ -z "$SYMLINKS" ]; then + break; + fi + # Iterate symlinks + for SYMLINK in $SYMLINKS; do + if [ -L "$SYMLINK" ]; then + DIR=`dirname "$SYMLINK"` + FILE=`basename "$SYMLINK"` + # Note that if `readlink $FILE` is also a link, we want to deal + # with it in the next iteration. There is potential infinite-loop + # situation for cicular link doesn't exist in our case, though. + (cd "$DIR" && \ + LINK=`readlink "$FILE"` && \ + test ! -L "$LINK" && \ + rm -f "$FILE" && \ + cp -a "$LINK" "$FILE") + fi + done + done + fi + done +} diff --git a/scripts/tools/prebuilt-common.sh b/scripts/tools/prebuilt-common.sh new file mode 100755 index 00000000..4b162010 --- /dev/null +++ b/scripts/tools/prebuilt-common.sh @@ -0,0 +1,1607 @@ +# Common functions for all prebuilt-related scripts +# This is included/sourced by other scripts +# + +# ensure stable sort order +export LC_ALL=C + +# NDK_BUILDTOOLS_PATH should point to the directory containing +# this script. If it is not defined, assume that this is one of +# the scripts in the same directory that sourced this file. +# +if [ -z "$NDK_BUILDTOOLS_PATH" ]; then + NDK_BUILDTOOLS_PATH=$(dirname $0) + if [ ! -f "$NDK_BUILDTOOLS_PATH/prebuilt-common.sh" ]; then + echo "INTERNAL ERROR: Please define NDK_BUILDTOOLS_PATH to point to \$NDK/build/tools" + exit 1 + fi +fi + +# Warn if /bin/sh isn't bash. +if [ -z "$BASH_VERSION" ] ; then + echo "WARNING: The shell running this script isn't bash. Although we try to avoid bashism in scripts, things can happen." +fi + +NDK_BUILDTOOLS_ABSPATH=$(cd $NDK_BUILDTOOLS_PATH && pwd) + +. $NDK_BUILDTOOLS_PATH/ndk-common.sh +. $NDK_BUILDTOOLS_PATH/dev-defaults.sh + +# Given an input string of the form <foo>-<bar>-<version>, where +# <version> can be <major>.<minor>, extract <major> +extract_version () +{ + echo $1 | tr '-' '\n' | tail -1 +} + +# $1: versioned name (e.g. arm-linux-androideabi-4.8) +# Out: major version (e.g. 4) +# +# Examples: arm-linux-androideabi-4.4.3 -> 4 +# gmp-0.81 -> 0 +# +extract_major_version () +{ + local RET=$(extract_version $1 | cut -d . -f 1) + RET=${RET:-0} + echo $RET +} + +# Same as extract_major_version, but for the minor version number +# $1: versioned named +# Out: minor version +# +extract_minor_version () +{ + local RET=$(extract_version $1 | cut -d . -f 2) + RET=${RET:-0} + echo $RET +} + +# Compare two version numbers and only succeeds if the first one is +# greater than or equal to the second one. +# +# $1: first version (e.g. 4.9) +# $2: second version (e.g. 4.8) +# +# Example: version_is_at_least 4.9 4.8 --> success +# +version_is_at_least () +{ + local A_MAJOR A_MINOR B_MAJOR B_MINOR + A_MAJOR=$(extract_major_version $1) + B_MAJOR=$(extract_major_version $2) + + if [ $A_MAJOR -lt $B_MAJOR ]; then + return 1 + elif [ $A_MAJOR -gt $B_MAJOR ]; then + return 0 + fi + + # We have A_MAJOR == B_MAJOR here + + A_MINOR=$(extract_minor_version $1) + B_MINOR=$(extract_minor_version $2) + + if [ $A_MINOR -lt $B_MINOR ]; then + return 0 + else + return 1 + fi +} + +#==================================================== +# +# UTILITY FUNCTIONS +# +#==================================================== + +# Return the maximum length of a series of strings +# +# Usage: len=`max_length <string1> <string2> ...` +# +max_length () +{ + echo "$@" | tr ' ' '\n' | awk 'BEGIN {max=0} {len=length($1); if (len > max) max=len} END {print max}' +} + +# Translate dashes to underscores +# Usage: str=`dashes_to_underscores <values>` +dashes_to_underscores () +{ + echo "$@" | tr '-' '_' +} + +# Translate underscores to dashes +# Usage: str=`underscores_to_dashes <values>` +underscores_to_dashes () +{ + echo "$@" | tr '_' '-' +} + +# Translate commas to spaces +# Usage: str=`commas_to_spaces <list>` +commas_to_spaces () +{ + echo "$@" | tr ',' ' ' +} + +# Translate spaces to commas +# Usage: list=`spaces_to_commas <string>` +spaces_to_commas () +{ + echo "$@" | tr ' ' ',' +} + +# Remove trailing path of a path +# $1: path +remove_trailing_slash () { + echo ${1%%/} +} + +# Reverse a file path directory +# foo -> . +# foo/bar -> .. +# foo/bar/zoo -> ../.. +reverse_path () +{ + local path cur item + path=${1%%/} # remove trailing slash + cur="." + if [ "$path" != "." ] ; then + for item in $(echo "$path" | tr '/' ' '); do + cur="../$cur" + done + fi + echo ${cur%%/.} +} + +# test_reverse_path () +# { +# rr=`reverse_path $1` +# if [ "$rr" != "$2" ] ; then +# echo "ERROR: reverse_path '$1' -> '$rr' (expected '$2')" +# fi +# } +# +# test_reverse_path . . +# test_reverse_path ./ . +# test_reverse_path foo .. +# test_reverse_path foo/ .. +# test_reverse_path foo/bar ../.. +# test_reverse_path foo/bar/ ../.. +# test_reverse_path foo/bar/zoo ../../.. +# test_reverse_path foo/bar/zoo/ ../../.. + +# Sort a space-separated list and remove duplicates +# $1+: slist +# Output: new slist +sort_uniq () +{ + local RET + RET=$(echo "$@" | tr ' ' '\n' | sort -u) + echo $RET +} + +# Return the list of all regular files under a given directory +# $1: Directory path +# Output: list of files, relative to $1 +list_files_under () +{ + if [ -d "$1" ]; then + (cd $1 && find . -type f | sed -e "s!./!!" | sort -u) + else + echo "" + fi +} + +# Returns all words in text that do not match any of the pattern +# $1: pattern +# $2: text +filter_out () +{ + local PATTERN="$1" + local TEXT="$2" + for pat in $PATTERN; do + pat=$"${pat//\//\\/}" + TEXT=$(echo $TEXT | sed -e 's/'$pat' //g' -e 's/'$pat'$//g') + done + echo $TEXT +} + +# Assign a value to a variable +# $1: Variable name +# $2: Value +var_assign () +{ + eval $1=\"$2\" +} + +#==================================================== +# +# OPTION PROCESSING +# +#==================================================== + +# We recognize the following option formats: +# +# -f +# --flag +# +# -s<value> +# --setting=<value> +# + +# NOTE: We translate '-' into '_' when storing the options in global variables +# + +OPTIONS="" +OPTION_FLAGS="" +OPTION_SETTINGS="" + +# Set a given option attribute +# $1: option name +# $2: option attribute +# $3: attribute value +# +option_set_attr () +{ + eval OPTIONS_$1_$2=\"$3\" +} + +# Get a given option attribute +# $1: option name +# $2: option attribute +# +option_get_attr () +{ + echo `var_value OPTIONS_$1_$2` +} + +# Register a new option +# $1: option +# $2: small abstract for the option +# $3: optional. default value +# +register_option_internal () +{ + optlabel= + optname= + optvalue= + opttype= + while [ -n "1" ] ; do + # Check for something like --setting=<value> + echo "$1" | grep -q -E -e '^--[^=]+=<.+>$' + if [ $? = 0 ] ; then + optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'` + optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'` + opttype="long_setting" + break + fi + + # Check for something like --flag + echo "$1" | grep -q -E -e '^--[^=]+$' + if [ $? = 0 ] ; then + optlabel="$1" + opttype="long_flag" + break + fi + + # Check for something like -f<value> + echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$' + if [ $? = 0 ] ; then + optlabel=`expr -- "$1" : '\(-.\).*'` + optvalue=`expr -- "$1" : '-.\(<.+>\)'` + opttype="short_setting" + break + fi + + # Check for something like -f + echo "$1" | grep -q -E -e '^-.$' + if [ $? = 0 ] ; then + optlabel="$1" + opttype="short_flag" + break + fi + + echo "ERROR: Invalid option format: $1" + echo " Check register_option call" + exit 1 + done + + log "new option: type='$opttype' name='$optlabel' value='$optvalue'" + + optname=`dashes_to_underscores $optlabel` + OPTIONS="$OPTIONS $optname" + OPTIONS_TEXT="$OPTIONS_TEXT $1" + option_set_attr $optname label "$optlabel" + option_set_attr $optname otype "$opttype" + option_set_attr $optname value "$optvalue" + option_set_attr $optname text "$1" + option_set_attr $optname abstract "$2" + option_set_attr $optname default "$3" +} + +# Register a new option with a function callback. +# +# $1: option +# $2: name of function that will be called when the option is parsed +# $3: small abstract for the option +# $4: optional. default value +# +register_option () +{ + local optname optvalue opttype optlabel + register_option_internal "$1" "$3" "$4" + option_set_attr $optname funcname "$2" +} + +# Register a new option with a variable store +# +# $1: option +# $2: name of variable that will be set by this option +# $3: small abstract for the option +# +# NOTE: The current value of $2 is used as the default +# +register_var_option () +{ + local optname optvalue opttype optlabel + register_option_internal "$1" "$3" "`var_value $2`" + option_set_attr $optname varname "$2" +} + + +MINGW=no +DARWIN=no +do_mingw_option () +{ + if [ "$DARWIN" = "yes" ]; then + echo "Can not have both --mingw and --darwin" + exit 1 + fi + MINGW=yes; +} +do_darwin_option () +{ + if [ "$MINGW" = "yes" ]; then + echo "Can not have both --mingw and --darwin" + exit 1 + fi + DARWIN=yes; +} + +register_canadian_option () +{ + if [ "$HOST_OS" = "linux" ] ; then + register_option "--mingw" do_mingw_option "Generate windows binaries on Linux." + register_option "--darwin" do_darwin_option "Generate darwin binaries on Linux." + fi +} + +TRY64=no +do_try64_option () { TRY64=yes; } + +register_try64_option () +{ + register_option "--try-64" do_try64_option "Generate 64-bit only binaries." +} + + +register_jobs_option () +{ + NUM_JOBS=$BUILD_NUM_CPUS + register_var_option "-j<number>" NUM_JOBS "Use <number> parallel build jobs" +} + +# Print the help, including a list of registered options for this program +# Note: Assumes PROGRAM_PARAMETERS and PROGRAM_DESCRIPTION exist and +# correspond to the parameters list and the program description +# +print_help () +{ + local opt text abstract default + + echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS" + echo "" + if [ -n "$PROGRAM_DESCRIPTION" ] ; then + echo "$PROGRAM_DESCRIPTION" + echo "" + fi + echo "Valid options (defaults are in brackets):" + echo "" + + maxw=`max_length "$OPTIONS_TEXT"` + AWK_SCRIPT=`echo "{ printf \"%-${maxw}s\", \\$1 }"` + for opt in $OPTIONS; do + text=`option_get_attr $opt text | awk "$AWK_SCRIPT"` + abstract=`option_get_attr $opt abstract` + default=`option_get_attr $opt default` + if [ -n "$default" ] ; then + echo " $text $abstract [$default]" + else + echo " $text $abstract" + fi + done + echo "" +} + +option_panic_no_args () +{ + echo "ERROR: Option '$1' does not take arguments. See --help for usage." + exit 1 +} + +option_panic_missing_arg () +{ + echo "ERROR: Option '$1' requires an argument. See --help for usage." + exit 1 +} + +extract_parameters () +{ + local opt optname otype value name fin funcname + PARAMETERS="" + while [ -n "$1" ] ; do + # If the parameter does not begin with a dash + # it is not an option. + param=`expr -- "$1" : '^\([^\-].*\)$'` + if [ -n "$param" ] ; then + if [ -z "$PARAMETERS" ] ; then + PARAMETERS="$1" + else + PARAMETERS="$PARAMETERS $1" + fi + shift + continue + fi + + while [ -n "1" ] ; do + # Try to match a long setting, i.e. --option=value + opt=`expr -- "$1" : '^\(--[^=]*\)=.*$'` + if [ -n "$opt" ] ; then + otype="long_setting" + value=`expr -- "$1" : '^--[^=]*=\(.*\)$'` + break + fi + + # Try to match a long flag, i.e. --option + opt=`expr -- "$1" : '^\(--.*\)$'` + if [ -n "$opt" ] ; then + otype="long_flag" + value="yes" + break + fi + + # Try to match a short setting, i.e. -o<value> + opt=`expr -- "$1" : '^\(-[A-Za-z0-9]\)..*$'` + if [ -n "$opt" ] ; then + otype="short_setting" + value=`expr -- "$1" : '^-.\(.*\)$'` + break + fi + + # Try to match a short flag, i.e. -o + opt=`expr -- "$1" : '^\(-.\)$'` + if [ -n "$opt" ] ; then + otype="short_flag" + value="yes" + break + fi + + echo "ERROR: Unknown option '$1'. Use --help for list of valid values." + exit 1 + done + + #echo "Found opt='$opt' otype='$otype' value='$value'" + + name=`dashes_to_underscores $opt` + found=0 + for xopt in $OPTIONS; do + if [ "$name" != "$xopt" ] ; then + continue + fi + # Check that the type is correct here + # + # This also allows us to handle -o <value> as -o<value> + # + xotype=`option_get_attr $name otype` + if [ "$otype" != "$xotype" ] ; then + case "$xotype" in + "short_flag") + option_panic_no_args $opt + ;; + "short_setting") + if [ -z "$2" ] ; then + option_panic_missing_arg $opt + fi + value="$2" + shift + ;; + "long_flag") + option_panic_no_args $opt + ;; + "long_setting") + option_panic_missing_arg $opt + ;; + esac + fi + found=1 + break + break + done + if [ "$found" = "0" ] ; then + echo "ERROR: Unknown option '$opt'. See --help for usage." + exit 1 + fi + # Set variable or launch option-specific function. + varname=`option_get_attr $name varname` + if [ -n "$varname" ] ; then + eval ${varname}=\"$value\" + else + eval `option_get_attr $name funcname` \"$value\" + fi + shift + done +} + +do_option_help () +{ + print_help + exit 0 +} + +VERBOSE=no +do_option_verbose () +{ + VERBOSE=yes +} + +DRYRUN=no +do_option_dryrun () +{ + DRYRUN=yes +} + +register_option "--help" do_option_help "Print this help." +register_option "--verbose" do_option_verbose "Enable verbose mode." +register_option "--dryrun" do_option_dryrun "Set to dryrun mode." + +#==================================================== +# +# TOOLCHAIN AND ABI PROCESSING +# +#==================================================== + +# Determine optional variable value +# $1: final variable name +# $2: option variable name +# $3: small description for the option +fix_option () +{ + if [ -n "$2" ] ; then + eval $1="$2" + log "Using specific $3: $2" + else + log "Using default $3: `var_value $1`" + fi +} + + +# If SYSROOT is empty, check that $1/$2 contains a sysroot +# and set the variable to it. +# +# $1: sysroot path +# $2: platform/arch suffix +check_sysroot () +{ + if [ -z "$SYSROOT" ] ; then + log "Probing directory for sysroot: $1/$2" + if [ -d $1/$2 ] ; then + SYSROOT=$1/$2 + fi + fi +} + +# Determine sysroot +# $1: Option value (or empty) +# +fix_sysroot () +{ + if [ -n "$1" ] ; then + eval SYSROOT="$1" + log "Using specified sysroot: $1" + else + SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH + SYSROOT= + check_sysroot $NDK_DIR/platforms $SYSROOT_SUFFIX + check_sysroot $ANDROID_NDK_ROOT/platforms $SYSROOT_SUFFIX + check_sysroot `dirname $ANDROID_NDK_ROOT`/development/ndk/platforms $SYSROOT_SUFFIX + + if [ -z "$SYSROOT" ] ; then + echo "ERROR: Could not find NDK sysroot path for $SYSROOT_SUFFIX." + echo " Use --sysroot=<path> to specify one." + exit 1 + fi + fi + + if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then + echo "ERROR: Invalid sysroot path: $SYSROOT" + echo " Use --sysroot=<path> to indicate a valid one." + exit 1 + fi +} + +# Check for the availability of a compatibility SDK in Darwin +# this can be used to generate binaries compatible with either Tiger or +# Leopard. +# +# $1: SDK root path +# $2: Optional MacOS X minimum version (e.g. 10.5) +DARWIN_MINVER=10.6 +check_darwin_sdk () +{ + local MACSDK="$1" + local MINVER=$2 + + if [ -z "$MINVER" ] ; then + # expect SDK root path ended up with either MacOSX##.#.sdk or MacOSX##.#u.sdk + MINVER=${MACSDK##*MacOSX} + MINVER=${MINVER%%.sdk*} + if [ "$MINVER" = "10.4u" ]; then + MINVER=10.4 + fi + fi + if [ -d "$MACSDK" ] ; then + HOST_CFLAGS=$HOST_CFLAGS" -isysroot $MACSDK -mmacosx-version-min=$MINVER -DMACOSX_DEPLOYMENT_TARGET=$MINVER" + HOST_LDFLAGS=$HOST_LDFLAGS" -Wl,-syslibroot,$MACSDK -mmacosx-version-min=$MINVER" + DARWIN_MINVER=$MINVER + return 0 # success + fi + return 1 +} + +# Probe Darwin SDK in specified diectory $DARWIN_SYSROOT, or +# /Developer/SDKs/MacOSX10.6.sdk +# +probe_darwin_sdk () +{ + if [ -n "$DARWIN_SYSROOT" ]; then + if check_darwin_sdk "$DARWIN_SYSROOT"; then + log "Use darwin sysroot $DARWIN_SYSROOT" + else + echo "darwin sysroot $DARWIN_SYSROOT is not valid" + exit 1 + fi + elif check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk 10.6; then + log "Generating Snow Leopard-compatible binaries!" + else + local version=`sw_vers -productVersion` + log "Generating $version-compatible binaries!" + fi +} + +handle_canadian_build () +{ + HOST_EXE= + if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then + case $HOST_TAG in + linux-*) + ;; + *) + echo "ERROR: Can only enable --mingw or --darwin on Linux platforms !" + exit 1 + ;; + esac + if [ "$MINGW" = "yes" ] ; then + # NOTE: Use x86_64-pc-mingw32msvc or i586-pc-mingw32msvc because wrappers are generated + # using these names + if [ "$TRY64" = "yes" ]; then + ABI_CONFIGURE_HOST=x86_64-pc-mingw32msvc + HOST_TAG=windows-x86_64 + else + ABI_CONFIGURE_HOST=i586-pc-mingw32msvc + HOST_TAG=windows + fi + HOST_OS=windows + HOST_EXE=.exe + else + if [ "$TRY64" = "yes" ]; then + ABI_CONFIGURE_HOST=x86_64-apple-darwin + HOST_TAG=darwin-x86_64 + else + ABI_CONFIGURE_HOST=i686-apple-darwin + HOST_TAG=darwin-x86 + fi + HOST_OS=darwin + fi + fi +} + +# Find mingw toolchain +# +# Set MINGW_GCC to the found mingw toolchain +# +find_mingw_toolchain () +{ + if [ "$DEBIAN_NAME" -a "$BINPREFIX" -a "$MINGW_GCC" ]; then + return + fi + # IMPORTANT NOTE: binutils 2.21 requires a cross toolchain named + # i585-pc-mingw32msvc-gcc, or it will fail its configure step late + # in the toolchain build. Note that binutils 2.19 can build properly + # with i585-mingw32mvsc-gcc, which is the name used by the 'mingw32' + # toolchain install on Debian/Ubuntu. + # + # To solve this dilemma, we create a wrapper toolchain named + # i586-pc-mingw32msvc-gcc that really calls i586-mingw32msvc-gcc, + # this works with all versions of binutils. + # + # We apply the same logic to the 64-bit Windows cross-toolchain + # + # Fedora note: On Fedora it's x86_64-w64-mingw32- or i686-w64-mingw32- + # On older Fedora it's 32-bit only and called i686-pc-mingw32- + # so we just add more prefixes to the list to check. + if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then + BINPREFIX=x86_64-pc-mingw32msvc- + #BINPREFIXLST="x86_64-w64-mingw32- x86_64-pc-mingw32msvc- amd64-mingw32msvc-" + MINGW_GCC=x86_64-w64-mingw32-gcc + DEBIAN_NAME=mingw64 + MINGW_PATH="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/bin" + else + # we are trying 32 bit anyway, so forcing it to avoid build issues + force_32bit_binaries + BINPREFIX=i586-pc-mingw32msvc- + #BINPREFIXLST="i686-w64-mingw32- i586-pc-mingw32msvc- i686-pc-mingw32- i586-mingw32msvc-" + MINGW_GCC=i686-w64-mingw32-gcc + DEBIAN_NAME=mingw32 + MINGW_PATH="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/i686-w64-mingw32-4.8/bin" + fi + + export PATH="$MINGW_PATH:$PATH" + dump "Will use mingw toolchain in: $MINGW_PATH" + + + # Scan $BINPREFIXLST list to find installed mingw toolchain. It will be + # wrapped later with $BINPREFIX. + #for i in $BINPREFIXLST; do + # find_program MINGW_GCC ${i}gcc + # if [ -n "$MINGW_GCC" ]; then + # dump "Found mingw toolchain: $MINGW_GCC" + # break + # fi + #done +} + +# Check there is a working cross-toolchain installed. +# +# $1: install directory for mingw/darwin wrapper toolchain +# +prepare_canadian_toolchain () +{ + if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then + return + fi + CROSS_GCC= + if [ "$MINGW" = "yes" ]; then + find_mingw_toolchain + if [ -z "$MINGW_GCC" ]; then + echo "ERROR: Could not find in your PATH any of:" + for i in $BINPREFIXLST; do echo " ${i}gcc"; done + echo "Please install the corresponding cross-toolchain and re-run this script" + echo "TIP: On Debian or Ubuntu, try: sudo apt-get install $DEBIAN_NAME" + exit 1 + fi + CROSS_GCC=$MINGW_GCC + else + if [ -z "$DARWIN_TOOLCHAIN" ]; then + echo "Please set DARWIN_TOOLCHAIN to darwin cross-toolchain" + exit 1 + fi + if [ ! -f "${DARWIN_TOOLCHAIN}-gcc" ]; then + echo "darwin cross-toolchain $DARWIN_TOOLCHAIN-gcc doesn't exist" + exit 1 + fi + if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then + BINPREFIX=x86_64-apple-darwin- + DEBIAN_NAME=darwin64 + HOST_CFLAGS=$HOST_CFLAGS" -m64" + else + force_32bit_binaries + BINPREFIX=i686-apple-darwin- + DEBIAN_NAME=darwin32 + HOST_CFLAGS=$HOST_CFLAGS" -m32" + fi + CROSS_GCC=${DARWIN_TOOLCHAIN}-gcc + probe_darwin_sdk + fi + + # Create a wrapper toolchain, and prepend its dir to our PATH + CROSS_WRAP_DIR="$1"/$DEBIAN_NAME-wrapper + rm -rf "$CROSS_WRAP_DIR" + mkdir -p "$CROSS_WRAP_DIR" + + if [ "$DARWIN" = "yes" ] ; then + cat > "$CROSS_WRAP_DIR/sw_vers" <<EOF +#!/bin/sh +# Tiny utility for the real sw_vers some Makefiles need +case \$1 in + -productVersion) + echo $DARWIN_MINVER + ;; + *) + echo "ERROR: Unknown switch \$1" + exit 1 +esac +EOF + chmod 0755 "$CROSS_WRAP_DIR/sw_vers" + fi + + DST_PREFIX=${CROSS_GCC%gcc} + if [ "$NDK_CCACHE" ]; then + DST_PREFIX="$NDK_CCACHE $DST_PREFIX" + fi + $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=$BINPREFIX --dst-prefix="$DST_PREFIX" "$CROSS_WRAP_DIR" \ + --cflags="$HOST_CFLAGS" --cxxflags="$HOST_CFLAGS" --ldflags="$HOST_LDFLAGS" + # generate wrappers for BUILD toolchain + # this is required for mingw/darwin build to avoid tools canadian cross configuration issues + # 32-bit BUILD toolchain + LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" + $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-linux-gnu- \ + --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \ + --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" + $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-pc-linux-gnu- \ + --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \ + --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" + # 64-bit BUILD toolchain. libbfd is still built in 32-bit. + $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-linux-gnu- \ + --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" + $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-pc-linux-gnu- \ + --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" + fail_panic "Could not create $DEBIAN_NAME wrapper toolchain in $CROSS_WRAP_DIR" + + export PATH=$CROSS_WRAP_DIR:$PATH + dump "Using $DEBIAN_NAME wrapper: $CROSS_WRAP_DIR/${BINPREFIX}gcc" +} + +handle_host () +{ + if [ "$TRY64" != "yes" ]; then + force_32bit_binaries # to modify HOST_TAG and others + HOST_BITS=32 + fi + handle_canadian_build +} + +setup_ccache () +{ + # Support for ccache compilation + # We can't use this here when building Windows/darwin binaries on Linux with + # binutils 2.21, because defining CC/CXX in the environment makes the + # configure script fail later + # + if [ "$NDK_CCACHE" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then + NDK_CCACHE_CC=$CC + NDK_CCACHE_CXX=$CXX + # Unfortunately, we can just do CC="$NDK_CCACHE $CC" because some + # configure scripts are not capable of dealing with this properly + # E.g. the ones used to rebuild the GCC toolchain from scratch. + # So instead, use a wrapper script + CC=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-gcc.sh + CXX=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-g++.sh + export NDK_CCACHE_CC NDK_CCACHE_CXX + log "Using ccache compilation" + log "NDK_CCACHE_CC=$NDK_CCACHE_CC" + log "NDK_CCACHE_CXX=$NDK_CCACHE_CXX" + fi +} + +prepare_common_build () +{ + if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then + if [ "$TRY64" = "yes" ]; then + HOST_BITS=64 + else + HOST_BITS=32 + fi + if [ "$MINGW" = "yes" ]; then + log "Generating $HOST_BITS-bit Windows binaries" + else + log "Generating $HOST_BITS-bit Darwin binaries" + fi + # Do *not* set CC and CXX when building the Windows/Darwin binaries in canadian build. + # Otherwise, the GCC configure/build script will mess that Canadian cross + # build in weird ways. Instead we rely on the toolchain detected or generated + # previously in prepare_canadian_toolchain. + unset CC CXX + return + fi + + # On Linux, detect our legacy-compatible toolchain when in the Android + # source tree, and use it to force the generation of glibc-2.7 compatible + # binaries. + # + # We only do this if the CC variable is not defined to a given value + if [ -z "$CC" ]; then + LEGACY_TOOLCHAIN_DIR= + if [ "$HOST_OS" = "linux" ]; then + LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8/bin" + LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/x86_64-linux-" + elif [ "$HOST_OS" = "darwin" ]; then + local GCCVER=4.9.3 + local LLVMVER=3.7.0 + local GCCDIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/darwin-x86/host/x86_64-apple-darwin-$GCCVER" + local LLVMDIR="$ANDROID_NDK_ROOT/../prebuilts/clang/darwin-x86/host/x86_64-apple-darwin-$LLVMVER" + + LEGACY_TOOLCHAIN_DIR="$GCCDIR/bin" + LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/" + + # For compilation LLDB's Objective-C++ sources we need use clang++, since g++ have a bug + # not distinguishing between Objective-C call and definition of C++11 lambda: + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57607 + # To workaround this, we're using prebuilt clang++ + # with includes from our g++, to keep binary compatibility of produced code + CXXINC="$LEGACY_TOOLCHAIN_DIR/../include/c++/$GCCVER" + CXXBITSINC="$CXXINC/x86_64-apple-darwin" + if [ "$TRY64" != "yes" ]; then + CXXBITSINC="$CXXBITSINC/i386" + fi + OBJCXX="$LLVMDIR/bin/clang++ -I$CXXBITSINC -I$CXXINC" + export OBJCXX + fi + if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then + log "Forcing generation of $HOST_OS binaries with legacy toolchain" + CC="${LEGACY_TOOLCHAIN_PREFIX}gcc" + CXX="${LEGACY_TOOLCHAIN_PREFIX}g++" + fi + fi + + CC=${CC:-gcc} + CXX=${CXX:-g++} + STRIP=${STRIP:-strip} + case $HOST_TAG in + darwin-*) + probe_darwin_sdk + ;; + esac + + # Force generation of 32-bit binaries on 64-bit systems. + # We used to test the value of $HOST_TAG for *-x86_64, but this is + # not sufficient on certain systems. + # + # For example, Snow Leopard can be booted with a 32-bit kernel, running + # a 64-bit userland, with a compiler that generates 64-bit binaries by + # default *even* though "gcc -v" will report --target=i686-apple-darwin10! + # + # So know, simply probe for the size of void* by performing a small runtime + # compilation test. + # + cat > $TMPC <<EOF + /* this test should fail if the compiler generates 64-bit machine code */ + int test_array[1-2*(sizeof(void*) != 4)]; +EOF + log_n "Checking whether the compiler generates 32-bit binaries..." + log $CC $HOST_CFLAGS -c -o $TMPO $TMPC + $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1 + if [ $? != 0 ] ; then + log "no" + if [ "$TRY64" != "yes" ]; then + # NOTE: We need to modify the definitions of CC and CXX directly + # here. Just changing the value of CFLAGS / HOST_CFLAGS + # will not work well with the GCC toolchain scripts. + CC="$CC -m32" + CXX="$CXX -m32" + fi + else + log "yes" + if [ "$TRY64" = "yes" ]; then + CC="$CC -m64" + CXX="$CXX -m64" + fi + fi + + if [ "$TRY64" = "yes" ]; then + HOST_BITS=64 + else + force_32bit_binaries # to modify HOST_TAG and others + HOST_BITS=32 + fi +} + +prepare_host_build () +{ + prepare_common_build + + # Now deal with mingw or darwin + if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then + handle_canadian_build + CC=$ABI_CONFIGURE_HOST-gcc + CXX=$ABI_CONFIGURE_HOST-g++ + CPP=$ABI_CONFIGURE_HOST-cpp + LD=$ABI_CONFIGURE_HOST-ld + AR=$ABI_CONFIGURE_HOST-ar + AS=$ABI_CONFIGURE_HOST-as + RANLIB=$ABI_CONFIGURE_HOST-ranlib + STRIP=$ABI_CONFIGURE_HOST-strip + export CC CXX CPP LD AR AS RANLIB STRIP + fi + + setup_ccache +} + +prepare_abi_configure_build () +{ + # detect build tag + case $HOST_TAG in + linux-x86) + ABI_CONFIGURE_BUILD=i386-linux-gnu + ;; + linux-x86_64) + ABI_CONFIGURE_BUILD=x86_64-linux-gnu + ;; + darwin-x86) + ABI_CONFIGURE_BUILD=i686-apple-darwin + ;; + darwin-x86_64) + ABI_CONFIGURE_BUILD=x86_64-apple-darwin + ;; + windows) + ABI_CONFIGURE_BUILD=i686-pc-cygwin + ;; + *) + echo "ERROR: Unsupported HOST_TAG: $HOST_TAG" + echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh" + ;; + esac +} + +prepare_target_build () +{ + prepare_abi_configure_build + + # By default, assume host == build + ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD" + + prepare_common_build + HOST_GMP_ABI=$HOST_BITS + + # Now handle the --mingw/--darwin flag + if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then + handle_canadian_build + STRIP=$ABI_CONFIGURE_HOST-strip + if [ "$MINGW" = "yes" ] ; then + # It turns out that we need to undefine this to be able to + # perform a canadian-cross build with mingw. Otherwise, the + # GMP configure scripts will not be called with the right options + HOST_GMP_ABI= + fi + fi + + setup_ccache +} + +# $1: Toolchain name +# +parse_toolchain_name () +{ + TOOLCHAIN=$1 + if [ -z "$TOOLCHAIN" ] ; then + echo "ERROR: Missing toolchain name!" + exit 1 + fi + + ABI_CFLAGS_FOR_TARGET= + ABI_CXXFLAGS_FOR_TARGET= + + # Determine ABI based on toolchain name + # + case "$TOOLCHAIN" in + arm-linux-androideabi-*) + ARCH="arm" + ABI="armeabi" + ABI_CONFIGURE_TARGET="arm-linux-androideabi" + ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te" + ;; + arm-eabi-*) + ARCH="arm" + ABI="armeabi" + ABI_CONFIGURE_TARGET="arm-eabi" + ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te --disable-gold --disable-libgomp" + ;; + aarch64-linux-android-*) + ARCH="arm64" + ABI="arm64-v8a" + ABI_CONFIGURE_TARGET="aarch64-linux-android" + ;; + x86-*) + ARCH="x86" + ABI=$ARCH + ABI_INSTALL_NAME="x86" + ABI_CONFIGURE_TARGET="i686-linux-android" + # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time + # You can't really build these separately at the moment. + ABI_CFLAGS_FOR_TARGET="-fPIC" + ;; + x86_64-*) + ARCH="x86_64" + ABI=$ARCH + ABI_INSTALL_NAME="x86_64" + ABI_CONFIGURE_TARGET="x86_64-linux-android" + # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time + # You can't really build these separately at the moment. + ABI_CFLAGS_FOR_TARGET="-fPIC" + ;; + mipsel*) + ARCH="mips" + ABI=$ARCH + ABI_INSTALL_NAME="mips" + ABI_CONFIGURE_TARGET="mipsel-linux-android" + # Set default to mips32 + ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips32" + # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time + # You can't really build these separately at the moment. + # Add -fpic, because MIPS NDK will need to link .a into .so. + ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic" + ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic" + # Add --disable-fixed-point to disable fixed-point support + ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point" + ;; + mips64el*) + ARCH="mips64" + ABI=$ARCH + ABI_INSTALL_NAME="mips64" + ABI_CONFIGURE_TARGET="mips64el-linux-android" + # Set default to mips64r6 + ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips64r6" + # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time + # You can't really build these separately at the moment. + # Add -fpic, because MIPS NDK will need to link .a into .so. + ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic" + ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic" + # Add --disable-fixed-point to disable fixed-point support + ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point" + ;; + * ) + echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|arm-eabi-*|x86-*|mipsel*|mips64el*)" + echo "" + print_help + exit 1 + ;; + esac + + log "Targetting CPU: $ARCH" + + GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'` + log "Using GCC version: $GCC_VERSION" + + # Determine --host value when building gdbserver + + case "$TOOLCHAIN" in + arm-*) + GDBSERVER_HOST=arm-eabi-linux + GDBSERVER_CFLAGS="-fno-short-enums" + GDBSERVER_LDFLAGS= + ;; + aarch64-*) + GDBSERVER_HOST=aarch64-eabi-linux + GDBSERVER_CFLAGS="-fno-short-enums -DUAPI_HEADERS" + GDBSERVER_LDFLAGS= + ;; + x86-*) + GDBSERVER_HOST=i686-linux-android + GDBSERVER_CFLAGS= + GDBSERVER_LDFLAGS= + ;; + x86_64-*) + GDBSERVER_HOST=x86_64-linux-android + GDBSERVER_CFLAGS=-DUAPI_HEADERS + GDBSERVER_LDFLAGS= + ;; + mipsel-*) + GDBSERVER_HOST=mipsel-linux-android + GDBSERVER_CFLAGS= + GDBSERVER_LDFLAGS= + ;; + mips64el-*) + GDBSERVER_HOST=mips64el-linux-android + GDBSERVER_CFLAGS=-DUAPI_HEADERS + GDBSERVER_LDFLAGS= + ;; + *) + echo "Unknown TOOLCHAIN=$TOOLCHAIN" + exit + esac +} + +# Return the host "tag" used to identify prebuilt host binaries. +# NOTE: Handles the case where '$MINGW = true' or '$DARWIN = true' +# For now, valid values are: linux-x86, darwin-x86 and windows +get_prebuilt_host_tag () +{ + local RET=$HOST_TAG + if [ "$MINGW" = "yes" ]; then + if [ "$TRY64" = "no" ]; then + RET=windows + else + RET=windows-x86_64 + fi + fi + if [ "$DARWIN" = "yes" ]; then + RET=darwin-x86_64 # let the following handles 32-bit case + fi + case $RET in + linux-x86_64) + if [ "$TRY64" = "no" ]; then + RET=linux-x86 + fi + ;; + darwin-x86_64) + if [ "$TRY64" = "no" ]; then + RET=darwin-x86 + fi + ;; + esac + echo $RET +} + +# Return the executable suffix corresponding to host executables +get_prebuilt_host_exe_ext () +{ + if [ "$MINGW" = "yes" ]; then + echo ".exe" + else + echo "" + fi +} + +# Get library suffix for given ABI +# $1: ABI +# Return: .so or .bc +get_lib_suffix_for_abi () +{ + local ABI=$1 + echo ".so" +} + +# Convert an ABI name into an Architecture name +# $1: ABI name +# Result: Arch name +convert_abi_to_arch () +{ + local RET + local ABI=$1 + case $ABI in + armeabi|armeabi-v7a|armeabi-v7a-hard) + RET=arm + ;; + x86|mips|x86_64|mips64) + RET=$ABI + ;; + mips32r6) + RET=mips + ;; + arm64-v8a) + RET=arm64 + ;; + *) + >&2 echo "ERROR: Unsupported ABI name: $ABI, use one of: armeabi, armeabi-v7a, x86, mips, armeabi-v7a-hard, arm64-v8a, x86_64 or mips64" + exit 1 + ;; + esac + echo "$RET" +} + +# Take architecture name as input, and output the list of corresponding ABIs +# Inverse for convert_abi_to_arch +# $1: ARCH name +# Out: ABI names list (comma-separated) +convert_arch_to_abi () +{ + local RET + local ARCH=$1 + case $ARCH in + arm) + RET=armeabi,armeabi-v7a,armeabi-v7a-hard + ;; + x86|x86_64|mips|mips64) + RET=$ARCH + ;; + arm64) + RET=arm64-v8a + ;; + *) + >&2 echo "ERROR: Unsupported ARCH name: $ARCH, use one of: arm, x86, mips" + exit 1 + ;; + esac + echo "$RET" +} + +# Take a list of architecture names as input, and output the list of corresponding ABIs +# $1: ARCH names list (separated by spaces or commas) +# Out: ABI names list (comma-separated) +convert_archs_to_abis () +{ + local RET + for ARCH in $(commas_to_spaces $@); do + ABI=$(convert_arch_to_abi $ARCH) + if [ -n "$ABI" ]; then + if [ -n "$RET" ]; then + RET=$RET",$ABI" + else + RET=$ABI + fi + else # Error message is printed by convert_arch_to_abi + exit 1 + fi + done + echo "$RET" +} + +# Return the default toolchain binary path prefix for given architecture and gcc version +# For example: arm 4.8 -> toolchains/arm-linux-androideabi-4.8/prebuilt/<system>/bin/arm-linux-androideabi- +# $1: Architecture name +# $2: GCC version +# $3: optional, system name, defaults to $HOST_TAG +get_toolchain_binprefix_for_arch () +{ + local NAME PREFIX DIR BINPREFIX + local SYSTEM=${3:-$(get_prebuilt_host_tag)} + NAME=$(get_toolchain_name_for_arch $1 $2) + PREFIX=$(get_default_toolchain_prefix_for_arch $1) + DIR=$(get_toolchain_install . $NAME $SYSTEM) + BINPREFIX=${DIR#./}/bin/$PREFIX- + echo "$BINPREFIX" +} + +# Return llvm toolchain binary path prefix for given llvm version +# $1: llvm version +# $2: optional, system name, defaults to $HOST_TAG +get_llvm_toolchain_binprefix () +{ + local NAME DIR BINPREFIX + local SYSTEM=${2:-$(get_prebuilt_host_tag)} + NAME=llvm-$1 + DIR=$(get_toolchain_install . $NAME $SYSTEM) + BINPREFIX=${DIR#./}/bin/ + echo "$BINPREFIX" +} + +# Return default API level for a given arch +# This is the level used to build the toolchains. +# +# $1: Architecture name +get_default_api_level_for_arch () +{ + # For now, always build the toolchain against API level 9 for 32-bit arch + # and API level $FIRST_API64_LEVEL for 64-bit arch + case $1 in + *64) echo $FIRST_API64_LEVEL ;; + *) echo 9 ;; + esac +} + +# Return the default platform sysroot corresponding to a given architecture +# This is the sysroot used to build the toolchain and other binaries like +# the STLport libraries. +# $1: Architecture name +get_default_platform_sysroot_for_arch () +{ + local ARCH=$1 + local LEVEL=$(get_default_api_level_for_arch $ARCH) + + if [ "$ARCH" != "${ARCH%%64*}" ] ; then + LEVEL=$FIRST_API64_LEVEL + fi + echo "platforms/android-$LEVEL/arch-$ARCH" +} + +# Return the default platform sysroot corresponding to a given abi +# $1: ABI +get_default_platform_sysroot_for_abi () +{ + local ARCH=$(convert_abi_to_arch $1) + $(get_default_platform_sysroot_for_arch $ARCH) +} + +# Return the default libs dir corresponding to a given architecture +# $1: Architecture name +# $2: Optional llvm version +get_default_libdir_for_arch () +{ + case $1 in + x86_64|mips64) echo "lib64" ;; + arm64) echo "lib" ;; # return "lib" until aarch64 is built to look for sysroot/usr/lib64 + *) echo "lib" ;; + esac +} + +# Return the default libs dir corresponding to a given abi +# $1: ABI +# $2: Optional llvm version +get_default_libdir_for_abi () +{ + local ARCH + + case $1 in + mips32r6) echo "libr6" ;; + *) + local ARCH=$(convert_abi_to_arch $1) + echo "$(get_default_libdir_for_arch $ARCH $2)" + ;; + esac +} + +# Return the host/build specific path for prebuilt toolchain binaries +# relative to $1. +# +# $1: target root NDK directory +# $2: toolchain name +# $3: optional, host system name +# +get_toolchain_install () +{ + local NDK="$1" + shift + echo "$NDK/$(get_toolchain_install_subdir "$@")" +} + +# $1: toolchain name +# $2: optional, host system name +get_toolchain_install_subdir () +{ + local SYSTEM=${2:-$(get_prebuilt_host_tag)} + echo "toolchains/$1/prebuilt/$SYSTEM" +} + +# Return the relative install prefix for prebuilt host +# executables (relative to the NDK top directory). +# NOTE: This deals with MINGW==yes or DARWIN==yes appropriately +# +# $1: optional, system name +# Out: relative path to prebuilt install prefix +get_prebuilt_install_prefix () +{ + local TAG=${1:-$(get_prebuilt_host_tag)} + echo "prebuilt/$TAG" +} + +# Return the relative path of an installed prebuilt host +# executable +# NOTE: This deals with MINGW==yes or DARWIN==yes appropriately. +# +# $1: executable name +# $2: optional, host system name +# Out: path to prebuilt host executable, relative +get_prebuilt_host_exec () +{ + local PREFIX EXE + PREFIX=$(get_prebuilt_install_prefix $2) + EXE=$(get_prebuilt_host_exe_ext) + echo "$PREFIX/bin/$1$EXE" +} + +# Return the name of a given host executable +# $1: executable base name +# Out: executable name, with optional suffix (e.g. .exe for windows) +get_host_exec_name () +{ + local EXE=$(get_prebuilt_host_exe_ext) + echo "$1$EXE" +} + +# Return the directory where host-specific binaries are installed. +# $1: target root NDK directory +get_host_install () +{ + echo "$1/$(get_prebuilt_install_prefix)" +} + +# Set the toolchain target NDK location. +# this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX +# $1: target NDK path +# $2: toolchain name +set_toolchain_ndk () +{ + TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` + log "Using toolchain path: $TOOLCHAIN_PATH" + + TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET + log "Using toolchain prefix: $TOOLCHAIN_PREFIX" +} + +# Check that a toolchain is properly installed at a target NDK location +# +# $1: target root NDK directory +# $2: toolchain name +# +check_toolchain_install () +{ + TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` + if [ ! -d "$TOOLCHAIN_PATH" ] ; then + echo "ERROR: Cannot find directory '$TOOLCHAIN_PATH'!" + echo " Toolchain '$2' not installed in '$NDK_DIR'!" + echo " Ensure that the toolchain has been installed there before." + exit 1 + fi + + set_toolchain_ndk $1 $2 +} + +# $1: toolchain source directory +check_toolchain_src_dir () +{ + local SRC_DIR="$1" + 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" ]; then + echo "ERROR: Either the file $SRC_DIR/build/configure or" + echo " the directory $SRC_DIR/gcc does not exist." + echo "This is not the top of a toolchain tree: $SRC_DIR" + exit 1 + fi +} + +# +# The NDK_TMPDIR variable is used to specify a root temporary directory +# when invoking toolchain build scripts. If it is not defined, we will +# create one here, and export the value to ensure that any scripts we +# call after that use the same one. +# +if [ -z "$NDK_TMPDIR" ]; then + + NDK_TMPDIR=$TMPDIR/tmp/build-$$ + mkdir -p $NDK_TMPDIR + if [ $? != 0 ]; then + echo "ERROR: Could not create NDK_TMPDIR: $NDK_TMPDIR" + exit 1 + fi + export NDK_TMPDIR +fi + +# Define HOST_TAG32, as the 32-bit version of HOST_TAG +# We do this by replacing an -x86_64 suffix by -x86 +HOST_TAG32=$HOST_TAG +case $HOST_TAG32 in + *-x86_64) + HOST_TAG32=${HOST_TAG%%_64} + ;; +esac + +# this function should be called after all options are extracted +CACHE_HOST_TAG=linux-x86 +set_cache_host_tag () +{ + if [ "$MINGW" = "yes" ] ; then + if [ "$TRY64" = "yes" ]; then + CACHE_HOST_TAG=windows-x86_64 + else + CACHE_HOST_TAG=windows + fi + elif [ "$DARWIN" = "yes" -o "$HOST_OS" = "darwin" ] ; then + if [ "$TRY64" = "yes" ]; then + CACHE_HOST_TAG=darwin-x86_64 + else + CACHE_HOST_TAG=darwin-x86 + fi + else + if [ "$TRY64" = "yes" ]; then + CACHE_HOST_TAG=linux-x86_64 + fi + fi +} + +assert_cache_host_tag () +{ + if [ "$CACHE_HOST_TAG" != "$HOST_TAG" ]; then + fail_panic "ASSERT in $PROGNAME: $CACHE_HOST_TAG != $HOST_TAG" + fi +} diff --git a/scripts/update.sh b/scripts/update.sh index e34a6261..66211203 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -31,4 +31,4 @@ git pull cd ../.. cd src/viper git pull -cd ../..
\ No newline at end of file +cd ../.. |