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 24PROGRAM_PARAMETERS="<src-dir> <ndk-dir> <toolchain>" 25 26PROGRAM_DESCRIPTION=\ 27"Rebuild the LLVM prebuilt binaries for the Android NDK. 28 29Where <src-dir> is the location of toolchain sources, <ndk-dir> is 30the top-level NDK installation path and <toolchain> is the name of 31the toolchain to use (e.g. llvm-3.2)." 32 33RELEASE=`date +%Y%m%d` 34BUILD_OUT=/tmp/ndk-$USER/build/toolchain 35OPTION_BUILD_OUT= 36register_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 39PLATFORM=$DEFAULT_PLATFORM 40register_var_option "--platform=<name>" PLATFORM "Specify platform name" 41 42GMP_VERSION=$DEFAULT_GMP_VERSION 43register_var_option "--gmp-version=<version>" GMP_VERSION "Specify gmp version" 44 45PACKAGE_DIR= 46register_var_option "--package-dir=<path>" PACKAGE_DIR "Create archive tarball in specific directory" 47 48WINE=wine 49register_var_option "--wine=<path>" WINE "WINE needed to run llvm-config.exe for building mclinker with --mingw" 50 51POLLY=no 52do_polly_option () { POLLY=yes; } 53register_option "--with-polly" do_polly_option "Enable Polyhedral optimizations for LLVM" 54 55CHECK=no 56do_check_option () { CHECK=yes; } 57register_option "--check" do_check_option "Check LLVM" 58 59register_jobs_option 60register_canadian_option 61register_try64_option 62 63extract_parameters "$@" 64 65prepare_canadian_toolchain /tmp/ndk-$USER/build 66 67fix_option BUILD_OUT "$OPTION_BUILD_OUT" "build directory" 68setup_default_log_file $BUILD_OUT/config.log 69 70set_parameters () 71{ 72 SRC_DIR=`cd $1; pwd` 73 NDK_DIR=`cd $2; pwd` 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 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 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 126set_parameters $PARAMETERS 127 128prepare_target_build 129 130if [ "$PACKAGE_DIR" ]; then 131 mkdir -p "$PACKAGE_DIR" 132 fail_panic "Could not create package directory: $PACKAGE_DIR" 133fi 134 135set_toolchain_ndk $NDK_DIR $TOOLCHAIN 136 137if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then 138 dump "Using C compiler: $CC" 139 dump "Using C++ compiler: $CXX" 140fi 141 142rm -rf $BUILD_OUT 143mkdir -p $BUILD_OUT 144 145MAKE_FLAGS= 146if [ "$VERBOSE" = "yes" ]; then 147 MAKE_FLAGS="VERBOSE=1" 148fi 149 150TOOLCHAIN_BUILD_PREFIX=$BUILD_OUT/prefix 151 152ARCH=$HOST_ARCH 153 154# Note that the following 2 flags only apply for BUILD_CC in canadian cross build 155CFLAGS_FOR_BUILD="-O2 -I$TOOLCHAIN_BUILD_PREFIX/include" 156LDFLAGS_FOR_BUILD="-L$TOOLCHAIN_BUILD_PREFIX/lib" 157 158# Eliminate dependency on libgcc_s_sjlj-1.dll and libstdc++-6.dll on cross builds 159if [ "$DARWIN" = "yes" -o "$MINGW" = "yes" ]; then 160 LDFLAGS_FOR_BUILD=$LDFLAGS_FOR_BUILD" -static-libgcc -static-libstdc++" 161fi 162 163CFLAGS="$CFLAGS $CFLAGS_FOR_BUILD $HOST_CFLAGS" 164CXXFLAGS="$CXXFLAGS $CFLAGS_FOR_BUILD $HOST_CFLAGS" # polly doesn't look at CFLAGS ! 165LDFLAGS="$LDFLAGS $LDFLAGS_FOR_BUILD $HOST_LDFLAGS" 166export CC CXX CFLAGS CXXFLAGS LDFLAGS CFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD REQUIRES_RTTI=1 ARCH 167 168if [ "$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 173fi 174 175if [ "$POLLY" = "yes" -a ! -d "$SRC_DIR/$TOOLCHAIN/polly" ] ; then 176 dump "Disable polly because $SRC_DIR/$TOOLCHAIN/polly doesn't exist" 177 POLLY=no 178fi 179 180EXTRA_CONFIG_FLAGS= 181rm -rf $SRC_DIR/$TOOLCHAIN/llvm/tools/polly 182if [ "$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 234fi # POLLY = yes 235 236# configure the toolchain 237dump "Configure: $TOOLCHAIN toolchain build" 238LLVM_BUILD_OUT=$BUILD_OUT/llvm 239mkdir -p $LLVM_BUILD_OUT && cd $LLVM_BUILD_OUT 240fail_panic "Couldn't cd into llvm build path: $LLVM_BUILD_OUT" 241 242run $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 251fail_panic "Couldn't configure llvm toolchain" 252 253# build llvm/clang 254dump "Building : llvm toolchain [this can take a long time]." 255cd $LLVM_BUILD_OUT 256run make -j$NUM_JOBS $MAKE_FLAGS 257fail_panic "Couldn't compile llvm toolchain" 258 259if [ "$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 271fi 272 273# install the toolchain to its final location 274dump "Install : llvm toolchain binaries" 275cd $LLVM_BUILD_OUT && run make install $MAKE_FLAGS 276fail_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. 282LLVM_CONFIG=llvm-config 283if [ "$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 "\$@" 287EOF 288 chmod 0755 $TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG 289fi 290 291# build mclinker only against default the LLVM version, once 292if [ "$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 cd $MCLINKER_SRC_DIR && run ./autogen.sh 302 fail_panic "Couldn't run autogen.sh in $MCLINKER_SRC_DIR" 303 304 dump "Configure: mclinker against $TOOLCHAIN" 305 MCLINKER_BUILD_OUT=$MCLINKER_SRC_DIR/build 306 mkdir -p $MCLINKER_BUILD_OUT && cd $MCLINKER_BUILD_OUT 307 fail_panic "Couldn't cd into mclinker build path: $MCLINKER_BUILD_OUT" 308 309 run $MCLINKER_SRC_DIR/configure \ 310 --prefix=$TOOLCHAIN_BUILD_PREFIX \ 311 --with-llvm-config=$TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG \ 312 --host=$ABI_CONFIGURE_HOST \ 313 --build=$ABI_CONFIGURE_BUILD 314 fail_panic "Couldn't configure mclinker" 315 316 dump "Building : mclinker" 317 cd $MCLINKER_BUILD_OUT 318 run make -j$NUM_JOBS $MAKE_FLAGS 319 fail_panic "Couldn't compile mclinker" 320 321 dump "Install : mclinker" 322 cd $MCLINKER_BUILD_OUT && run make install $MAKE_FLAGS 323 fail_panic "Couldn't install mclinker to $TOOLCHAIN_BUILD_PREFIX" 324 325 if [ "$CHECK" = "yes" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then 326 # run the regression test 327 dump "Running : mclinker regression test" 328 cd $MCLINKER_BUILD_OUT 329 run make check 330 fail_warning "Couldn't pass all mclinker regression test" # change to fail_panic later 331 fi 332fi 333 334# remove redundant bits 335rm -rf $TOOLCHAIN_BUILD_PREFIX/docs 336rm -rf $TOOLCHAIN_BUILD_PREFIX/include 337rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/*.a 338rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/*.la 339rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/pkgconfig 340rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/lib[cp]*.so 341rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/lib[cp]*.dylib 342rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/B*.so 343rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/B*.dylib 344rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.so 345rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.dylib 346rm -rf $TOOLCHAIN_BUILD_PREFIX/bin/ld.bcc* 347rm -rf $TOOLCHAIN_BUILD_PREFIX/share 348 349UNUSED_LLVM_EXECUTABLES=" 350bugpoint c-index-test clang-check clang-tblgen lli llvm-as llvm-bcanalyzer 351llvm-config llvm-config-host llvm-cov llvm-diff llvm-dwarfdump llvm-extract llvm-ld 352llvm-mc llvm-nm llvm-mcmarkup llvm-objdump llvm-prof llvm-ranlib llvm-readobj llvm-rtdyld 353llvm-size llvm-stress llvm-stub llvm-tblgen macho-dump cloog" 354 355for i in $UNUSED_LLVM_EXECUTABLES; do 356 rm -f $TOOLCHAIN_BUILD_PREFIX/bin/$i 357 rm -f $TOOLCHAIN_BUILD_PREFIX/bin/$i.exe 358done 359 360test -z "$STRIP" && STRIP=strip 361find $TOOLCHAIN_BUILD_PREFIX/bin -maxdepth 1 -type f -exec $STRIP {} \; 362# Note that MacOSX strip generate the follow error on .dylib: 363# "symbols referenced by indirect symbol table entries that can't be stripped " 364find $TOOLCHAIN_BUILD_PREFIX/lib -maxdepth 1 -type f \( -name "*.dll" -o -name "*.so" \) -exec $STRIP {} \; 365 366# copy to toolchain path 367run copy_directory "$TOOLCHAIN_BUILD_PREFIX" "$TOOLCHAIN_PATH" 368 369# create analyzer/++ scripts 370for ABI in $PREBUILT_ABIS; do 371 ANALYZER_PATH="$TOOLCHAIN_PATH/bin/$ABI" 372 ANALYZER="$ANALYZER_PATH/analyzer" 373 mkdir -p "$ANALYZER_PATH" 374 case "$ABI" in 375 armeabi) 376 LLVM_TARGET=armv5te-none-linux-androideabi 377 ;; 378 armeabi-v7a) 379 LLVM_TARGET=armv7-none-linux-androideabi 380 ;; 381 x86) 382 LLVM_TARGET=i686-none-linux-android 383 ;; 384 mips) 385 LLVM_TARGET=mipsel-none-linux-android 386 ;; 387 *) 388 dump "ERROR: Unsupported NDK ABI: $ABI" 389 exit 1 390 esac 391 392 cat > "${ANALYZER}" <<EOF 393if [ "\$1" != "-cc1" ]; then 394 \`dirname \$0\`/../clang -target $LLVM_TARGET "\$@" 395else 396 # target/triple already spelled out. 397 \`dirname \$0\`/../clang "\$@" 398fi 399EOF 400 cat > "${ANALYZER}++" <<EOF 401if [ "\$1" != "-cc1" ]; then 402 \`dirname \$0\`/../clang++ -target $LLVM_TARGET "\$@" 403else 404 # target/triple already spelled out. 405 \`dirname \$0\`/../clang++ "\$@" 406fi 407EOF 408 chmod 0755 "${ANALYZER}" "${ANALYZER}++" 409 410 if [ -n "$HOST_EXE" ] ; then 411 cat > "${ANALYZER}.cmd" <<EOF 412@echo off 413if "%1" == "-cc1" goto :L 414%~dp0\\..\\clang${HOST_EXE} -target $LLVM_TARGET %* 415if ERRORLEVEL 1 exit /b 1 416goto :done 417:L 418rem target/triple already spelled out. 419%~dp0\\..\\clang${HOST_EXE} %* 420if ERRORLEVEL 1 exit /b 1 421:done 422EOF 423 cat > "${ANALYZER}++.cmd" <<EOF 424@echo off 425if "%1" == "-cc1" goto :L 426%~dp0\\..\\clang++${HOST_EXE} -target $LLVM_TARGET %* 427if ERRORLEVEL 1 exit /b 1 428goto :done 429:L 430rem target/triple already spelled out. 431%~dp0\\..\\clang++${HOST_EXE} %* 432if ERRORLEVEL 1 exit /b 1 433:done 434EOF 435 fi 436done 437 438if [ "$PACKAGE_DIR" ]; then 439 ARCHIVE="$TOOLCHAIN-$HOST_TAG.tar.bz2" 440 SUBDIR=$(get_toolchain_install_subdir $TOOLCHAIN $HOST_TAG) 441 dump "Packaging $ARCHIVE" 442 pack_archive "$PACKAGE_DIR/$ARCHIVE" "$NDK_DIR" "$SUBDIR" 443fi 444 445dump "Done." 446if [ -z "$OPTION_BUILD_OUT" ] ; then 447 rm -rf $BUILD_OUT 448fi 449