• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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