Home | History | Annotate | Download | only in tools
      1 #!/bin/sh
      2 #
      3 # Copyright (C) 2012 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 #  This shell script is used to rebuild the llvm and clang binaries
     18 #  for the Android NDK.
     19 #
     20 
     21 # include common function and variable definitions
     22 . `dirname $0`/prebuilt-common.sh
     23 
     24 PROGRAM_PARAMETERS="<src-dir> <ndk-dir> <toolchain>"
     25 
     26 PROGRAM_DESCRIPTION=\
     27 "Rebuild the LLVM prebuilt binaries for the Android NDK.
     28 
     29 Where <src-dir> is the location of toolchain sources, <ndk-dir> is
     30 the top-level NDK installation path and <toolchain> is the name of
     31 the toolchain to use (e.g. llvm-3.3)."
     32 
     33 RELEASE=`date +%Y%m%d`
     34 BUILD_OUT=/tmp/ndk-$USER/build/toolchain
     35 OPTION_BUILD_OUT=
     36 register_var_option "--build-out=<path>" OPTION_BUILD_OUT "Set temporary build directory"
     37 
     38 # Note: platform API level 9 or higher is needed for proper C++ support
     39 PLATFORM=$DEFAULT_PLATFORM
     40 register_var_option "--platform=<name>"  PLATFORM "Specify platform name"
     41 
     42 GMP_VERSION=$DEFAULT_GMP_VERSION
     43 register_var_option "--gmp-version=<version>" GMP_VERSION "Specify gmp version"
     44 
     45 PACKAGE_DIR=
     46 register_var_option "--package-dir=<path>" PACKAGE_DIR "Create archive tarball in specific directory"
     47 
     48 WINE=wine
     49 register_var_option "--wine=<path>" WINE "WINE needed to run llvm-config.exe for building mclinker with --mingw"
     50 
     51 POLLY=no
     52 do_polly_option () { POLLY=yes; }
     53 register_option "--with-polly" do_polly_option "Enable Polyhedral optimizations for LLVM"
     54 
     55 CHECK=no
     56 do_check_option () { CHECK=yes; }
     57 register_option "--check" do_check_option "Check LLVM"
     58 
     59 register_jobs_option
     60 register_canadian_option
     61 register_try64_option
     62 
     63 extract_parameters "$@"
     64 
     65 prepare_canadian_toolchain /tmp/ndk-$USER/build
     66 
     67 fix_option BUILD_OUT "$OPTION_BUILD_OUT" "build directory"
     68 setup_default_log_file $BUILD_OUT/config.log
     69 
     70 set_parameters ()
     71 {
     72     SRC_DIR="$1"
     73     NDK_DIR="$2"
     74     TOOLCHAIN="$3"
     75 
     76     # Check source directory
     77     #
     78     if [ -z "$SRC_DIR" ] ; then
     79         echo "ERROR: Missing source directory parameter. See --help for details."
     80         exit 1
     81     fi
     82 
     83     if [ ! -d "$SRC_DIR/$TOOLCHAIN/llvm" ] ; then
     84         echo "ERROR: Source directory does not contain llvm sources: $SRC_DIR/$TOOLCHAIN/llvm"
     85         exit 1
     86     fi
     87 
     88     if [ -e "$SRC_DIR/$TOOLCHAIN/llvm/tools/polly" -a ! -h "$SRC_DIR/$TOOLCHAIN/llvm/tools/polly" ] ; then
     89         echo "ERROR: polly, if exist, needs to be a symbolic link: $SRC_DIR/$TOOLCHAIN/llvm/tools/polly"
     90         exit 1
     91     fi
     92 
     93     GMP_SOURCE=$SRC_DIR/gmp/gmp-$GMP_VERSION.tar.bz2
     94     if [ ! -f "$GMP_SOURCE" ] ; then
     95         echo "ERROR: Source directory does not contain gmp: $GMP_SOURCE"
     96         exit 1
     97     fi
     98     SRC_DIR=`cd $SRC_DIR; pwd`
     99     log "Using source directory: $SRC_DIR"
    100 
    101     # Check NDK installation directory
    102     #
    103     if [ -z "$NDK_DIR" ] ; then
    104         echo "ERROR: Missing NDK directory parameter. See --help for details."
    105         exit 1
    106     fi
    107 
    108     if [ ! -d "$NDK_DIR" ] ; then
    109         mkdir -p $NDK_DIR
    110         if [ $? != 0 ] ; then
    111             echo "ERROR: Could not create target NDK installation path: $NDK_DIR"
    112             exit 1
    113         fi
    114     fi
    115     NDK_DIR=`cd $NDK_DIR; pwd`
    116     log "Using NDK directory: $NDK_DIR"
    117 
    118     # Check toolchain name
    119     #
    120     if [ -z "$TOOLCHAIN" ] ; then
    121         echo "ERROR: Missing toolchain name parameter. See --help for details."
    122         exit 1
    123     fi
    124 }
    125 
    126 set_parameters $PARAMETERS
    127 
    128 prepare_target_build
    129 
    130 if [ "$PACKAGE_DIR" ]; then
    131     mkdir -p "$PACKAGE_DIR"
    132     fail_panic "Could not create package directory: $PACKAGE_DIR"
    133 fi
    134 
    135 set_toolchain_ndk $NDK_DIR $TOOLCHAIN
    136 
    137 if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then
    138     dump "Using C compiler: $CC"
    139     dump "Using C++ compiler: $CXX"
    140 fi
    141 
    142 rm -rf $BUILD_OUT
    143 mkdir -p $BUILD_OUT
    144 
    145 MAKE_FLAGS=
    146 if [ "$VERBOSE" = "yes" ]; then
    147     MAKE_FLAGS="VERBOSE=1"
    148 fi
    149 
    150 TOOLCHAIN_BUILD_PREFIX=$BUILD_OUT/prefix
    151 
    152 ARCH=$HOST_ARCH
    153 
    154 # Note that the following 2 flags only apply for BUILD_CC in canadian cross build
    155 CFLAGS_FOR_BUILD="-O2 -I$TOOLCHAIN_BUILD_PREFIX/include"
    156 LDFLAGS_FOR_BUILD="-L$TOOLCHAIN_BUILD_PREFIX/lib"
    157 
    158 # Eliminate dependency on libgcc_s_sjlj-1.dll and libstdc++-6.dll on cross builds
    159 if [ "$DARWIN" = "yes" -o "$MINGW" = "yes" ]; then
    160     LDFLAGS_FOR_BUILD=$LDFLAGS_FOR_BUILD" -static-libgcc -static-libstdc++"
    161 fi
    162 
    163 CFLAGS="$CFLAGS $CFLAGS_FOR_BUILD $HOST_CFLAGS"
    164 CXXFLAGS="$CXXFLAGS $CFLAGS_FOR_BUILD $HOST_CFLAGS"  # polly doesn't look at CFLAGS !
    165 LDFLAGS="$LDFLAGS $LDFLAGS_FOR_BUILD $HOST_LDFLAGS"
    166 export CC CXX CFLAGS CXXFLAGS LDFLAGS CFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD REQUIRES_RTTI=1 ARCH
    167 
    168 if [ "$DARWIN" = "yes" ]; then
    169     # To stop /usr/bin/install -s calls strip on darwin binary
    170     export KEEP_SYMBOLS=1
    171     # Disable polly for now
    172     POLLY=no
    173 fi
    174 
    175 if [ "$POLLY" = "yes" -a ! -d "$SRC_DIR/$TOOLCHAIN/polly" ] ; then
    176     dump "Disable polly because $SRC_DIR/$TOOLCHAIN/polly doesn't exist"
    177     POLLY=no
    178 fi
    179 
    180 EXTRA_CONFIG_FLAGS=
    181 rm -rf $SRC_DIR/$TOOLCHAIN/llvm/tools/polly
    182 if [ "$POLLY" = "yes" ]; then
    183     # crate symbolic link
    184     ln -s ../../polly $SRC_DIR/$TOOLCHAIN/llvm/tools
    185 
    186     # build polly dependencies
    187     unpack_archive "$GMP_SOURCE" "$BUILD_OUT"
    188     fail_panic "Couldn't unpack $SRC_DIR/gmp/gmp-$GMP_VERSION to $BUILD_OUT"
    189 
    190     GMP_BUILD_OUT=$BUILD_OUT/gmp-$GMP_VERSION
    191     cd $GMP_BUILD_OUT
    192     fail_panic "Couldn't cd into gmp build path: $GMP_BUILD_OUT"
    193 
    194     OLD_ABI="${ABI}"
    195     export ABI=$HOST_GMP_ABI  # needed to build 32-bit on 64-bit host
    196     run ./configure \
    197         --prefix=$TOOLCHAIN_BUILD_PREFIX \
    198         --host=$ABI_CONFIGURE_HOST \
    199         --build=$ABI_CONFIGURE_BUILD \
    200         --disable-shared \
    201         --disable-nls \
    202         --enable-cxx
    203     fail_panic "Couldn't configure gmp"
    204     run make -j$NUM_JOBS
    205     fail_panic "Couldn't compile gmp"
    206     run make install
    207     fail_panic "Couldn't install gmp to $TOOLCHAIN_BUILD_PREFIX"
    208     ABI="$OLD_ABI"
    209 
    210     CLOOG_BUILD_OUT=$BUILD_OUT/cloog
    211     mkdir -p $CLOOG_BUILD_OUT && cd $CLOOG_BUILD_OUT
    212     fail_panic "Couldn't create cloog build path: $CLOOG_BUILD_OUT"
    213 
    214     run $SRC_DIR/$TOOLCHAIN/llvm/tools/polly/utils/cloog_src/configure \
    215         --prefix=$TOOLCHAIN_BUILD_PREFIX \
    216         --host=$ABI_CONFIGURE_HOST \
    217         --build=$ABI_CONFIGURE_BUILD \
    218         --with-gmp-prefix=$TOOLCHAIN_BUILD_PREFIX \
    219         --disable-shared \
    220         --disable-nls
    221     fail_panic "Couldn't configure cloog"
    222     run make -j$NUM_JOBS
    223     fail_panic "Couldn't compile cloog"
    224     run make install
    225     fail_panic "Couldn't install cloog to $TOOLCHAIN_BUILD_PREFIX"
    226 
    227     EXTRA_CONFIG_FLAGS="--with-cloog=$TOOLCHAIN_BUILD_PREFIX --with-isl=$TOOLCHAIN_BUILD_PREFIX"
    228 
    229     # Allow text relocs when linking LLVMPolly.dylib against statically linked libgmp.a
    230     if [ "$HOST_TAG32" = "darwin-x86" -o "$DARWIN" = "yes" ]; then   # -a "$HOST_ARCH" = "x86"
    231         LDFLAGS="$LDFLAGS -read_only_relocs suppress"
    232         export LDFLAGS
    233     fi
    234 fi # POLLY = yes
    235 
    236 # configure the toolchain
    237 dump "Configure: $TOOLCHAIN toolchain build"
    238 LLVM_BUILD_OUT=$BUILD_OUT/llvm
    239 mkdir -p $LLVM_BUILD_OUT && cd $LLVM_BUILD_OUT
    240 fail_panic "Couldn't cd into llvm build path: $LLVM_BUILD_OUT"
    241 
    242 run $SRC_DIR/$TOOLCHAIN/llvm/configure \
    243     --prefix=$TOOLCHAIN_BUILD_PREFIX \
    244     --host=$ABI_CONFIGURE_HOST \
    245     --build=$ABI_CONFIGURE_BUILD \
    246     --with-bug-report-url=$DEFAULT_ISSUE_TRACKER_URL \
    247     --enable-targets=arm,mips,x86 \
    248     --enable-optimized \
    249     --with-binutils-include=$SRC_DIR/binutils/binutils-$DEFAULT_BINUTILS_VERSION/include \
    250     $EXTRA_CONFIG_FLAGS
    251 fail_panic "Couldn't configure llvm toolchain"
    252 
    253 # build llvm/clang
    254 dump "Building : llvm toolchain [this can take a long time]."
    255 cd $LLVM_BUILD_OUT
    256 run make -j$NUM_JOBS $MAKE_FLAGS
    257 fail_panic "Couldn't compile llvm toolchain"
    258 
    259 if [ "$CHECK" = "yes" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then
    260     # run the regression test
    261     dump "Running  : llvm toolchain regression test"
    262     cd $LLVM_BUILD_OUT
    263     run make check-all
    264     fail_warning "Couldn't pass all llvm regression test"  # change to fail_panic later
    265     if [ "$POLLY" = "yes" ]; then
    266         dump "Running  : polly toolchain regression test"
    267         cd $LLVM_BUILD_OUT
    268         run make polly-test -C tools/polly/test
    269         fail_warning "Couldn't pass all polly regression test"  # change to fail_panic later
    270     fi
    271 fi
    272 
    273 # install the toolchain to its final location
    274 dump "Install  : llvm toolchain binaries"
    275 cd $LLVM_BUILD_OUT && run make install $MAKE_FLAGS
    276 fail_panic "Couldn't install llvm toolchain to $TOOLCHAIN_BUILD_PREFIX"
    277 
    278 # create llvm-config wrapper if needed.
    279 # llvm-config is invoked by other llvm projects (eg. mclinker/configure)
    280 # to figure out flags and libs dependencies.  Unfortunately in canadian-build
    281 # llvm-config[.exe] may not run directly.  Create a wrapper.
    282 LLVM_CONFIG=llvm-config
    283 if [ "$MINGW" = "yes" ] ; then
    284     LLVM_CONFIG=llvm-config.sh
    285     cat > $TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG <<EOF
    286 $WINE \`dirname \$0\`/llvm-config.exe "\$@"
    287 EOF
    288     chmod 0755 $TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG
    289 fi
    290 
    291 # build mclinker only against default the LLVM version, once
    292 if [ "$TOOLCHAIN" = "llvm-$DEFAULT_LLVM_VERSION" -a "$DARWIN" != "yes" ] ; then
    293     dump "Copy     : mclinker source"
    294     MCLINKER_SRC_DIR=$BUILD_OUT/mclinker
    295     mkdir -p $MCLINKER_SRC_DIR
    296     fail_panic "Couldn't create mclinker source directory: $MCLINKER_SRC_DIR"
    297 
    298     run copy_directory "$SRC_DIR/mclinker" "$MCLINKER_SRC_DIR"
    299     fail_panic "Couldn't copy mclinker source: $MCLINKER_SRC_DIR"
    300 
    301     CXXFLAGS="$CXXFLAGS -fexceptions"  # optimized/ScriptParser.cc needs it
    302     export CXXFLAGS
    303 
    304     cd $MCLINKER_SRC_DIR && run ./autogen.sh
    305     fail_panic "Couldn't run autogen.sh in $MCLINKER_SRC_DIR"
    306 
    307     dump "Configure: mclinker against $TOOLCHAIN"
    308     MCLINKER_BUILD_OUT=$MCLINKER_SRC_DIR/build
    309     mkdir -p $MCLINKER_BUILD_OUT && cd $MCLINKER_BUILD_OUT
    310     fail_panic "Couldn't cd into mclinker build path: $MCLINKER_BUILD_OUT"
    311 
    312     run $MCLINKER_SRC_DIR/configure \
    313         --prefix=$TOOLCHAIN_BUILD_PREFIX \
    314         --with-llvm-config=$TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG \
    315         --host=$ABI_CONFIGURE_HOST \
    316         --build=$ABI_CONFIGURE_BUILD
    317     fail_panic "Couldn't configure mclinker"
    318 
    319     dump "Building : mclinker"
    320     cd $MCLINKER_BUILD_OUT
    321     run make -j$NUM_JOBS $MAKE_FLAGS CXXFLAGS="$CXXFLAGS"
    322     fail_panic "Couldn't compile mclinker"
    323 
    324     dump "Install  : mclinker"
    325     cd $MCLINKER_BUILD_OUT && run make install $MAKE_FLAGS
    326     fail_panic "Couldn't install mclinker to $TOOLCHAIN_BUILD_PREFIX"
    327 
    328     if [ "$CHECK" = "yes" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then
    329         # run the regression test
    330         dump "Running  : mclinker regression test"
    331         cd $MCLINKER_BUILD_OUT
    332         run make check
    333         fail_warning "Couldn't pass all mclinker regression test"  # change to fail_panic later
    334     fi
    335 fi
    336 
    337 # remove redundant bits
    338 rm -rf $TOOLCHAIN_BUILD_PREFIX/docs
    339 rm -rf $TOOLCHAIN_BUILD_PREFIX/include
    340 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/*.a
    341 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/*.la
    342 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/pkgconfig
    343 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/lib[cp]*.so
    344 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/lib[cp]*.dylib
    345 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/B*.so
    346 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/B*.dylib
    347 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.so
    348 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.dylib
    349 rm -rf $TOOLCHAIN_BUILD_PREFIX/bin/ld.bcc*
    350 rm -rf $TOOLCHAIN_BUILD_PREFIX/share
    351 
    352 UNUSED_LLVM_EXECUTABLES="
    353 bugpoint c-index-test clang-check clang-format clang-tblgen lli llvm-as llvm-bcanalyzer
    354 llvm-config llvm-config-host llvm-cov llvm-diff llvm-dwarfdump llvm-extract llvm-ld
    355 llvm-mc llvm-nm llvm-mcmarkup llvm-objdump llvm-prof llvm-ranlib llvm-readobj llvm-rtdyld
    356 llvm-size llvm-stress llvm-stub llvm-symbolizer llvm-tblgen macho-dump cloog"
    357 
    358 for i in $UNUSED_LLVM_EXECUTABLES; do
    359     rm -f $TOOLCHAIN_BUILD_PREFIX/bin/$i
    360     rm -f $TOOLCHAIN_BUILD_PREFIX/bin/$i.exe
    361 done
    362 
    363 test -z "$STRIP" && STRIP=strip
    364 find $TOOLCHAIN_BUILD_PREFIX/bin -maxdepth 1 -type f -exec $STRIP {} \;
    365 # Note that MacOSX strip generate the follow error on .dylib:
    366 # "symbols referenced by indirect symbol table entries that can't be stripped "
    367 find $TOOLCHAIN_BUILD_PREFIX/lib -maxdepth 1 -type f \( -name "*.dll" -o -name "*.so" \) -exec $STRIP {} \;
    368 
    369 # install script
    370 cp -p "$SRC_DIR/$TOOLCHAIN/llvm/tools/ndk-bc2native/ndk-bc2native.py" "$TOOLCHAIN_BUILD_PREFIX/bin/"
    371 
    372 # copy to toolchain path
    373 run copy_directory "$TOOLCHAIN_BUILD_PREFIX" "$TOOLCHAIN_PATH"
    374 
    375 # create analyzer/++ scripts
    376 for ABI in $PREBUILT_ABIS; do
    377     ANALYZER_PATH="$TOOLCHAIN_PATH/bin/$ABI"
    378     ANALYZER="$ANALYZER_PATH/analyzer"
    379     mkdir -p "$ANALYZER_PATH"
    380     case "$ABI" in
    381       armeabi)
    382           LLVM_TARGET=armv5te-none-linux-androideabi
    383           ;;
    384       armeabi-v7a)
    385           LLVM_TARGET=armv7-none-linux-androideabi
    386           ;;
    387       x86)
    388           LLVM_TARGET=i686-none-linux-android
    389           ;;
    390       mips)
    391           LLVM_TARGET=mipsel-none-linux-android
    392           ;;
    393       *)
    394         dump "ERROR: Unsupported NDK ABI: $ABI"
    395         exit 1
    396     esac
    397 
    398     cat > "${ANALYZER}" <<EOF
    399 if [ "\$1" != "-cc1" ]; then
    400     \`dirname \$0\`/../clang -target $LLVM_TARGET "\$@"
    401 else
    402     # target/triple already spelled out.
    403     \`dirname \$0\`/../clang "\$@"
    404 fi
    405 EOF
    406     cat > "${ANALYZER}++" <<EOF
    407 if [ "\$1" != "-cc1" ]; then
    408     \`dirname \$0\`/../clang++ -target $LLVM_TARGET "\$@"
    409 else
    410     # target/triple already spelled out.
    411     \`dirname \$0\`/../clang++ "\$@"
    412 fi
    413 EOF
    414     chmod 0755 "${ANALYZER}" "${ANALYZER}++"
    415 
    416     if [ -n "$HOST_EXE" ] ; then
    417         cat > "${ANALYZER}.cmd" <<EOF
    418 @echo off
    419 if "%1" == "-cc1" goto :L
    420 %~dp0\\..\\clang${HOST_EXE} -target $LLVM_TARGET %*
    421 if ERRORLEVEL 1 exit /b 1
    422 goto :done
    423 :L
    424 rem target/triple already spelled out.
    425 %~dp0\\..\\clang${HOST_EXE} %*
    426 if ERRORLEVEL 1 exit /b 1
    427 :done
    428 EOF
    429         cat > "${ANALYZER}++.cmd" <<EOF
    430 @echo off
    431 if "%1" == "-cc1" goto :L
    432 %~dp0\\..\\clang++${HOST_EXE} -target $LLVM_TARGET %*
    433 if ERRORLEVEL 1 exit /b 1
    434 goto :done
    435 :L
    436 rem target/triple already spelled out.
    437 %~dp0\\..\\clang++${HOST_EXE} %*
    438 if ERRORLEVEL 1 exit /b 1
    439 :done
    440 EOF
    441     fi
    442 done
    443 
    444 if [ "$PACKAGE_DIR" ]; then
    445     ARCHIVE="$TOOLCHAIN-$HOST_TAG.tar.bz2"
    446     SUBDIR=$(get_toolchain_install_subdir $TOOLCHAIN $HOST_TAG)
    447     dump "Packaging $ARCHIVE"
    448     pack_archive "$PACKAGE_DIR/$ARCHIVE" "$NDK_DIR" "$SUBDIR"
    449 fi
    450 
    451 dump "Done."
    452 if [ -z "$OPTION_BUILD_OUT" ] ; then
    453     rm -rf $BUILD_OUT
    454 fi
    455