| #!/bin/sh |
| # |
| # Copyright (C) 2012 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| # This shell script is used to rebuild the llvm and clang binaries |
| # for the Android NDK. |
| # |
| |
| # include common function and variable definitions |
| . `dirname $0`/prebuilt-common.sh |
| |
| PROGRAM_PARAMETERS="<src-dir> <ndk-dir> <toolchain>" |
| |
| PROGRAM_DESCRIPTION=\ |
| "Rebuild the LLVM prebuilt binaries for the Android NDK. |
| |
| Where <src-dir> is the location of toolchain sources, <ndk-dir> is |
| the top-level NDK installation path and <toolchain> is the name of |
| the toolchain to use (e.g. llvm-3.2)." |
| |
| RELEASE=`date +%Y%m%d` |
| BUILD_OUT=/tmp/ndk-$USER/build/toolchain |
| OPTION_BUILD_OUT= |
| register_var_option "--build-out=<path>" OPTION_BUILD_OUT "Set temporary build directory" |
| |
| # Note: platform API level 9 or higher is needed for proper C++ support |
| PLATFORM=$DEFAULT_PLATFORM |
| register_var_option "--platform=<name>" PLATFORM "Specify platform name" |
| |
| GMP_VERSION=$DEFAULT_GMP_VERSION |
| register_var_option "--gmp-version=<version>" GMP_VERSION "Specify gmp version" |
| |
| PACKAGE_DIR= |
| register_var_option "--package-dir=<path>" PACKAGE_DIR "Create archive tarball in specific directory" |
| |
| WINE=wine |
| register_var_option "--wine=<path>" WINE "WINE needed to run llvm-config.exe for building mclinker with --mingw" |
| |
| POLLY=no |
| do_polly_option () { POLLY=yes; } |
| register_option "--with-polly" do_polly_option "Enable Polyhedral optimizations for LLVM" |
| |
| CHECK=no |
| do_check_option () { CHECK=yes; } |
| register_option "--check" do_check_option "Check LLVM" |
| |
| register_jobs_option |
| register_canadian_option |
| register_try64_option |
| |
| extract_parameters "$@" |
| |
| prepare_canadian_toolchain /tmp/ndk-$USER/build |
| |
| fix_option BUILD_OUT "$OPTION_BUILD_OUT" "build directory" |
| setup_default_log_file $BUILD_OUT/config.log |
| |
| set_parameters () |
| { |
| SRC_DIR=`cd $1; pwd` |
| NDK_DIR=`cd $2; pwd` |
| TOOLCHAIN="$3" |
| |
| # Check source directory |
| # |
| if [ -z "$SRC_DIR" ] ; then |
| echo "ERROR: Missing source directory parameter. See --help for details." |
| exit 1 |
| fi |
| |
| if [ ! -d "$SRC_DIR/$TOOLCHAIN/llvm" ] ; then |
| echo "ERROR: Source directory does not contain llvm sources: $SRC_DIR/$TOOLCHAIN/llvm" |
| exit 1 |
| fi |
| |
| if [ -e "$SRC_DIR/$TOOLCHAIN/llvm/tools/polly" -a ! -h "$SRC_DIR/$TOOLCHAIN/llvm/tools/polly" ] ; then |
| echo "ERROR: polly, if exist, needs to be a symbolic link: $SRC_DIR/$TOOLCHAIN/llvm/tools/polly" |
| exit 1 |
| fi |
| |
| GMP_SOURCE=$SRC_DIR/gmp/gmp-$GMP_VERSION.tar.bz2 |
| if [ ! -f "$GMP_SOURCE" ] ; then |
| echo "ERROR: Source directory does not contain gmp: $GMP_SOURCE" |
| exit 1 |
| fi |
| |
| log "Using source directory: $SRC_DIR" |
| |
| # Check NDK installation directory |
| # |
| if [ -z "$NDK_DIR" ] ; then |
| echo "ERROR: Missing NDK directory parameter. See --help for details." |
| exit 1 |
| fi |
| |
| if [ ! -d "$NDK_DIR" ] ; then |
| mkdir -p $NDK_DIR |
| if [ $? != 0 ] ; then |
| echo "ERROR: Could not create target NDK installation path: $NDK_DIR" |
| exit 1 |
| fi |
| fi |
| |
| log "Using NDK directory: $NDK_DIR" |
| |
| # Check toolchain name |
| # |
| if [ -z "$TOOLCHAIN" ] ; then |
| echo "ERROR: Missing toolchain name parameter. See --help for details." |
| exit 1 |
| fi |
| } |
| |
| set_parameters $PARAMETERS |
| |
| prepare_target_build |
| |
| if [ "$PACKAGE_DIR" ]; then |
| mkdir -p "$PACKAGE_DIR" |
| fail_panic "Could not create package directory: $PACKAGE_DIR" |
| fi |
| |
| set_toolchain_ndk $NDK_DIR $TOOLCHAIN |
| |
| if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then |
| dump "Using C compiler: $CC" |
| dump "Using C++ compiler: $CXX" |
| fi |
| |
| rm -rf $BUILD_OUT |
| mkdir -p $BUILD_OUT |
| |
| MAKE_FLAGS= |
| if [ "$VERBOSE" = "yes" ]; then |
| MAKE_FLAGS="VERBOSE=1" |
| fi |
| |
| TOOLCHAIN_BUILD_PREFIX=$BUILD_OUT/prefix |
| |
| ARCH=$HOST_ARCH |
| |
| # Note that the following 2 flags only apply for BUILD_CC in canadian cross build |
| CFLAGS_FOR_BUILD="-O2 -I$TOOLCHAIN_BUILD_PREFIX/include" |
| LDFLAGS_FOR_BUILD="-L$TOOLCHAIN_BUILD_PREFIX/lib" |
| |
| # Eliminate dependency on libgcc_s_sjlj-1.dll and libstdc++-6.dll on cross builds |
| if [ "$DARWIN" = "yes" -o "$MINGW" = "yes" ]; then |
| LDFLAGS_FOR_BUILD=$LDFLAGS_FOR_BUILD" -static-libgcc -static-libstdc++" |
| fi |
| |
| CFLAGS="$CFLAGS $CFLAGS_FOR_BUILD $HOST_CFLAGS" |
| CXXFLAGS="$CXXFLAGS $CFLAGS_FOR_BUILD $HOST_CFLAGS" # polly doesn't look at CFLAGS ! |
| LDFLAGS="$LDFLAGS $LDFLAGS_FOR_BUILD $HOST_LDFLAGS" |
| export CC CXX CFLAGS CXXFLAGS LDFLAGS CFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD REQUIRES_RTTI=1 ARCH |
| |
| if [ "$DARWIN" = "yes" ]; then |
| # To stop /usr/bin/install -s calls strip on darwin binary |
| export KEEP_SYMBOLS=1 |
| # Disable polly for now |
| POLLY=no |
| fi |
| |
| if [ "$POLLY" = "yes" -a ! -d "$SRC_DIR/$TOOLCHAIN/polly" ] ; then |
| dump "Disable polly because $SRC_DIR/$TOOLCHAIN/polly doesn't exist" |
| POLLY=no |
| fi |
| |
| EXTRA_CONFIG_FLAGS= |
| rm -rf $SRC_DIR/$TOOLCHAIN/llvm/tools/polly |
| if [ "$POLLY" = "yes" ]; then |
| # crate symbolic link |
| ln -s ../../polly $SRC_DIR/$TOOLCHAIN/llvm/tools |
| |
| # build polly dependencies |
| unpack_archive "$GMP_SOURCE" "$BUILD_OUT" |
| fail_panic "Couldn't unpack $SRC_DIR/gmp/gmp-$GMP_VERSION to $BUILD_OUT" |
| |
| GMP_BUILD_OUT=$BUILD_OUT/gmp-$GMP_VERSION |
| cd $GMP_BUILD_OUT |
| fail_panic "Couldn't cd into gmp build path: $GMP_BUILD_OUT" |
| |
| OLD_ABI="${ABI}" |
| export ABI=$HOST_GMP_ABI # needed to build 32-bit on 64-bit host |
| run ./configure \ |
| --prefix=$TOOLCHAIN_BUILD_PREFIX \ |
| --host=$ABI_CONFIGURE_HOST \ |
| --build=$ABI_CONFIGURE_BUILD \ |
| --disable-shared \ |
| --disable-nls \ |
| --enable-cxx |
| fail_panic "Couldn't configure gmp" |
| run make -j$NUM_JOBS |
| fail_panic "Couldn't compile gmp" |
| run make install |
| fail_panic "Couldn't install gmp to $TOOLCHAIN_BUILD_PREFIX" |
| ABI="$OLD_ABI" |
| |
| CLOOG_BUILD_OUT=$BUILD_OUT/cloog |
| mkdir -p $CLOOG_BUILD_OUT && cd $CLOOG_BUILD_OUT |
| fail_panic "Couldn't create cloog build path: $CLOOG_BUILD_OUT" |
| |
| run $SRC_DIR/$TOOLCHAIN/llvm/tools/polly/utils/cloog_src/configure \ |
| --prefix=$TOOLCHAIN_BUILD_PREFIX \ |
| --host=$ABI_CONFIGURE_HOST \ |
| --build=$ABI_CONFIGURE_BUILD \ |
| --with-gmp-prefix=$TOOLCHAIN_BUILD_PREFIX \ |
| --disable-shared \ |
| --disable-nls |
| fail_panic "Couldn't configure cloog" |
| run make -j$NUM_JOBS |
| fail_panic "Couldn't compile cloog" |
| run make install |
| fail_panic "Couldn't install cloog to $TOOLCHAIN_BUILD_PREFIX" |
| |
| EXTRA_CONFIG_FLAGS="--with-cloog=$TOOLCHAIN_BUILD_PREFIX --with-isl=$TOOLCHAIN_BUILD_PREFIX" |
| |
| # Allow text relocs when linking LLVMPolly.dylib against statically linked libgmp.a |
| if [ "$HOST_TAG32" = "darwin-x86" -o "$DARWIN" = "yes" ]; then # -a "$HOST_ARCH" = "x86" |
| LDFLAGS="$LDFLAGS -read_only_relocs suppress" |
| export LDFLAGS |
| fi |
| fi # POLLY = yes |
| |
| # configure the toolchain |
| dump "Configure: $TOOLCHAIN toolchain build" |
| LLVM_BUILD_OUT=$BUILD_OUT/llvm |
| mkdir -p $LLVM_BUILD_OUT && cd $LLVM_BUILD_OUT |
| fail_panic "Couldn't cd into llvm build path: $LLVM_BUILD_OUT" |
| |
| run $SRC_DIR/$TOOLCHAIN/llvm/configure \ |
| --prefix=$TOOLCHAIN_BUILD_PREFIX \ |
| --host=$ABI_CONFIGURE_HOST \ |
| --build=$ABI_CONFIGURE_BUILD \ |
| --with-bug-report-url=$DEFAULT_ISSUE_TRACKER_URL \ |
| --enable-targets=arm,mips,x86 \ |
| --enable-optimized \ |
| --with-binutils-include=$SRC_DIR/binutils/binutils-$DEFAULT_BINUTILS_VERSION/include \ |
| $EXTRA_CONFIG_FLAGS |
| fail_panic "Couldn't configure llvm toolchain" |
| |
| # build llvm/clang |
| dump "Building : llvm toolchain [this can take a long time]." |
| cd $LLVM_BUILD_OUT |
| run make -j$NUM_JOBS $MAKE_FLAGS |
| fail_panic "Couldn't compile llvm toolchain" |
| |
| if [ "$CHECK" = "yes" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then |
| # run the regression test |
| dump "Running : llvm toolchain regression test" |
| cd $LLVM_BUILD_OUT |
| run make check-all |
| fail_warning "Couldn't pass all llvm regression test" # change to fail_panic later |
| if [ "$POLLY" = "yes" ]; then |
| dump "Running : polly toolchain regression test" |
| cd $LLVM_BUILD_OUT |
| run make polly-test -C tools/polly/test |
| fail_warning "Couldn't pass all polly regression test" # change to fail_panic later |
| fi |
| fi |
| |
| # install the toolchain to its final location |
| dump "Install : llvm toolchain binaries" |
| cd $LLVM_BUILD_OUT && run make install $MAKE_FLAGS |
| fail_panic "Couldn't install llvm toolchain to $TOOLCHAIN_BUILD_PREFIX" |
| |
| # create llvm-config wrapper if needed. |
| # llvm-config is invoked by other llvm projects (eg. mclinker/configure) |
| # to figure out flags and libs dependencies. Unfortunately in canadian-build |
| # llvm-config[.exe] may not run directly. Create a wrapper. |
| LLVM_CONFIG=llvm-config |
| if [ "$MINGW" = "yes" ] ; then |
| LLVM_CONFIG=llvm-config.sh |
| cat > $TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG <<EOF |
| $WINE \`dirname \$0\`/llvm-config.exe "\$@" |
| EOF |
| chmod 0755 $TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG |
| fi |
| |
| # build mclinker only against default the LLVM version, once |
| if [ "$TOOLCHAIN" = "llvm-$DEFAULT_LLVM_VERSION" -a "$DARWIN" != "yes" ] ; then |
| dump "Copy : mclinker source" |
| MCLINKER_SRC_DIR=$BUILD_OUT/mclinker |
| mkdir -p $MCLINKER_SRC_DIR |
| fail_panic "Couldn't create mclinker source directory: $MCLINKER_SRC_DIR" |
| |
| run copy_directory "$SRC_DIR/mclinker" "$MCLINKER_SRC_DIR" |
| fail_panic "Couldn't copy mclinker source: $MCLINKER_SRC_DIR" |
| |
| cd $MCLINKER_SRC_DIR && run ./autogen.sh |
| fail_panic "Couldn't run autogen.sh in $MCLINKER_SRC_DIR" |
| |
| dump "Configure: mclinker against $TOOLCHAIN" |
| MCLINKER_BUILD_OUT=$MCLINKER_SRC_DIR/build |
| mkdir -p $MCLINKER_BUILD_OUT && cd $MCLINKER_BUILD_OUT |
| fail_panic "Couldn't cd into mclinker build path: $MCLINKER_BUILD_OUT" |
| |
| run $MCLINKER_SRC_DIR/configure \ |
| --prefix=$TOOLCHAIN_BUILD_PREFIX \ |
| --with-llvm-config=$TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG \ |
| --host=$ABI_CONFIGURE_HOST \ |
| --build=$ABI_CONFIGURE_BUILD |
| fail_panic "Couldn't configure mclinker" |
| |
| dump "Building : mclinker" |
| cd $MCLINKER_BUILD_OUT |
| run make -j$NUM_JOBS $MAKE_FLAGS |
| fail_panic "Couldn't compile mclinker" |
| |
| dump "Install : mclinker" |
| cd $MCLINKER_BUILD_OUT && run make install $MAKE_FLAGS |
| fail_panic "Couldn't install mclinker to $TOOLCHAIN_BUILD_PREFIX" |
| |
| if [ "$CHECK" = "yes" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then |
| # run the regression test |
| dump "Running : mclinker regression test" |
| cd $MCLINKER_BUILD_OUT |
| run make check |
| fail_warning "Couldn't pass all mclinker regression test" # change to fail_panic later |
| fi |
| fi |
| |
| # remove redundant bits |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/docs |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/include |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/*.a |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/*.la |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/pkgconfig |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/lib[cp]*.so |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/lib[cp]*.dylib |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/B*.so |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/B*.dylib |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.so |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.dylib |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/bin/ld.bcc* |
| rm -rf $TOOLCHAIN_BUILD_PREFIX/share |
| |
| UNUSED_LLVM_EXECUTABLES=" |
| bugpoint c-index-test clang-check clang-tblgen lli llvm-as llvm-bcanalyzer |
| llvm-config llvm-config-host llvm-cov llvm-diff llvm-dwarfdump llvm-extract llvm-ld |
| llvm-mc llvm-nm llvm-mcmarkup llvm-objdump llvm-prof llvm-ranlib llvm-readobj llvm-rtdyld |
| llvm-size llvm-stress llvm-stub llvm-tblgen macho-dump cloog" |
| |
| for i in $UNUSED_LLVM_EXECUTABLES; do |
| rm -f $TOOLCHAIN_BUILD_PREFIX/bin/$i |
| rm -f $TOOLCHAIN_BUILD_PREFIX/bin/$i.exe |
| done |
| |
| test -z "$STRIP" && STRIP=strip |
| find $TOOLCHAIN_BUILD_PREFIX/bin -maxdepth 1 -type f -exec $STRIP {} \; |
| # Note that MacOSX strip generate the follow error on .dylib: |
| # "symbols referenced by indirect symbol table entries that can't be stripped " |
| find $TOOLCHAIN_BUILD_PREFIX/lib -maxdepth 1 -type f \( -name "*.dll" -o -name "*.so" \) -exec $STRIP {} \; |
| |
| # copy to toolchain path |
| run copy_directory "$TOOLCHAIN_BUILD_PREFIX" "$TOOLCHAIN_PATH" |
| |
| # create analyzer/++ scripts |
| for ABI in $PREBUILT_ABIS; do |
| ANALYZER_PATH="$TOOLCHAIN_PATH/bin/$ABI" |
| ANALYZER="$ANALYZER_PATH/analyzer" |
| mkdir -p "$ANALYZER_PATH" |
| case "$ABI" in |
| armeabi) |
| LLVM_TARGET=armv5te-none-linux-androideabi |
| ;; |
| armeabi-v7a) |
| LLVM_TARGET=armv7-none-linux-androideabi |
| ;; |
| x86) |
| LLVM_TARGET=i686-none-linux-android |
| ;; |
| mips) |
| LLVM_TARGET=mipsel-none-linux-android |
| ;; |
| *) |
| dump "ERROR: Unsupported NDK ABI: $ABI" |
| exit 1 |
| esac |
| |
| cat > "${ANALYZER}" <<EOF |
| if [ "\$1" != "-cc1" ]; then |
| \`dirname \$0\`/../clang -target $LLVM_TARGET "\$@" |
| else |
| # target/triple already spelled out. |
| \`dirname \$0\`/../clang "\$@" |
| fi |
| EOF |
| cat > "${ANALYZER}++" <<EOF |
| if [ "\$1" != "-cc1" ]; then |
| \`dirname \$0\`/../clang++ -target $LLVM_TARGET "\$@" |
| else |
| # target/triple already spelled out. |
| \`dirname \$0\`/../clang++ "\$@" |
| fi |
| EOF |
| chmod 0755 "${ANALYZER}" "${ANALYZER}++" |
| |
| if [ -n "$HOST_EXE" ] ; then |
| cat > "${ANALYZER}.cmd" <<EOF |
| @echo off |
| if "%1" == "-cc1" goto :L |
| %~dp0\\..\\clang${HOST_EXE} -target $LLVM_TARGET %* |
| if ERRORLEVEL 1 exit /b 1 |
| goto :done |
| :L |
| rem target/triple already spelled out. |
| %~dp0\\..\\clang${HOST_EXE} %* |
| if ERRORLEVEL 1 exit /b 1 |
| :done |
| EOF |
| cat > "${ANALYZER}++.cmd" <<EOF |
| @echo off |
| if "%1" == "-cc1" goto :L |
| %~dp0\\..\\clang++${HOST_EXE} -target $LLVM_TARGET %* |
| if ERRORLEVEL 1 exit /b 1 |
| goto :done |
| :L |
| rem target/triple already spelled out. |
| %~dp0\\..\\clang++${HOST_EXE} %* |
| if ERRORLEVEL 1 exit /b 1 |
| :done |
| EOF |
| fi |
| done |
| |
| if [ "$PACKAGE_DIR" ]; then |
| ARCHIVE="$TOOLCHAIN-$HOST_TAG.tar.bz2" |
| SUBDIR=$(get_toolchain_install_subdir $TOOLCHAIN $HOST_TAG) |
| dump "Packaging $ARCHIVE" |
| pack_archive "$PACKAGE_DIR/$ARCHIVE" "$NDK_DIR" "$SUBDIR" |
| fi |
| |
| dump "Done." |
| if [ -z "$OPTION_BUILD_OUT" ] ; then |
| rm -rf $BUILD_OUT |
| fi |