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_bh_extract_version () 256{ 257 echo $1 | tr '-' '\n' | tail -1 258} 259 260# Given an input string of the form <foo>-<bar>-<version>, where 261# <version> can be <major>.<minor>, extract <major> 262# 263# $1: versioned name (e.g. arm-linux-androideabi-4.4.3) 264# Out: major version (e.g. 4) 265# 266# Examples: arm-linux-androideabi-4.4.3 -> 4 267# gmp-0.81 -> 0 268# 269bh_extract_major_version () 270{ 271 local RET=$(_bh_extract_version $1 | cut -d . -f 1) 272 RET=${RET:-0} 273 echo $RET 274} 275 276# Same as extract_major_version, but for the minor version number 277# $1: versioned named 278# Out: minor version 279# 280bh_extract_minor_version () 281{ 282 local RET=$(_bh_extract_version $1 | cut -d . -f 2) 283 RET=${RET:-0} 284 echo $RET 285} 286 287# Compare two version numbers and only succeeds if the first one is 288# greather or equal than the second one. 289# 290# $1: first version (e.g. 4.4.3) 291# $2: second version (e.g. 4.6) 292# 293# Example: version_is_greater_than 4.6 4.4.3 --> success 294# 295bh_version_is_greater_than () 296{ 297 local A_MAJOR A_MINOR B_MAJOR B_MINOR 298 A_MAJOR=$(bh_extract_major_version $1) 299 B_MAJOR=$(bh_extract_major_version $2) 300 301 if [ $A_MAJOR -lt $B_MAJOR ]; then 302 return 1 303 elif [ $A_MAJOR -gt $B_MAJOR ]; then 304 return 0 305 fi 306 307 # We have A_MAJOR == B_MAJOR here 308 309 A_MINOR=$(bh_extract_minor_version $1) 310 B_MINOR=$(bh_extract_minor_version $2) 311 312 if [ $A_MINOR -lt $B_MINOR ]; then 313 return 1 314 else 315 return 0 316 fi 317} 318 319# Check that a given compiler generates code correctly 320# 321# This is to detect bad/broken toolchains, e.g. amd64-mingw32msvc 322# is totally broken on Ubuntu 10.10 and 11.04 323# 324# $1: compiler 325# $2: optional extra flags 326# 327bh_check_compiler () 328{ 329 local CC="$1" 330 local TMPC=/tmp/build-host-$USER-$$.c 331 local TMPE=${TMPC%%.c} 332 local TMPL=$TMPC.log 333 local RET 334 shift 335 cat > $TMPC <<EOF 336int main(void) { return 0; } 337EOF 338 log_n "Checking compiler code generation ($CC)... " 339 $CC -o $TMPE $TMPC "$@" >$TMPL 2>&1 340 RET=$? 341 rm -f $TMPC $TMPE $TMPL 342 if [ "$RET" = 0 ]; then 343 log "yes" 344 else 345 log "no" 346 fi 347 return $RET 348} 349 350 351# $1: toolchain install dir 352# $2: toolchain prefix, no trailing dash (e.g. arm-linux-androideabi) 353# $3: optional -m32 or -m64. 354_bh_try_host_fullprefix () 355{ 356 local PREFIX="$1/bin/$2" 357 shift; shift; 358 if [ -z "$HOST_FULLPREFIX" ]; then 359 local GCC="$PREFIX-gcc" 360 if [ -f "$GCC" ]; then 361 if bh_check_compiler "$GCC" "$@"; then 362 HOST_FULLPREFIX="${GCC%%gcc}" 363 dump "$(bh_host_text) Using host gcc: $GCC $@" 364 else 365 dump "$(bh_host_text) Ignoring broken host gcc: $GCC $@" 366 fi 367 fi 368 fi 369} 370 371# $1: host prefix, no trailing slash (e.g. i686-linux-android) 372# $2: optional compiler args (should be empty, -m32 or -m64) 373_bh_try_host_prefix () 374{ 375 local PREFIX="$1" 376 shift 377 if [ -z "$HOST_FULLPREFIX" ]; then 378 local GCC="$(which $PREFIX-gcc 2>/dev/null)" 379 if [ "$GCC" -a -e "$GCC" ]; then 380 if bh_check_compiler "$GCC" "$@"; then 381 HOST_FULLPREFIX=${GCC%%gcc} 382 dump "$(bh_host_text) Using host gcc: ${HOST_FULLPREFIX}gcc $@" 383 else 384 dump "$(bh_host_text) Ignoring broken host gcc: $GCC $@" 385 fi 386 fi 387 fi 388} 389 390# Used to determine the minimum possible Darwin version that a Darwin SDK 391# can target. This actually depends from the host architecture. 392# $1: Host architecture name 393# out: SDK version number (e.g. 10.4 or 10.5) 394_bh_darwin_arch_to_min_version () 395{ 396 if [ "$1" = "x86" ]; then 397 echo "10.4" 398 else 399 echo "10.5" 400 fi 401} 402 403# Use the check for the availability of a compatibility SDK in Darwin 404# this can be used to generate binaries compatible with either Tiger or 405# Leopard. 406# 407# $1: SDK root path 408# $2: Darwin compatibility minimum version 409_bh_check_darwin_sdk () 410{ 411 if [ -d "$1" -a -z "$HOST_CFLAGS" ] ; then 412 HOST_CFLAGS="-isysroot $1 -mmacosx-version-min=$2 -DMAXOSX_DEPLOYEMENT_TARGET=$2" 413 HOST_CXXFLAGS=$HOST_CFLAGS 414 HOST_LDFLAGS="-syslibroot $1 -mmacosx-version-min=$2" 415 dump "Generating $2-compatible binaries." 416 return 0 # success 417 fi 418 return 1 419} 420 421# Check that a given compiler generates 32 or 64 bit code. 422# $1: compiler full path (.e.g /path/to/fullprefix-gcc) 423# $2: 32 or 64 424# $3: extract compiler flags 425# Return: success iff the compiler generates $2-bits code 426_bh_check_compiler_bitness () 427{ 428 local CC="$1" 429 local BITS="$2" 430 local TMPC=/tmp/build-host-gcc-bits-$USER-$$.c 431 local TMPL=$TMPC.log 432 local RET 433 shift; shift; 434 cat > $TMPC <<EOF 435/* this program will fail to compile if the compiler doesn't generate BITS-bits code */ 436int tab[1-2*(sizeof(void*)*8 != BITS)]; 437EOF 438 dump_n "$(bh_host_text) Checking that the compiler generates $BITS-bits code ($@)... " 439 $CC -c -DBITS=$BITS -o /dev/null $TMPC $HOST_CFLAGS "$@" > $TMPL 2>&1 440 RET=$? 441 rm -f $TMPC $TMPL 442 if [ "$RET" = 0 ]; then 443 dump "yes" 444 else 445 dump "no" 446 fi 447 return $RET 448} 449 450# This function probes the system to find the best toolchain or cross-toolchain 451# to build binaries that run on a given host system. After that, it generates 452# a wrapper toolchain under $2 with a prefix of ${BH_HOST_CONFIG}- 453# where $BH_HOST_CONFIG is a GNU configuration name. 454# 455# Important: this script might redefine $BH_HOST_CONFIG to a different value! 456# 457# $1: NDK system tag (e.g. linux-x86) 458# 459# The following can be defined, otherwise they'll be auto-detected and set. 460# 461# DARWIN_MIN_VERSION -> Darwmin minimum compatibility version 462# DARWIN_SDK_VERSION -> Darwin SDK version 463# 464# The following can be defined for extra features: 465# 466# DARWIN_TOOLCHAIN -> Path to Darwin cross-toolchain (cross-compile only). 467# DARWIN_SYSROOT -> Path to Darwin SDK sysroot (cross-compile only). 468# NDK_CCACHE -> Ccache binary to use to speed up rebuilds. 469# ANDROID_NDK_ROOT -> Top-level NDK directory, for automatic probing 470# of prebuilt platform toolchains. 471# 472_bh_select_toolchain_for_host () 473{ 474 local HOST_CFLAGS HOST_CXXFLAGS HOST_LDFLAGS HOST_FULLPREFIX DARWIN_ARCH 475 local DARWIN_ARCH DARWIN_SDK_SUBDIR 476 477 # We do all the complex auto-detection magic in the setup phase, 478 # then save the result in host-specific global variables. 479 # 480 # In the build phase, we will simply restore the values into the 481 # global HOST_FULLPREFIX / HOST_BUILD_DIR 482 # variables. 483 # 484 485 # Try to find the best toolchain to do that job, assuming we are in 486 # a full Android platform source checkout, we can look at the prebuilts/ 487 # directory. 488 case $1 in 489 linux-x86) 490 # If possible, automatically use our custom toolchain to generate 491 # 32-bit executables that work on Ubuntu 8.04 and higher. 492 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" i686-linux 493 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.4.3" i686-linux 494 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3" i686-linux 495 _bh_try_host_prefix i686-linux-gnu 496 _bh_try_host_prefix i686-linux 497 _bh_try_host_prefix x86_64-linux-gnu -m32 498 _bh_try_host_prefix x86_64-linux -m32 499 ;; 500 501 linux-x86_64) 502 # If possible, automaticaly use our custom toolchain to generate 503 # 64-bit executables that work on Ubuntu 8.04 and higher. 504 _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" x86_64-linux 505 _bh_try_host_prefix x86_64-linux-gnu 506 _bh_try_host_prefix x84_64-linux 507 _bh_try_host_prefix i686-linux-gnu -m64 508 _bh_try_host_prefix i686-linux -m64 509 ;; 510 511 darwin-*) 512 DARWIN_ARCH=$(bh_tag_to_arch $1) 513 if [ -z "$DARWIN_MIN_VERSION" ]; then 514 DARWIN_MIN_VERSION=$(_bh_darwin_arch_to_min_version $DARWIN_ARCH) 515 fi 516 case $BH_BUILD_OS in 517 darwin) 518 if [ "$DARWIN_SDK_VERSION" ]; then 519 # Compute SDK subdirectory name 520 case $DARWIN_SDK_VERSION in 521 10.4) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdku;; 522 *) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdk;; 523 esac 524 # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder. 525 _bh_check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_MIN_VERSION 526 _bh_check_darwin_sdk /Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_MIN_VERSION 527 else 528 # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder. 529 _bh_check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk $DARWIN_MIN_VERSION 530 _bh_check_darwin_sdk /Developer/SDKs/MacOSX10.7.sdk $DARWIN_MIN_VERSION 531 _bh_check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk $DARWIN_MIN_VERSION 532 # NOTE: The 10.5.sdk on Lion is buggy and cannot build basic C++ programs 533 #_bh_check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk $DARWIN_ARCH 534 # NOTE: The 10.4.sdku is not available anymore and could not be tested. 535 #_bh_check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku $DARWIN_ARCH 536 fi 537 if [ -z "$HOST_CFLAGS" ]; then 538 local version="$(sw_vers -productVersion)" 539 log "Generating $version-compatible binaries!" 540 fi 541 ;; 542 *) 543 if [ -z "$DARWIN_TOOLCHAIN" -o -z "$DARWIN_SYSROOT" ]; then 544 dump "If you want to build Darwin binaries on a non-Darwin machine," 545 dump "Please define DARWIN_TOOLCHAIN to name it, and DARWIN_SYSROOT to point" 546 dump "to the SDK. For example:" 547 dump "" 548 dump " DARWIN_TOOLCHAIN=\"i686-apple-darwin11\"" 549 dump " DARWIN_SYSROOT=\"~/darwin-cross/MacOSX10.7.sdk\"" 550 dump " export DARWIN_TOOLCHAIN DARWIN_SYSROOT" 551 dump "" 552 exit 1 553 fi 554 _bh_check_darwin_sdk $DARWIN_SYSROOT $DARWIN_MIN_VERSION 555 _bh_try_host_prefix "$DARWIN_TOOLCHAIN" -m$(bh_tag_to_bits $1) --sysroot "$DARWIN_SYSROOT" 556 if [ -z "$HOST_FULLPREFIX" ]; then 557 dump "It looks like $DARWIN_TOOLCHAIN-gcc is not in your path, or does not work correctly!" 558 exit 1 559 fi 560 dump "Using darwin cross-toolchain: ${HOST_FULLPREFIX}gcc" 561 ;; 562 esac 563 ;; 564 565 windows|windows-x86) 566 case $BH_BUILD_OS in 567 linux) 568 # We favor these because they are more recent, and because 569 # we have a script to rebuild them from scratch. See 570 # build-mingw64-toolchain.sh. 571 _bh_try_host_prefix x86_64-w64-mingw32 -m32 572 _bh_try_host_prefix i686-w64-mingw32 573 # Typically provided by the 'mingw32' package on Debian 574 # and Ubuntu systems. 575 _bh_try_host_prefix i586-mingw32msvc 576 # Special note for Fedora: this distribution used 577 # to have a mingw32-gcc package that provided a 32-bit 578 # only cross-toolchain named i686-pc-mingw32. 579 # Later versions of the distro now provide a new package 580 # named mingw-gcc which provides i686-w64-mingw32 and 581 # x86_64-w64-mingw32 instead. 582 _bh_try_host_prefix i686-pc-mingw32 583 if [ -z "$HOST_FULLPREFIX" ]; then 584 dump "There is no Windows cross-compiler. Ensure that you" 585 dump "have one of these installed and in your path:" 586 dump " x86_64-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 587 dump " i686-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 588 dump " i586-mingw32msvc-gcc ('mingw32' Debian/Ubuntu package)" 589 dump " i686-pc-mingw32 (on Fedora)" 590 dump "" 591 exit 1 592 fi 593 # Adjust $HOST to match the toolchain to ensure proper builds. 594 # I.e. chose configuration triplets that are known to work 595 # with the gmp/mpfr/mpc/binutils/gcc configure scripts. 596 case $HOST_FULLPREFIX in 597 *-mingw32msvc-*|i686-pc-mingw32) 598 BH_HOST_CONFIG=i586-pc-mingw32msvc 599 ;; 600 *) 601 BH_HOST_CONFIG=i686-w64-mingw32msvc 602 ;; 603 esac 604 ;; 605 *) panic "Sorry, this script only supports building windows binaries on Linux." 606 ;; 607 esac 608 HOST_CFLAGS=$HOST_CFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 609 HOST_CXXFLAGS=$HOST_CXXFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 610 ;; 611 612 windows-x86_64) 613 case $BH_BUILD_OS in 614 linux) 615 # See comments above for windows-x86 616 _bh_try_host_prefix x86_64-w64-mingw32 617 _bh_try_host_prefix i686-w64-mingw32 -m64 618 # Beware that this package is completely broken on many 619 # versions of no vinegar Ubuntu (i.e. it fails at building trivial 620 # programs). 621 _bh_try_host_prefix amd64-mingw32msvc 622 # There is no x86_64-pc-mingw32 toolchain on Fedora. 623 if [ -z "$HOST_FULLPREFIX" ]; then 624 dump "There is no Windows cross-compiler in your path. Ensure you" 625 dump "have one of these installed and in your path:" 626 dump " x86_64-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 627 dump " i686-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 628 dump " amd64-mingw32msvc-gcc (Debian/Ubuntu - broken until Ubuntu 11.10)" 629 dump "" 630 exit 1 631 fi 632 # See comment above for windows-x86 633 case $HOST_FULLPREFIX in 634 *-mingw32msvc*) 635 # Actually, this has never been tested. 636 BH_HOST=amd64-pc-mingw32msvc 637 ;; 638 *) 639 BH_HOST=x86_64-w64-mingw32 640 ;; 641 esac 642 ;; 643 644 *) panic "Sorry, this script only supports building windows binaries on Linux." 645 ;; 646 esac 647 HOST_CFLAGS=$HOST_CFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 648 HOST_CXXFLAGS=$HOST_CXXFLAGS" -D__USE_MINGW_ANSI_STDIO=1" 649 ;; 650 esac 651 652 # Determine the default bitness of our compiler. It it doesn't match 653 # HOST_BITS, tries to see if it supports -m32 or -m64 to change it. 654 if ! _bh_check_compiler_bitness ${HOST_FULLPREFIX}gcc $BH_HOST_BITS; then 655 local TRY_CFLAGS 656 case $BH_HOST_BITS in 657 32) TRY_CFLAGS=-m32;; 658 64) TRY_CFLAGS=-m64;; 659 esac 660 if ! _bh_check_compiler_bitness ${HOST_FULLPREFIX}gcc $BH_HOST_BITS $TRY_CFLAGS; then 661 panic "Can't find a way to generate $BH_HOST_BITS binaries with this compiler: ${HOST_FULLPREFIX}gcc" 662 fi 663 HOST_CFLAGS=$HOST_CFLAGS" "$TRY_CFLAGS 664 HOST_CXXFLAGS=$HOST_CXXFLAGS" "$TRY_CFLAGS 665 fi 666 667 # Support for ccache, to speed up rebuilds. 668 DST_PREFIX=$HOST_FULLPREFIX 669 local CCACHE= 670 if [ "$NDK_CCACHE" ]; then 671 CCACHE="--ccache=$NDK_CCACHE" 672 fi 673 674 # We're going to generate a wrapper toolchain with the $HOST prefix 675 # i.e. if $HOST is 'i686-linux-gnu', then we're going to generate a 676 # wrapper toolchain named 'i686-linux-gnu-gcc' that will redirect 677 # to whatever HOST_FULLPREFIX points to, with appropriate modifier 678 # compiler/linker flags. 679 # 680 # This helps tremendously getting stuff to compile with the GCC 681 # configure scripts. 682 # 683 run mkdir -p "$BH_WRAPPERS_DIR" && 684 run $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh "$BH_WRAPPERS_DIR" \ 685 --src-prefix="$BH_HOST_CONFIG-" \ 686 --dst-prefix="$DST_PREFIX" \ 687 --cflags="$HOST_CFLAGS" \ 688 --cxxflags="$HOST_CXXFLAGS" \ 689 --ldflags="$HOST_LDFLAGS" \ 690 $CCACHE 691} 692 693 694# Setup the build directory, i.e. a directory where all intermediate 695# files will be placed. 696# 697# $1: Build directory. If empty, a random one will be selected. 698# 699# $2: Either 'preserve' or 'remove'. Indicates what to do of 700# existing files in the build directory, if any. 701# 702# $3: Either 'release' or 'debug'. Compilation mode. 703# 704bh_setup_build_dir () 705{ 706 BH_BUILD_DIR="$1" 707 if [ -z "$BH_BUILD_DIR" ]; then 708 BH_BUILD_DIR=/tmp/ndk-$USER/buildhost 709 fi 710 mkdir -p "$BH_BUILD_DIR" 711 fail_panic "Could not create build directory: $BH_BUILD_DIR" 712 713 setup_default_log_file $BH_BUILD_DIR/build.log 714 715 if [ "$_BH_OPTION_FORCE" ]; then 716 rm -rf "$BH_BUILD_DIR"/* 717 fi 718 719 if [ "$_BH_OPTION_NO_STRIP" ]; then 720 BH_BUILD_MODE=debug 721 else 722 BH_BUILD_MODE=release 723 fi 724 725 # The directory that will contain our toolchain wrappers 726 BH_WRAPPERS_DIR=$BH_BUILD_DIR/toolchain-wrappers 727 rm -rf "$BH_WRAPPERS_DIR" && mkdir "$BH_WRAPPERS_DIR" 728 fail_panic "Could not create wrappers dir: $BH_WRAPPERS_DIR" 729 730 # The directory that will contain our timestamps 731 BH_STAMPS_DIR=$BH_BUILD_DIR/timestamps 732 mkdir -p "$BH_STAMPS_DIR" 733 fail_panic "Could not create timestamps dir" 734} 735 736# Call this before anything else to setup a few important variables that are 737# used consistently to build any host-specific binaries. 738# 739# $1: Host system name (e.g. linux-x86), this is the name of the host system 740# where the generated GCC binaries will run, not the current machine's 741# type (this one is in $ORIGINAL_HOST_TAG instead). 742# 743bh_setup_build_for_host () 744{ 745 local HOST_VARNAME=$(dashes_to_underscores $1) 746 local HOST_VAR=_BH_HOST_${HOST_VARNAME} 747 748 # Determine the host configuration triplet in $HOST 749 bh_set_host_tag $1 750 751 # Note: since _bh_select_toolchain_for_host can change the value of 752 # $BH_HOST_CONFIG, we need to save it in a variable to later get the 753 # correct one when this function is called again. 754 if [ -z "$(var_value ${HOST_VAR}_SETUP)" ]; then 755 _bh_select_toolchain_for_host $1 756 var_assign ${HOST_VAR}_CONFIG $BH_HOST_CONFIG 757 var_assign ${HOST_VAR}_SETUP true 758 else 759 BH_HOST_CONFIG=$(var_value ${HOST_VAR}_CONFIG) 760 fi 761} 762 763# This function is used to setup the build environment whenever we 764# generate host-specific binaries. You should call it before invoking 765# a configure script or make. 766# 767# It assume sthat bh_setup_build_for_host was called with the right 768# host system tag and wrappers directory. 769# 770bh_setup_host_env () 771{ 772 CC=$BH_HOST_CONFIG-gcc 773 CXX=$BH_HOST_CONFIG-g++ 774 LD=$BH_HOST_CONFIG-ld 775 AR=$BH_HOST_CONFIG-ar 776 AS=$BH_HOST_CONFIG-as 777 RANLIB=$BH_HOST_CONFIG-ranlib 778 NM=$BH_HOST_CONFIG-nm 779 STRIP=$BH_HOST_CONFIG-strip 780 STRINGS=$BH_HOST_CONFIG-strings 781 export CC CXX LD AR AS RANLIB NM STRIP STRINGS 782 783 CFLAGS= 784 CXXFLAGS= 785 LDFLAGS= 786 case $BH_BUILD_MODE in 787 release) 788 CFLAGS="-O2 -Os -fomit-frame-pointer -s" 789 CXXFLAGS=$CFLAGS 790 ;; 791 debug) 792 CFLAGS="-O0 -g" 793 CXXFLAGS=$CFLAGS 794 ;; 795 esac 796 export CFLAGS CXXFLAGS LDFLAGS 797 798 export PATH=$BH_WRAPPERS_DIR:$PATH 799} 800 801_bh_option_no_color () 802{ 803 bh_set_color_mode off 804} 805 806# This function is used to register a few command-line options that 807# impact the build of host binaries. Call it before invoking 808# extract_parameters to add them automatically. 809# 810bh_register_options () 811{ 812 BH_HOST_SYSTEMS="$BH_BUILD_TAG" 813 register_var_option "--systems=<list>" BH_HOST_SYSTEMS "Build binaries that run on these systems." 814 815 _BH_OPTION_FORCE= 816 register_var_option "--force" _BH_OPTION_FORCE "Force rebuild." 817 818 _BH_OPTION_NO_STRIP= 819 register_var_option "--no-strip" _BH_OPTION_NO_STRIP "Don't strip generated binaries." 820 821 register_option "--no-color" _bh_option_no_color "Don't output colored text." 822 823 if [ "$HOST_OS" = darwin ]; then 824 DARWIN_SDK_VERSION= 825 register_var_option "--darwin-sdk-version=<version>" DARWIN_SDK "Select Darwin SDK version." 826 827 DARWIN_MIN_VERSION= 828 register_var_option "--darwin-min-version=<version>" DARWIN_MIN_VERSION "Select minimum OS X version of generated host toolchains." 829 fi 830} 831 832# Execute a given command if the corresponding timestamp hasn't been touched 833# 834# NOTE: The command is run in its own sub-shell to avoid environment 835# contamination. 836# 837# $1: timestamps name 838# $2+: command 839bh_stamps_do () 840{ 841 local STAMP_NAME=$1 842 shift 843 if [ ! -f "$BH_STAMPS_DIR/$STAMP_NAME" ]; then 844 ("$@") 845 fail_panic 846 mkdir -p "$BH_STAMPS_DIR" && touch "$BH_STAMPS_DIR/$STAMP_NAME" 847 fi 848} 849 850# Return host tag with only translation that windows-x86 -> windows 851# 852# $1: host system tag 853install_dir_from_host_tag () 854{ 855 case $1 in 856 windows-x86) 857 echo "windows" 858 ;; 859 *) 860 echo "$1" 861 ;; 862 esac 863} 864 865# Return the build install directory of a given Python version 866# 867# $1: host system tag 868# $2: python version 869# The suffix of this has to match python_ndk_install_dir 870# as I package them from the build folder, substituting 871# the end part of python_build_install_dir matching 872# python_ndk_install_dir with nothing. 873python_build_install_dir () 874{ 875 echo "$BH_BUILD_DIR/install/prebuilt/$(install_dir_from_host_tag $1)" 876} 877 878# Same as python_build_install_dir, but for the final NDK installation 879# directory. Relative to $NDK_DIR. 880# 881# $1: host system tag 882python_ndk_install_dir () 883{ 884 echo "prebuilt/$(install_dir_from_host_tag $1)" 885} 886