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 # 65 BH_BUILD_OS=$HOST_OS 66 BH_BUILD_ARCH=$HOST_ARCH 67 BH_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) 72 bh_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) 87 bh_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) 102 bh_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 115 bh_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 133 bh_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. 143 bh_set_build_tag $HOST_TAG 144 145 bh_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 154 bh_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 163 bh_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. 185 bh_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' 210 bh_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 231 bh_set_color_mode true 232 233 # Pretty printing with colors! 234 bh_host_text () 235 { 236 printf "[${_BH_COLOR_GREEN}${BH_HOST_TAG}${_BH_COLOR_END}]" 237 } 238 239 bh_toolchain_text () 240 { 241 printf "[${_BH_COLOR_PURPLE}${BH_TOOLCHAIN}${_BH_COLOR_END}]" 242 } 243 244 bh_target_text () 245 { 246 printf "[${_BH_COLOR_CYAN}${BH_TARGET_TAG}${_BH_COLOR_END}]" 247 } 248 249 bh_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 # 269 bh_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 # 280 bh_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 # 295 bh_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 # 327 bh_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 336 int main(void) { return 0; } 337 EOF 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 */ 436 int tab[1-2*(sizeof(void*)*8 != BITS)]; 437 EOF 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 # 704 bh_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 # 743 bh_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 # 770 bh_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 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 # 810 bh_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 839 bh_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