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