1# Copyright (C) 2012 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# 15 16# A set of function shared by the 'build-host-xxxx.sh' scripts. 17# They are mostly related to building host libraries. 18# 19# NOTE: This script uses various prefixes: 20# 21# BH_ Used for public macros 22# bh_ Use for public functions 23# 24# _BH_ Used for private macros 25# _bh_ Used for private functions 26# 27# Callers should only rely on the public macros and functions defined here. 28# 29 30# List of macros defined by the functions here: 31# 32# defined by 'bh_set_build_tag' 33# 34# BH_BUILD_CONFIG Generic GNU config triplet for build system 35# BH_BUILD_OS NDK system name 36# BH_BUILD_ARCH NDK arch name 37# BH_BUILD_TAG NDK system tag ($OS-$ARCH) 38# BH_BUILD_BITS build system bitness (32 or 64) 39# 40# defined by 'bh_set_host_tag' 41# 7 42# BH_HOST_CONFIG 43# BH_HOST_OS 44# BH_HOST_ARCH 45# BH_HOST_TAG 46# BH_HOST_BITS 47# 48# defined by 'bh_set_target_tag' 49# 50# BH_TARGET_CONFIG 51# BH_TARGET_OS 52# BH_TARGET_ARCH 53# BH_TARGET_TAG 54# BH_TARGET_BITS 55# 56# 57 58 59# The values of HOST_OS/ARCH/TAG will be redefined during the build to 60# match those of the system the generated compiler binaries will run on. 61# 62# Save the original ones into BUILD_XXX variants, corresponding to the 63# machine where the build happens. 64# 65BH_BUILD_OS=$HOST_OS 66BH_BUILD_ARCH=$HOST_ARCH 67BH_BUILD_TAG=$HOST_TAG 68 69# Map an NDK system tag to an OS name 70# $1: system tag (e.g. linux-x86) 71# Out: system name (e.g. linux) 72bh_tag_to_os () 73{ 74 local RET 75 case $1 in 76 android-*) RET="android";; 77 linux-*) RET="linux";; 78 darwin-*) RET="darwin";; 79 windows|windows-*) RET="windows";; 80 esac 81 echo $RET 82} 83 84# Map an NDK system tag to an architecture name 85# $1: system tag (e.g. linux-x86) 86# Out: arch name (e.g. x86) 87bh_tag_to_arch () 88{ 89 local RET 90 case $1 in 91 *-arm) RET=arm;; 92 *-mips) RET=mips;; 93 windows|*-x86) RET=x86;; 94 *-x86_64) RET=x86_64;; 95 esac 96 echo $RET 97} 98 99# Map an NDK system tag to a bit number 100# $1: system tag (e.g. linux-x86) 101# Out: bit number (32 or 64) 102bh_tag_to_bits () 103{ 104 local RET 105 case $1 in 106 windows|*-x86|*-arm|*-mips) RET=32;; 107 *-x86_64) RET=64;; 108 esac 109 echo $RET 110} 111 112# Map an NDK system tag to the corresponding GNU configuration triplet. 113# $1: NDK system tag 114# Out: GNU configuration triplet 115bh_tag_to_config_triplet () 116{ 117 local RET 118 case $1 in 119 linux-x86) RET=i686-linux-gnu;; 120 linux-x86_64) RET=x86_64-linux-gnu;; 121 darwin-x86) RET=i686-apple-darwin;; 122 darwin-x86_64) RET=x86_64-apple-darwin;; 123 windows|windows-x86) RET=i586-pc-mingw32msvc;; 124 windows-x86_64) RET=x86_64-w64-mingw32;; 125 android-arm) RET=arm-linux-androideabi;; 126 android-x86) RET=i686-linux-android;; 127 android-mips) RET=mipsel-linux-android;; 128 esac 129 echo "$RET" 130} 131 132 133bh_set_build_tag () 134{ 135 BH_BUILD_OS=$(bh_tag_to_os $1) 136 BH_BUILD_ARCH=$(bh_tag_to_arch $1) 137 BH_BUILD_BITS=$(bh_tag_to_bits $1) 138 BH_BUILD_TAG=$BH_BUILD_OS-$BH_BUILD_ARCH 139 BH_BUILD_CONFIG=$(bh_tag_to_config_triplet $1) 140} 141 142# Set default BH_BUILD macros. 143bh_set_build_tag $HOST_TAG 144 145bh_set_host_tag () 146{ 147 BH_HOST_OS=$(bh_tag_to_os $1) 148 BH_HOST_ARCH=$(bh_tag_to_arch $1) 149 BH_HOST_BITS=$(bh_tag_to_bits $1) 150 BH_HOST_TAG=$BH_HOST_OS-$BH_HOST_ARCH 151 BH_HOST_CONFIG=$(bh_tag_to_config_triplet $1) 152} 153 154bh_set_target_tag () 155{ 156 BH_TARGET_OS=$(bh_tag_to_os $1) 157 BH_TARGET_ARCH=$(bh_tag_to_arch $1) 158 BH_TARGET_BITS=$(bh_tag_to_bits $1) 159 BH_TARGET_TAG=$BH_TARGET_OS-$BH_TARGET_ARCH 160 BH_TARGET_CONFIG=$(bh_tag_to_config_triplet $1) 161} 162 163bh_sort_systems_build_first () 164{ 165 local IN_SYSTEMS="$1" 166 local OUT_SYSTEMS 167 # Pull out the host if there 168 for IN_SYSTEM in $IN_SYSTEMS; do 169 if [ "$IN_SYSTEM" = "$BH_BUILD_TAG" ]; then 170 OUT_SYSTEMS=$IN_SYSTEM 171 fi 172 done 173 # Append the rest 174 for IN_SYSTEM in $IN_SYSTEMS; do 175 if [ ! "$IN_SYSTEM" = "$BH_BUILD_TAG" ]; then 176 OUT_SYSTEMS=$OUT_SYSTEMS" $IN_SYSTEM" 177 fi 178 done 179 echo $OUT_SYSTEMS 180} 181 182# $1 is the string to search for 183# $2... is the list to search in 184# Returns first, yes or no. 185bh_list_contains () 186{ 187 local SEARCH="$1" 188 shift 189 # For dash, this has to be split over 2 lines. 190 # Seems to be a bug with dash itself: 191 # https://bugs.launchpad.net/ubuntu/+source/dash/+bug/141481 192 local LIST 193 LIST=$@ 194 local RESULT=first 195 # Pull out the host if there 196 for ELEMENT in $LIST; do 197 if [ "$ELEMENT" = "$SEARCH" ]; then 198 echo $RESULT 199 return 0 200 fi 201 RESULT=yes 202 done 203 echo no 204 return 1 205} 206 207 208# Use this function to enable/disable colored output 209# $1: 'true' or 'false' 210bh_set_color_mode () 211{ 212 local DO_COLOR= 213 case $1 in 214 on|enable|true) DO_COLOR=true 215 ;; 216 esac 217 if [ "$DO_COLOR" ]; then 218 _BH_COLOR_GREEN="\033[32m" 219 _BH_COLOR_PURPLE="\033[35m" 220 _BH_COLOR_CYAN="\033[36m" 221 _BH_COLOR_END="\033[0m" 222 else 223 _BH_COLOR_GREEN= 224 _BH_COLOR_PURPLE= 225 _BH_COLOR_CYAN= 226 _BH_COLOR_END= 227 fi 228} 229 230# By default, enable color mode 231bh_set_color_mode true 232 233# Pretty printing with colors! 234bh_host_text () 235{ 236 printf "[${_BH_COLOR_GREEN}${BH_HOST_TAG}${_BH_COLOR_END}]" 237} 238 239bh_toolchain_text () 240{ 241 printf "[${_BH_COLOR_PURPLE}${BH_TOOLCHAIN}${_BH_COLOR_END}]" 242} 243 244bh_target_text () 245{ 246 printf "[${_BH_COLOR_CYAN}${BH_TARGET_TAG}${_BH_COLOR_END}]" 247} 248 249bh_arch_text () 250{ 251 # Print arch name in cyan 252 printf "[${_BH_COLOR_CYAN}${BH_TARGET_ARCH}${_BH_COLOR_END}]" 253} 254 255# Check that a given compiler generates code correctly 256# 257# This is to detect bad/broken toolchains, e.g. amd64-mingw32msvc 258# is totally broken on Ubuntu 10.10 and 11.04 259# 260# $1: compiler 261# $2: optional extra flags 262# 263bh_check_compiler () 264{ 265 local CC="$1" 266 local TMPC=/tmp/build-host-$USER-$$.c 267 local TMPE=${TMPC%%.c} 268 local TMPL=$TMPC.log 269 local RET 270 shift 271 cat > $TMPC <<EOF 272int main(void) { return 0; } 273EOF 274 log_n "Checking compiler code generation ($CC)... " 275 $CC -o $TMPE $TMPC "$@" >$TMPL 2>&1 276 RET=$? 277 rm -f $TMPC $TMPE $TMPL 278 if [ "$RET" = 0 ]; then 279 log "yes" 280 else 281 log "no" 282 fi 283 return $RET 284} 285 286 287# $1: toolchain install dir 288# $2: toolchain prefix, no trailing dash (e.g. arm-linux-androideabi) 289# $3: optional -m32 or -m64. 290_bh_try_host_fullprefix () 291{ 292 local PREFIX="$1/bin/$2" 293 shift; shift; 294 if [ -z "$HOST_FULLPREFIX" ]; then 295 local GCC="$PREFIX-gcc" 296 if [ -f "$GCC" ]; then 297 if bh_check_compiler "$GCC" "$@"; then 298 HOST_FULLPREFIX="${GCC%%gcc}" 299 dump "$(bh_host_text) Using host gcc: $GCC $@" 300 else 301 dump "$(bh_host_text) Ignoring broken host gcc: $GCC $@" 302 fi 303 fi 304 fi 305} 306 307# $1: host prefix, no trailing slash (e.g. i686-linux-android) 308# $2: optional compiler args (should be empty, -m32 or -m64) 309_bh_try_host_prefix () 310{ 311 local PREFIX="$1" 312 shift 313 if [ -z "$HOST_FULLPREFIX" ]; then 314 local GCC="$(which $PREFIX-gcc 2>/dev/null)" 315 if [ "$GCC" -a -e "$GCC" ]; then 316 if bh_check_compiler "$GCC" "$@"; then 317 HOST_FULLPREFIX=${GCC%%gcc} 318 dump "$(bh_host_text) Using host gcc: ${HOST_FULLPREFIX}gcc $@" 319 else 320 dump "$(bh_host_text) Ignoring broken host gcc: $GCC $@" 321 fi 322 fi 323 fi 324} 325 326# Used to determine the minimum possible Darwin version that a Darwin SDK 327# can target. This actually depends from the host architecture. 328# $1: Host architecture name 329# out: SDK version number (e.g. 10.4 or 10.5) 330_bh_darwin_arch_to_min_version () 331{ 332 if [ "$1" = "x86" ]; then 333 echo "10.4" 334 else 335 echo "10.5" 336 fi 337} 338 339# Use the check for the availability of a compatibility SDK in Darwin 340# this can be used to generate binaries compatible with either Tiger or 341# Leopard. 342# 343# $1: SDK root path 344# $2: Darwin compatibility minimum version 345_bh_check_darwin_sdk () 346{ 347 if [ -d "$1" -a -z "$HOST_CFLAGS" ] ; then 348 HOST_CFLAGS="-isysroot $1 -mmacosx-version-min=$2 -DMAXOSX_DEPLOYEMENT_TARGET=$2" 349 HOST_CXXFLAGS=$HOST_CFLAGS 350 HOST_LDFLAGS="-syslibroot $1 -mmacosx-version-min=$2" 351 dump "Generating $2-compatible binaries." 352 return 0 # success 353 fi 354 return 1 355} 356 357# Check that a given compiler generates 32 or 64 bit code. 358# $1: compiler full path (.e.g /path/to/fullprefix-gcc) 359# $2: 32 or 64 360# $3: extract compiler flags 361# Return: success iff the compiler generates $2-bits code 362_bh_check_compiler_bitness () 363{ 364 local CC="$1" 365 local BITS="$2" 366 local TMPC=/tmp/build-host-gcc-bits-$USER-$$.c 367 local TMPL=$TMPC.log 368 local RET 369 shift; shift; 370 cat > $TMPC <<EOF 371/* this program will fail to compile if the compiler doesn't generate BITS-bits code */ 372int tab[1-2*(sizeof(void*)*8 != BITS)]; 373EOF 374 dump_n "$(bh_host_text) Checking that the compiler generates $BITS-bits code ($@)... " 375 $CC -c -DBITS=$BITS -o /dev/null $TMPC $HOST_CFLAGS "$@" > $TMPL 2>&1 376 RET=$? 377 rm -f $TMPC $TMPL 378 if [ "$RET" = 0 ]; then 379 dump "yes" 380 else 381 dump "no" 382 fi 383 return $RET 384} 385 386# This function probes the system to find the best toolchain or cross-toolchain 387# to build binaries that run on a given host system. After that, it generates 388# a wrapper toolchain under $2 with a prefix of ${BH_HOST_CONFIG}- 389# where $BH_HOST_CONFIG is a GNU configuration name. 390# 391# Important: this script might redefine $BH_HOST_CONFIG to a different value! 392# 393# $1: NDK system tag (e.g. linux-x86) 394# 395# The following can be defined, otherwise they'll be auto-detected and set. 396# 397# DARWIN_MIN_VERSION -> Darwmin minimum compatibility version 398# DARWIN_SDK_VERSION -> Darwin SDK version 399# 400# The following can be defined for extra features: 401# 402# DARWIN_TOOLCHAIN -> Path to Darwin cross-toolchain (cross-compile only). 403# DARWIN_SYSROOT -> Path to Darwin SDK sysroot (cross-compile only). 404# NDK_CCACHE -> Ccache binary to use to speed up rebuilds. 405# ANDROID_NDK_ROOT -> Top-level NDK directory, for automatic probing 406# of prebuilt platform toolchains. 407# 408_bh_select_toolchain_for_host () 409{ 410 local HOST_CFLAGS HOST_CXXFLAGS HOST_LDFLAGS HOST_FULLPREFIX DARWIN_ARCH 411 local DARWIN_ARCH DARWIN_SDK_SUBDIR 412 413 # We do all the complex auto-detection magic in the setup phase, 414 # then save the result in host-specific global variables. 415 # 416 # In the build phase, we will simply restore the values into the 417 # global HOST_FULLPREFIX / HOST_BUILD_DIR 418 # variables. 419 # 420 421 # Try to find the best toolchain to do that job, assuming we are in 422 # a full Android platform source checkout, we can look at the prebuilts/ 423 # directory. 424 case $1 in 425 linux-x86) 426 # If possible, automatically use our custom toolchain to generate 427 # 32-bit executables that work on Ubuntu 8.04 and higher. 428 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" i686-linux 429 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.4.3" i686-linux 430 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3" i686-linux 431 _bh_try_host_prefix i686-linux-gnu 432 _bh_try_host_prefix i686-linux 433 _bh_try_host_prefix x86_64-linux-gnu -m32 434 _bh_try_host_prefix x86_64-linux -m32 435 ;; 436 437 linux-x86_64) 438 # If possible, automaticaly use our custom toolchain to generate 439 # 64-bit executables that work on Ubuntu 8.04 and higher. 440 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" x86_64-linux 441 _bh_try_host_prefix x86_64-linux-gnu 442 _bh_try_host_prefix x84_64-linux 443 _bh_try_host_prefix i686-linux-gnu -m64 444 _bh_try_host_prefix i686-linux -m64 445 ;; 446 447 darwin-*) 448 DARWIN_ARCH=$(bh_tag_to_arch $1) 449 if [ -z "$DARWIN_MIN_VERSION" ]; then 450 DARWIN_MIN_VERSION=$(_bh_darwin_arch_to_min_version $DARWIN_ARCH) 451 fi 452 case $BH_BUILD_OS in 453 darwin) 454 if [ "$DARWIN_SDK_VERSION" ]; then 455 # Compute SDK subdirectory name 456 case $DARWIN_SDK_VERSION in 457 10.4) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdku;; 458 *) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdk;; 459 esac 460 # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder. 461 _bh_check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_MIN_VERSION 462 _bh_check_darwin_sdk /Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_MIN_VERSION 463 else 464 # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder. 465 _bh_check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk $DARWIN_MIN_VERSION 466 _bh_check_darwin_sdk /Developer/SDKs/MacOSX10.7.sdk $DARWIN_MIN_VERSION 467 _bh_check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk $DARWIN_MIN_VERSION 468 # NOTE: The 10.5.sdk on Lion is buggy and cannot build basic C++ programs 469 #_bh_check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk $DARWIN_ARCH 470 # NOTE: The 10.4.sdku is not available anymore and could not be tested. 471 #_bh_check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku $DARWIN_ARCH 472 fi 473 if [ -z "$HOST_CFLAGS" ]; then 474 local version="$(sw_vers -productVersion)" 475 log "Generating $version-compatible binaries!" 476 fi 477 ;; 478 *) 479 if [ -z "$DARWIN_TOOLCHAIN" -o -z "$DARWIN_SYSROOT" ]; then 480 dump "If you want to build Darwin binaries on a non-Darwin machine," 481 dump "Please define DARWIN_TOOLCHAIN to name it, and DARWIN_SYSROOT to point" 482 dump "to the SDK. For example:" 483 dump "" 484 dump " DARWIN_TOOLCHAIN=\"i686-apple-darwin11\"" 485 dump " DARWIN_SYSROOT=\"~/darwin-cross/MacOSX10.7.sdk\"" 486 dump " export DARWIN_TOOLCHAIN DARWIN_SYSROOT" 487 dump "" 488 exit 1 489 fi 490 _bh_check_darwin_sdk $DARWIN_SYSROOT $DARWIN_MIN_VERSION 491 _bh_try_host_prefix "$DARWIN_TOOLCHAIN" -m$(bh_tag_to_bits $1) --sysroot "$DARWIN_SYSROOT" 492 if [ -z "$HOST_FULLPREFIX" ]; then 493 dump "It looks like $DARWIN_TOOLCHAIN-gcc is not in your path, or does not work correctly!" 494 exit 1 495 fi 496 dump "Using darwin cross-toolchain: ${HOST_FULLPREFIX}gcc" 497 ;; 498 esac 499 ;; 500 501 windows|windows-x86) 502 case $BH_BUILD_OS in 503 linux) 504 # We favor these because they are more recent, and because 505 # we have a script to rebuild them from scratch. See 506 # build-mingw64-toolchain.sh. 507 _bh_try_host_prefix x86_64-w64-mingw32 -m32 508 _bh_try_host_prefix i686-w64-mingw32 509 # Typically provided by the 'mingw32' package on Debian 510 # and Ubuntu systems. 511 _bh_try_host_prefix i586-mingw32msvc 512 # Special note for Fedora: this distribution used 513 # to have a mingw32-gcc package that provided a 32-bit 514 # only cross-toolchain named i686-pc-mingw32. 515 # Later versions of the distro now provide a new package 516 # named mingw-gcc which provides i686-w64-mingw32 and 517 # x86_64-w64-mingw32 instead. 518 _bh_try_host_prefix i686-pc-mingw32 519 if [ -z "$HOST_FULLPREFIX" ]; then 520 dump "There is no Windows cross-compiler. Ensure that you" 521 dump "have one of these installed and in your path:" 522 dump " x86_64-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 523 dump " i686-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 524 dump " i586-mingw32msvc-gcc ('mingw32' Debian/Ubuntu package)" 525 dump " i686-pc-mingw32 (on Fedora)" 526 dump "" 527 exit 1 528 fi 529 # Adjust $HOST to match the toolchain to ensure proper builds. 530 # I.e. chose configuration triplets that are known to work 531 # with the gmp/mpfr/mpc/binutils/gcc configure scripts. 532 case $HOST_FULLPREFIX in 533 *-mingw32msvc-*|i686-pc-mingw32) 534 BH_HOST_CONFIG=i586-pc-mingw32msvc 535 ;; 536 *) 537 BH_HOST_CONFIG=i686-w64-mingw32msvc 538 ;; 539 esac 540 ;; 541 *) panic "Sorry, this script only supports building windows binaries on Linux." 542 ;; 543 esac 544 HOST_CFLAGS=$HOST_CFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 545 HOST_CXXFLAGS=$HOST_CXXFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 546 ;; 547 548 windows-x86_64) 549 case $BH_BUILD_OS in 550 linux) 551 # See comments above for windows-x86 552 _bh_try_host_prefix x86_64-w64-mingw32 553 _bh_try_host_prefix i686-w64-mingw32 -m64 554 # Beware that this package is completely broken on many 555 # versions of no vinegar Ubuntu (i.e. it fails at building trivial 556 # programs). 557 _bh_try_host_prefix amd64-mingw32msvc 558 # There is no x86_64-pc-mingw32 toolchain on Fedora. 559 if [ -z "$HOST_FULLPREFIX" ]; then 560 dump "There is no Windows cross-compiler in your path. Ensure you" 561 dump "have one of these installed and in your path:" 562 dump " x86_64-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 563 dump " i686-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 564 dump " amd64-mingw32msvc-gcc (Debian/Ubuntu - broken until Ubuntu 11.10)" 565 dump "" 566 exit 1 567 fi 568 # See comment above for windows-x86 569 case $HOST_FULLPREFIX in 570 *-mingw32msvc*) 571 # Actually, this has never been tested. 572 BH_HOST=amd64-pc-mingw32msvc 573 ;; 574 *) 575 BH_HOST=x86_64-w64-mingw32 576 ;; 577 esac 578 ;; 579 580 *) panic "Sorry, this script only supports building windows binaries on Linux." 581 ;; 582 esac 583 HOST_CFLAGS=$HOST_CFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 584 HOST_CXXFLAGS=$HOST_CXXFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 585 ;; 586 esac 587 588 # Determine the default bitness of our compiler. It it doesn't match 589 # HOST_BITS, tries to see if it supports -m32 or -m64 to change it. 590 if ! _bh_check_compiler_bitness ${HOST_FULLPREFIX}gcc $BH_HOST_BITS; then 591 local TRY_CFLAGS 592 case $BH_HOST_BITS in 593 32) TRY_CFLAGS=-m32;; 594 64) TRY_CFLAGS=-m64;; 595 esac 596 if ! _bh_check_compiler_bitness ${HOST_FULLPREFIX}gcc $BH_HOST_BITS $TRY_CFLAGS; then 597 panic "Can't find a way to generate $BH_HOST_BITS binaries with this compiler: ${HOST_FULLPREFIX}gcc" 598 fi 599 HOST_CFLAGS=$HOST_CFLAGS" "$TRY_CFLAGS 600 HOST_CXXFLAGS=$HOST_CXXFLAGS" "$TRY_CFLAGS 601 fi 602 603 # Support for ccache, to speed up rebuilds. 604 DST_PREFIX=$HOST_FULLPREFIX 605 local CCACHE= 606 if [ "$NDK_CCACHE" ]; then 607 CCACHE="--ccache=$NDK_CCACHE" 608 fi 609 610 # We're going to generate a wrapper toolchain with the $HOST prefix 611 # i.e. if $HOST is 'i686-linux-gnu', then we're going to generate a 612 # wrapper toolchain named 'i686-linux-gnu-gcc' that will redirect 613 # to whatever HOST_FULLPREFIX points to, with appropriate modifier 614 # compiler/linker flags. 615 # 616 # This helps tremendously getting stuff to compile with the GCC 617 # configure scripts. 618 # 619 run mkdir -p "$BH_WRAPPERS_DIR" && 620 run $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh "$BH_WRAPPERS_DIR" \ 621 --src-prefix="$BH_HOST_CONFIG-" \ 622 --dst-prefix="$DST_PREFIX" \ 623 --cflags="$HOST_CFLAGS" \ 624 --cxxflags="$HOST_CXXFLAGS" \ 625 --ldflags="$HOST_LDFLAGS" \ 626 $CCACHE 627} 628 629 630# Setup the build directory, i.e. a directory where all intermediate 631# files will be placed. 632# 633# $1: Build directory. If empty, a random one will be selected. 634# 635# $2: Either 'preserve' or 'remove'. Indicates what to do of 636# existing files in the build directory, if any. 637# 638# $3: Either 'release' or 'debug'. Compilation mode. 639# 640bh_setup_build_dir () 641{ 642 BH_BUILD_DIR="$1" 643 if [ -z "$BH_BUILD_DIR" ]; then 644 BH_BUILD_DIR=/tmp/ndk-$USER/buildhost 645 fi 646 mkdir -p "$BH_BUILD_DIR" 647 fail_panic "Could not create build directory: $BH_BUILD_DIR" 648 649 setup_default_log_file $BH_BUILD_DIR/build.log 650 651 if [ "$_BH_OPTION_FORCE" ]; then 652 rm -rf "$BH_BUILD_DIR"/* 653 fi 654 655 if [ "$_BH_OPTION_NO_STRIP" ]; then 656 BH_BUILD_MODE=debug 657 else 658 BH_BUILD_MODE=release 659 fi 660 661 # The directory that will contain our toolchain wrappers 662 BH_WRAPPERS_DIR=$BH_BUILD_DIR/toolchain-wrappers 663 rm -rf "$BH_WRAPPERS_DIR" && mkdir "$BH_WRAPPERS_DIR" 664 fail_panic "Could not create wrappers dir: $BH_WRAPPERS_DIR" 665 666 # The directory that will contain our timestamps 667 BH_STAMPS_DIR=$BH_BUILD_DIR/timestamps 668 mkdir -p "$BH_STAMPS_DIR" 669 fail_panic "Could not create timestamps dir" 670} 671 672# Call this before anything else to setup a few important variables that are 673# used consistently to build any host-specific binaries. 674# 675# $1: Host system name (e.g. linux-x86), this is the name of the host system 676# where the generated GCC binaries will run, not the current machine's 677# type (this one is in $ORIGINAL_HOST_TAG instead). 678# 679bh_setup_build_for_host () 680{ 681 local HOST_VARNAME=$(dashes_to_underscores $1) 682 local HOST_VAR=_BH_HOST_${HOST_VARNAME} 683 684 # Determine the host configuration triplet in $HOST 685 bh_set_host_tag $1 686 687 # Note: since _bh_select_toolchain_for_host can change the value of 688 # $BH_HOST_CONFIG, we need to save it in a variable to later get the 689 # correct one when this function is called again. 690 if [ -z "$(var_value ${HOST_VAR}_SETUP)" ]; then 691 _bh_select_toolchain_for_host $1 692 var_assign ${HOST_VAR}_CONFIG $BH_HOST_CONFIG 693 var_assign ${HOST_VAR}_SETUP true 694 else 695 BH_HOST_CONFIG=$(var_value ${HOST_VAR}_CONFIG) 696 fi 697} 698 699# This function is used to setup the build environment whenever we 700# generate host-specific binaries. You should call it before invoking 701# a configure script or make. 702# 703# It assume sthat bh_setup_build_for_host was called with the right 704# host system tag and wrappers directory. 705# 706bh_setup_host_env () 707{ 708 CC=$BH_HOST_CONFIG-gcc 709 CXX=$BH_HOST_CONFIG-g++ 710 LD=$BH_HOST_CONFIG-ld 711 AR=$BH_HOST_CONFIG-ar 712 AS=$BH_HOST_CONFIG-as 713 RANLIB=$BH_HOST_CONFIG-ranlib 714 NM=$BH_HOST_CONFIG-nm 715 STRIP=$BH_HOST_CONFIG-strip 716 STRINGS=$BH_HOST_CONFIG-strings 717 export CC CXX LD AR AS RANLIB NM STRIP STRINGS 718 719 CFLAGS= 720 CXXFLAGS= 721 LDFLAGS= 722 case $BH_BUILD_MODE in 723 release) 724 CFLAGS="-O2 -Os -fomit-frame-pointer -s" 725 CXXFLAGS=$CFLAGS 726 ;; 727 debug) 728 CFLAGS="-O0 -g" 729 CXXFLAGS=$CFLAGS 730 ;; 731 esac 732 export CFLAGS CXXFLAGS LDFLAGS 733 734 export PATH=$BH_WRAPPERS_DIR:$PATH 735} 736 737_bh_option_no_color () 738{ 739 bh_set_color_mode off 740} 741 742# This function is used to register a few command-line options that 743# impact the build of host binaries. Call it before invoking 744# extract_parameters to add them automatically. 745# 746bh_register_options () 747{ 748 BH_HOST_SYSTEMS="$BH_BUILD_TAG" 749 register_var_option "--systems=<list>" BH_HOST_SYSTEMS "Build binaries that run on these systems." 750 751 _BH_OPTION_FORCE= 752 register_var_option "--force" _BH_OPTION_FORCE "Force rebuild." 753 754 _BH_OPTION_NO_STRIP= 755 register_var_option "--no-strip" _BH_OPTION_NO_STRIP "Don't strip generated binaries." 756 757 register_option "--no-color" _bh_option_no_color "Don't output colored text." 758 759 if [ "$HOST_OS" = darwin ]; then 760 DARWIN_SDK_VERSION= 761 register_var_option "--darwin-sdk-version=<version>" DARWIN_SDK "Select Darwin SDK version." 762 763 DARWIN_MIN_VERSION= 764 register_var_option "--darwin-min-version=<version>" DARWIN_MIN_VERSION "Select minimum OS X version of generated host toolchains." 765 fi 766} 767 768# Execute a given command if the corresponding timestamp hasn't been touched 769# 770# NOTE: The command is run in its own sub-shell to avoid environment 771# contamination. 772# 773# $1: timestamps name 774# $2+: command 775bh_stamps_do () 776{ 777 local STAMP_NAME=$1 778 shift 779 if [ ! -f "$BH_STAMPS_DIR/$STAMP_NAME" ]; then 780 ("$@") 781 fail_panic 782 mkdir -p "$BH_STAMPS_DIR" && touch "$BH_STAMPS_DIR/$STAMP_NAME" 783 fi 784} 785 786# Return host tag with only translation that windows-x86 -> windows 787# 788# $1: host system tag 789install_dir_from_host_tag () 790{ 791 case $1 in 792 windows-x86) 793 echo "windows" 794 ;; 795 *) 796 echo "$1" 797 ;; 798 esac 799} 800 801# Return the build install directory of a given Python version 802# 803# $1: host system tag 804# $2: python version 805# The suffix of this has to match python_ndk_install_dir 806# as I package them from the build folder, substituting 807# the end part of python_build_install_dir matching 808# python_ndk_install_dir with nothing. 809python_build_install_dir () 810{ 811 echo "$BH_BUILD_DIR/install/prebuilt/$(install_dir_from_host_tag $1)" 812} 813 814# Same as python_build_install_dir, but for the final NDK installation 815# directory. Relative to $NDK_DIR. 816# 817# $1: host system tag 818python_ndk_install_dir () 819{ 820 echo "prebuilt/$(install_dir_from_host_tag $1)" 821} 822