1 #!/bin/sh 2 # 3 # Copyright (C) 2011 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 prebuilt GNU libsupc++ and 18 # libstdc++ binaries from their sources. It requires an NDK installation 19 # that contains valid plaforms files and toolchain binaries. 20 # 21 22 # include common function and variable definitions 23 . `dirname $0`/prebuilt-common.sh 24 25 PROGRAM_PARAMETERS="<src-dir>" 26 27 PROGRAM_DESCRIPTION=\ 28 "Rebuild the prebuilt GNU libsupc++ / libstdc++ binaries for the Android NDK. 29 30 This script is called when packaging a new NDK release. It will simply 31 rebuild the GNU libsupc++ and libstdc++ static and shared libraries from 32 sources. 33 34 This requires a temporary NDK installation containing platforms and 35 toolchain binaries for all target architectures, as well as the path to 36 the corresponding gcc source tree. 37 38 By default, this will try with the current NDK directory, unless 39 you use the --ndk-dir=<path> option. 40 41 The output will be placed in appropriate sub-directories of 42 <ndk>/$GNUSTL_SUBDIR/<gcc-version>, but you can override this with the --out-dir=<path> 43 option. 44 " 45 GCC_VERSION_LIST=$DEFAULT_GCC_VERSION_LIST 46 register_var_option "--gcc-version-list=<vers>" GCC_VERSION_LIST "List of GCC versions" 47 48 PACKAGE_DIR= 49 register_var_option "--package-dir=<path>" PACKAGE_DIR "Put prebuilt tarballs into <path>." 50 51 NDK_DIR= 52 register_var_option "--ndk-dir=<path>" NDK_DIR "Specify NDK root path for the build." 53 54 BUILD_DIR= 55 OPTION_BUILD_DIR= 56 register_var_option "--build-dir=<path>" OPTION_BUILD_DIR "Specify temporary build dir." 57 58 OUT_DIR= 59 register_var_option "--out-dir=<path>" OUT_DIR "Specify output directory directly." 60 61 ABIS=$(spaces_to_commas $PREBUILT_ABIS) 62 register_var_option "--abis=<list>" ABIS "Specify list of target ABIs." 63 64 NO_MAKEFILE= 65 register_var_option "--no-makefile" NO_MAKEFILE "Do not use makefile to speed-up build" 66 67 VISIBLE_LIBGNUSTL_STATIC= 68 register_var_option "--visible-libgnustl-static" VISIBLE_LIBGNUSTL_STATIC "Do not use hidden visibility for libgnustl_static.a" 69 70 WITH_DEBUG_INFO= 71 register_var_option "--with-debug-info" WITH_DEBUG_INFO "Build with -g. STL is still built with optimization but with debug info" 72 73 register_jobs_option 74 75 extract_parameters "$@" 76 77 SRCDIR=$(echo $PARAMETERS | sed 1q) 78 check_toolchain_src_dir "$SRCDIR" 79 80 ABIS=$(commas_to_spaces $ABIS) 81 82 # Handle NDK_DIR 83 if [ -z "$NDK_DIR" ] ; then 84 NDK_DIR=$ANDROID_NDK_ROOT 85 log "Auto-config: --ndk-dir=$NDK_DIR" 86 else 87 if [ ! -d "$NDK_DIR" ] ; then 88 echo "ERROR: NDK directory does not exists: $NDK_DIR" 89 exit 1 90 fi 91 fi 92 93 if [ -z "$OPTION_BUILD_DIR" ]; then 94 BUILD_DIR=$NDK_TMPDIR/build-gnustl 95 else 96 BUILD_DIR=$OPTION_BUILD_DIR 97 fi 98 99 HOST_TAG_LIST="$HOST_TAG $HOST_TAG32" 100 101 rm -rf "$BUILD_DIR" 102 mkdir -p "$BUILD_DIR" 103 fail_panic "Could not create build directory: $BUILD_DIR" 104 105 # $1: ABI name 106 # $2: Build directory 107 # $3: "static" or "shared" 108 # $4: GCC version 109 # $5: optional "thumb" 110 build_gnustl_for_abi () 111 { 112 local ARCH BINPREFIX SYSROOT GNUSTL_SRCDIR 113 local ABI=$1 114 local BUILDDIR="$2" 115 local LIBTYPE="$3" 116 local GCC_VERSION="$4" 117 local THUMB="$5" 118 local DSTDIR=$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION/libs/$ABI/$THUMB 119 local SRC OBJ OBJECTS CFLAGS CXXFLAGS CPPFLAGS 120 121 prepare_target_build $ABI $PLATFORM $NDK_DIR 122 fail_panic "Could not setup target build." 123 124 INSTALLDIR=$BUILDDIR/install-$ABI-$GCC_VERSION/$THUMB 125 BUILDDIR=$BUILDDIR/$LIBTYPE-${ABI}${THUMB}-$GCC_VERSION 126 127 mkdir -p $DSTDIR 128 129 ARCH=$(convert_abi_to_arch $ABI) 130 for TAG in $HOST_TAG_LIST; do 131 BINPREFIX=$NDK_DIR/$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION $TAG) 132 if [ -f ${BINPREFIX}gcc ]; then 133 break; 134 fi 135 done 136 GNUSTL_SRCDIR=$SRCDIR/gcc/gcc-$GCC_VERSION/libstdc++-v3 137 # Sanity check 138 if [ ! -d "$GNUSTL_SRCDIR" ]; then 139 echo "ERROR: Not a valid toolchain source tree." 140 echo "Can't find: $GNUSTL_SRCDIR" 141 exit 1 142 fi 143 144 if [ ! -f "$GNUSTL_SRCDIR/configure" ]; then 145 echo "ERROR: Configure script missing: $GNUSTL_SRCDIR/configure" 146 exit 1 147 fi 148 149 SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH) 150 LDIR=$SYSROOT"/usr/"$(get_default_libdir_for_arch $ARCH) 151 # Sanity check 152 if [ ! -f "$LDIR/libc.a" ]; then 153 echo "ERROR: Empty sysroot! you probably need to run gen-platforms.sh before this script." 154 exit 1 155 fi 156 if [ ! -f "$LDIR/libc.so" ]; then 157 echo "ERROR: Sysroot misses shared libraries! you probably need to run gen-platforms.sh" 158 echo "*without* the --minimal flag before running this script." 159 exit 1 160 fi 161 162 case $ARCH in 163 arm) 164 BUILD_HOST=arm-linux-androideabi 165 ;; 166 arm64) 167 BUILD_HOST=aarch64-linux-android 168 ;; 169 x86) 170 BUILD_HOST=i686-linux-android 171 ;; 172 x86_64) 173 BUILD_HOST=x86_64-linux-android 174 ;; 175 mips) 176 BUILD_HOST=mipsel-linux-android 177 ;; 178 mips64) 179 BUILD_HOST=mips64el-linux-android 180 ;; 181 esac 182 183 EXTRA_FLAGS="-ffunction-sections -fdata-sections" 184 if [ -n "$THUMB" ] ; then 185 EXTRA_FLAGS="-mthumb" 186 fi 187 CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS" 188 CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS" 189 CPPFLAGS="$CPPFLAGS --sysroot=$SYSROOT" 190 if [ "$WITH_DEBUG_INFO" ]; then 191 CFLAGS="$CFLAGS -g" 192 CXXFLAGS="$CXXFLAGS -g" 193 fi 194 export CFLAGS CXXFLAGS CPPFLAGS 195 196 export CC=${BINPREFIX}gcc 197 export CXX=${BINPREFIX}g++ 198 export AS=${BINPREFIX}as 199 export LD=${BINPREFIX}ld 200 export AR=${BINPREFIX}ar 201 export RANLIB=${BINPREFIX}ranlib 202 export STRIP=${BINPREFIX}strip 203 204 setup_ccache 205 206 export LDFLAGS="-lc $EXTRA_FLAGS" 207 208 if [ "$ABI" = "armeabi-v7a" -o "$ABI" = "armeabi-v7a-hard" ]; then 209 CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfpu=vfpv3-d16" 210 LDFLAGS=$LDFLAGS" -Wl,--fix-cortex-a8" 211 if [ "$ABI" != "armeabi-v7a-hard" ]; then 212 CXXFLAGS=$CXXFLAGS" -mfloat-abi=softfp" 213 else 214 CXXFLAGS=$CXXFLAGS" -mhard-float -D_NDK_MATH_NO_SOFTFP=1" 215 LDFLAGS=$LDFLAGS" -Wl,--no-warn-mismatch -lm_hard" 216 fi 217 fi 218 219 LIBTYPE_FLAGS= 220 if [ $LIBTYPE = "static" ]; then 221 # Ensure we disable visibility for the static library to reduce the 222 # size of the code that will be linked against it. 223 if [ -z "$VISIBLE_LIBGNUSTL_STATIC" ] ; then 224 LIBTYPE_FLAGS="--enable-static --disable-shared" 225 if [ $GCC_VERSION = "4.4.3" -o $GCC_VERSION = "4.6" ]; then 226 LIBTYPE_FLAGS=$LIBTYPE_FLAGS" --disable-visibility" 227 else 228 LIBTYPE_FLAGS=$LIBTYPE_FLAGS" --disable-libstdcxx-visibility" 229 fi 230 CXXFLAGS=$CXXFLAGS" -fvisibility=hidden -fvisibility-inlines-hidden" 231 fi 232 else 233 LIBTYPE_FLAGS="--disable-static --enable-shared" 234 #LDFLAGS=$LDFLAGS" -lsupc++" 235 fi 236 237 if [ "$ARCH" == "x86_64" -o "$ARCH" == "mips64" ]; then 238 MULTILIB_FLAGS= # Both x86_64 and mips64el toolchains are built with multilib options 239 else 240 MULTILIB_FLAGS=--disable-multilib 241 fi 242 243 PROJECT="gnustl_$LIBTYPE gcc-$GCC_VERSION $ABI $THUMB" 244 echo "$PROJECT: configuring" 245 mkdir -p $BUILDDIR && rm -rf $BUILDDIR/* && 246 cd $BUILDDIR && 247 run $GNUSTL_SRCDIR/configure \ 248 --prefix=$INSTALLDIR \ 249 --host=$BUILD_HOST \ 250 $LIBTYPE_FLAGS \ 251 --enable-libstdcxx-time \ 252 --disable-symvers \ 253 $MULTILIB_FLAGS \ 254 --disable-nls \ 255 --disable-sjlj-exceptions \ 256 --disable-tls \ 257 --disable-libstdcxx-pch \ 258 --with-gxx-include-dir=$INSTALLDIR/include/c++/$GCC_VERSION 259 260 fail_panic "Could not configure $PROJECT" 261 262 echo "$PROJECT: compiling" 263 run make -j$NUM_JOBS 264 fail_panic "Could not build $PROJECT" 265 266 echo "$PROJECT: installing" 267 run make install 268 fail_panic "Could not create $ABI $THUMB prebuilts for GNU libsupc++/libstdc++" 269 } 270 271 272 HAS_COMMON_HEADERS= 273 274 # $1: ABI 275 # $2: Build directory 276 # $3: GCC_VERSION 277 copy_gnustl_libs () 278 { 279 local ABI="$1" 280 local BUILDDIR="$2" 281 local ARCH=$(convert_abi_to_arch $ABI) 282 local GCC_VERSION="$3" 283 local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH) 284 PREFIX=${PREFIX%%-} 285 286 local SDIR="$BUILDDIR/install-$ABI-$GCC_VERSION" 287 local DDIR="$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION" 288 289 local GCC_VERSION_NO_DOT=$(echo $GCC_VERSION|sed 's/\./_/g') 290 # Copy the common headers only once per gcc version 291 if [ -z `var_value HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT` ]; then 292 copy_directory "$SDIR/include/c++/$GCC_VERSION" "$DDIR/include" 293 rm -rf "$DDIR/include/$PREFIX" 294 eval HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT=true 295 fi 296 297 rm -rf "$DDIR/libs/$ABI" && 298 mkdir -p "$DDIR/libs/$ABI/include" 299 300 # Copy the ABI-specific headers 301 copy_directory "$SDIR/include/c++/$GCC_VERSION/$PREFIX/bits" "$DDIR/libs/$ABI/include/bits" 302 if [ "$ARCH" = "x86_64" -o "$ARCH" = "mips64" ]; then 303 copy_directory "$SDIR/include/c++/$GCC_VERSION/$PREFIX/32/bits" "$DDIR/libs/$ABI/include/32/bits" 304 if [ "$ARCH" = "x86_64" ]; then 305 copy_directory "$SDIR/include/c++/$GCC_VERSION/$PREFIX/x32/bits" "$DDIR/libs/$ABI/include/x32/bits" 306 else 307 copy_directory "$SDIR/include/c++/$GCC_VERSION/$PREFIX/n32/bits" "$DDIR/libs/$ABI/include/n32/bits" 308 fi 309 fi 310 311 LDIR=lib 312 if [ "$ARCH" != "${ARCH%%64*}" ]; then 313 #Can't call $(get_default_libdir_for_arch $ARCH) which contain hack for arm64 and mips64 314 LDIR=lib64 315 fi 316 317 # Copy the ABI-specific libraries 318 # Note: the shared library name is libgnustl_shared.so due our custom toolchain patch 319 copy_file_list "$SDIR/$LDIR" "$DDIR/libs/$ABI" libsupc++.a libgnustl_shared.so 320 # Note: we need to rename libgnustl_shared.a to libgnustl_static.a 321 cp "$SDIR/$LDIR/libgnustl_shared.a" "$DDIR/libs/$ABI/libgnustl_static.a" 322 if [ "$ARCH" = "x86_64" -o "$ARCH" = "mips64" ]; then 323 # for multilib we copy full set. Keep native libs in $ABI dir for compatibility. 324 # TODO: remove it in $ABI top directory 325 copy_file_list "$SDIR/lib" "$DDIR/libs/$ABI/lib" libsupc++.a libgnustl_shared.so 326 copy_file_list "$SDIR/lib64" "$DDIR/libs/$ABI/lib64" libsupc++.a libgnustl_shared.so 327 cp "$SDIR/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/lib/libgnustl_static.a" 328 cp "$SDIR/lib64/libgnustl_shared.a" "$DDIR/libs/$ABI/lib64/libgnustl_static.a" 329 if [ "$ARCH" = "x86_64" ]; then 330 copy_file_list "$SDIR/libx32" "$DDIR/libs/$ABI/libx32" libsupc++.a libgnustl_shared.so 331 cp "$SDIR/libx32/libgnustl_shared.a" "$DDIR/libs/$ABI/libx32/libgnustl_static.a" 332 else 333 copy_file_list "$SDIR/lib32" "$DDIR/libs/$ABI/lib32" libsupc++.a libgnustl_shared.so 334 cp "$SDIR/lib32/libgnustl_shared.a" "$DDIR/libs/$ABI/lib32/libgnustl_static.a" 335 fi 336 fi 337 if [ -d "$SDIR/thumb" ] ; then 338 copy_file_list "$SDIR/thumb/$LDIR" "$DDIR/libs/$ABI/thumb" libsupc++.a libgnustl_shared.so 339 cp "$SDIR/thumb/$LDIR/libgnustl_shared.a" "$DDIR/libs/$ABI/thumb/libgnustl_static.a" 340 fi 341 } 342 343 GCC_VERSION_LIST=$(commas_to_spaces $GCC_VERSION_LIST) 344 for ABI in $ABIS; do 345 ARCH=$(convert_abi_to_arch $ABI) 346 DEFAULT_GCC_VERSION=$(get_default_gcc_version_for_arch $ARCH) 347 for VERSION in $GCC_VERSION_LIST; do 348 # Only build for this GCC version if it on or after DEFAULT_GCC_VERSION 349 if [ "${VERSION%%l}" \< "$DEFAULT_GCC_VERSION" ]; then 350 continue 351 fi 352 353 build_gnustl_for_abi $ABI "$BUILD_DIR" static $VERSION 354 build_gnustl_for_abi $ABI "$BUILD_DIR" shared $VERSION 355 # build thumb version of libraries for 32-bit arm 356 if [ "$ABI" != "${ABI%%arm*}" -a "$ABI" = "${ABI%%64*}" ] ; then 357 build_gnustl_for_abi $ABI "$BUILD_DIR" static $VERSION thumb 358 build_gnustl_for_abi $ABI "$BUILD_DIR" shared $VERSION thumb 359 fi 360 copy_gnustl_libs $ABI "$BUILD_DIR" $VERSION 361 done 362 done 363 364 # If needed, package files into tarballs 365 if [ -n "$PACKAGE_DIR" ] ; then 366 for VERSION in $GCC_VERSION_LIST; do 367 # First, the headers as a single package for a given gcc version 368 PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers-$VERSION.tar.bz2" 369 dump "Packaging: $PACKAGE" 370 pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/$VERSION/include" 371 372 # Then, one package per version/ABI for libraries 373 for ABI in $ABIS; do 374 if [ ! -d "$NDK_DIR/$GNUSTL_SUBDIR/$VERSION/libs/$ABI" ]; then 375 continue 376 fi 377 FILES="" 378 case "$ABI" in 379 x86_64) 380 MULTILIB="include/32/bits include/x32/bits 381 lib/libsupc++.a lib/libgnustl_static.a lib/libgnustl_shared.so 382 libx32/libsupc++.a libx32/libgnustl_static.a libx32/libgnustl_shared.so 383 lib64/libsupc++.a lib64/libgnustl_static.a lib64/libgnustl_shared.so" 384 ;; 385 mips64) 386 MULTILIB="include/32/bits include/n32/bits 387 lib/libsupc++.a lib/libgnustl_static.a lib/libgnustl_shared.so 388 lib32/libsupc++.a lib32/libgnustl_static.a lib32/libgnustl_shared.so 389 lib64/libsupc++.a lib64/libgnustl_static.a lib64/libgnustl_shared.so" 390 ;; 391 *) 392 MULTILIB= 393 ;; 394 esac 395 for LIB in include/bits $MULTILIB libsupc++.a libgnustl_static.a libgnustl_shared.so; do 396 FILES="$FILES $GNUSTL_SUBDIR/$VERSION/libs/$ABI/$LIB" 397 THUMB_FILE="$GNUSTL_SUBDIR/$VERSION/libs/$ABI/thumb/$LIB" 398 if [ -f "$NDK_DIR/$THUMB_FILE" ] ; then 399 FILES="$FILES $THUMB_FILE" 400 fi 401 done 402 PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$VERSION-$ABI" 403 if [ "$WITH_DEBUG_INFO" ]; then 404 PACKAGE="${PACKAGE}-g" 405 fi 406 PACKAGE="${PACKAGE}.tar.bz2" 407 dump "Packaging: $PACKAGE" 408 pack_archive "$PACKAGE" "$NDK_DIR" "$FILES" 409 fail_panic "Could not package $ABI GNU libstdc++ binaries!" 410 done 411 done 412 fi 413 414 if [ -z "$OPTION_BUILD_DIR" ]; then 415 log "Cleaning up..." 416 rm -rf $BUILD_DIR 417 else 418 log "Don't forget to cleanup: $BUILD_DIR" 419 fi 420 421 log "Done!" 422