1#!/bin/sh 2# 3# Copyright (C) 2010 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 run all NDK build tests in a row. 18# "Build tests" are tests that check the building features of the NDK 19# but do not run anything on target devices/emulators. 20# 21 22# You need to define the NDK 23 24PROGDIR=`dirname $0` 25PROGDIR=`cd $PROGDIR && pwd` 26 27# Assume that we are under tests/ 28# and that the samples will be under samples/ and platforms/android-N/samples/ 29# 30ROOTDIR=`cd $PROGDIR/.. && pwd` 31NDK_BUILDTOOLS_PATH=$ROOTDIR/build/tools 32. $NDK_BUILDTOOLS_PATH/ndk-common.sh 33. $NDK_BUILDTOOLS_PATH/prebuilt-common.sh 34 35# Defining _NDK_TESTING_ALL_=yes to put armeabi-v7a-hard in its own libs/armeabi-v7a-hard 36# directoy and tested separately from armeabi-v7a. Some tests are now compiled with both 37# APP_ABI=armeabi-v7a and APP_ABI=armeabi-v7a-hard. Without _NDK_TESTING_ALL_=yes, tests 38# may fail to install due to race condition on the same libs/armeabi-v7a 39if [ -z "$_NDK_TESTING_ALL_" ]; then 40 _NDK_TESTING_ALL_=all 41fi 42export _NDK_TESTING_ALL_ 43 44# The list of tests that are too long to be part of a normal run of 45# run-tests.sh. Most of these do not run properly at the moment. 46LONG_TESTS="prebuild-stlport test-stlport test-gnustl-full \ 47test-stlport_shared-exception test-stlport_static-exception \ 48test-gnustl_shared-exception-full test-gnustl_static-exception-full \ 49test-googletest-full test-libc++-shared-full test-libc++-static-full" 50 51# 52# Parse options 53# 54VERBOSE=no 55ABI=default 56PLATFORM="" 57NDK_ROOT= 58JOBS=$BUILD_NUM_CPUS 59find_program ADB_CMD adb 60TESTABLES="samples build device awk" 61FULL_TESTS=no 62RUN_TESTS= 63RUN_TESTS_FILTERED= 64NDK_PACKAGE= 65WINE= 66CONTINUE_ON_BUILD_FAIL= 67if [ -z "$TEST_DIR" ]; then 68 TEST_DIR="/tmp/ndk-$USER/tests" 69fi 70if [ -z "$TARGET_TEST_SUBDIR" ]; then 71 TARGET_TEST_SUBDIR="ndk-tests" 72fi 73 74while [ -n "$1" ]; do 75 opt="$1" 76 optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` 77 case "$opt" in 78 --help|-h|-\?) 79 OPTION_HELP=yes 80 ;; 81 --verbose) 82 if [ "$VERBOSE" = "yes" ] ; then 83 VERBOSE2=yes 84 else 85 VERBOSE=yes 86 fi 87 ;; 88 --abi=*) 89 ABI="$optarg" 90 ;; 91 --platform=*) 92 PLATFORM="$optarg" 93 ;; 94 --test-dir=*) 95 TEST_DIR="$optarg" 96 ;; 97 --ndk=*) 98 NDK_ROOT="$optarg" 99 ;; 100 --full) 101 FULL_TESTS=yes; 102 ;; 103 --test=*) 104 RUN_TESTS="$RUN_TESTS $optarg" 105 ;; 106 --test-filtered=*) 107 # same as --test but apply BROKEN_RUN too. Useful for projects with tons of test some of them can't run 108 RUN_TESTS="$RUN_TESTS $optarg" 109 RUN_TESTS_FILTERED="yes" 110 ;; 111 --package=*) 112 NDK_PACKAGE="$optarg" 113 ;; 114 -j*) 115 JOBS=`expr "$opt" : '-j\(.*\)'` 116 shift 117 ;; 118 --jobs=*) 119 JOBS="$optarg" 120 ;; 121 --adb=*) 122 ADB_CMD="$optarg" 123 ;; 124 --only-samples) 125 TESTABLES=samples 126 ;; 127 --only-build) 128 TESTABLES=build 129 ;; 130 --only-device) 131 TESTABLES=device 132 ;; 133 --only-awk) 134 TESTABLES=awk 135 ;; 136 --wine) 137 WINE=yes 138 ;; 139 --continue-on-build-fail) 140 CONTINUE_ON_BUILD_FAIL=yes 141 ;; 142 -*) # unknown options 143 echo "ERROR: Unknown option '$opt', use --help for list of valid ones." 144 exit 1 145 ;; 146 *) # Simply record new test name 147 RUN_TESTS=$RUN_TESTS" $opt" 148 ;; 149 esac 150 shift 151done 152 153if [ "$OPTION_HELP" = "yes" ] ; then 154 echo "Usage: $PROGNAME [options] [testname1 [testname2...]]" 155 echo "" 156 echo "Run NDK automated tests. Without any parameter, this will try to" 157 echo "run all standard tests, except those are tagged broken. You can" 158 echo "also select/enforce specific tests by listing their name on the" 159 echo "command-line." 160 echo "" 161 echo "Valid options:" 162 echo "" 163 echo " --help|-h|-? Print this help" 164 echo " --verbose Enable verbose mode (can be used several times)" 165 echo " --ndk=<path> Path to NDK to test [$ROOTDIR]" 166 echo " --package=<path> Path to NDK package to test" 167 echo " -j<N> --jobs=<N> Launch parallel builds [$JOBS]" 168 echo " --abi=<name> Only run tests for the specific ABI [$ABI]" 169 echo " --platform=<name> Force API level for testing; platform=<android-x>" 170 echo " --adb=<file> Specify adb executable for device tests" 171 echo " --only-samples Only rebuild samples" 172 echo " --only-build Only rebuild build tests" 173 echo " --only-device Only rebuild & run device tests" 174 echo " --only-awk Only run awk tests." 175 echo " --full Run all device tests, even very long ones." 176 echo " --wine Build all tests with wine on Linux" 177 echo "" 178 echo "NOTE: You cannot use --ndk and --package at the same time." 179 echo "" 180 exit 0 181fi 182 183# Run a command in ADB. 184# 185# This is needed because "adb shell" does not return the proper status 186# of the launched command, so we need to add it to the output, and grab 187# it after that. 188# $1: Device name 189# $2: Variable name that will contain the result 190# $3+: Command options 191adb_var_shell_cmd () 192{ 193 # We need a temporary file to store the output of our command 194 local ADB_SHELL_CMD_LOG RET OUT 195 local DEVICE=$1 196 local VARNAME=$2 197 shift; shift; 198 ADB_SHELL_CMD_LOG=$(mktemp -t XXXXXXXX) 199 # Run the command, while storing the standard output to ADB_SHELL_CMD_LOG 200 # and appending the exit code as the last line. 201 if [ $VERBOSE = "yes" ] ; then 202 echo "$ADB_CMD -s \"$DEVICE\" shell \"$@\"" 203 $ADB_CMD -s "$DEVICE" shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' | tee $ADB_SHELL_CMD_LOG 204 else 205 $ADB_CMD -s "$DEVICE" shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' > $ADB_SHELL_CMD_LOG 206 fi 207 # Get last line in log, which contains the exit code from the command 208 RET=`sed -e '$!d' $ADB_SHELL_CMD_LOG` 209 # Get output, which corresponds to everything except the last line 210 OUT=`sed -e '$d' $ADB_SHELL_CMD_LOG` 211 rm -f $ADB_SHELL_CMD_LOG 212 if [ "$VARNAME" != "" ]; then 213 eval $VARNAME=\"\$OUT\" 214 fi 215 return $RET 216} 217 218# Make a directory path on device 219# 220# The 'mkdir' command on the Android device does not 221# support the '-p' option. This function will test 222# for the existence of the parent directory and recursively 223# call itself until it files a parent which exists; then 224# create the requested directory. 225adb_shell_mkdir () 226{ 227 local FULLDIR BASEDIR 228 local DEVICE=$1 229 local FULLDIR=$2 230 local BASEDIR=`dirname $FULLDIR` 231 232 adb_var_shell_cmd "$DEVICE" "" "ls $BASEDIR 1>/dev/null 2>&1" 233 if [ $? != 0 ] ; then 234 if [ $BASEDIR = "/" ] ; then 235 dump "ERROR: Could not find the root (/) directory on the device!" 236 exit 1 237 else 238 adb_shell_mkdir "$DEVICE" $BASEDIR 239 adb_shell_mkdir "$DEVICE" $FULLDIR 240 fi 241 else 242 #If the directory doesn't exist, make it 243 adb_var_shell_cmd "$DEVICE" "" "ls $FULLDIR 1>/dev/null 2>&1 || mkdir $FULLDIR" 244 if [ $? != 0 ] ; then 245 dump "ERROR: Could not mkdir '$FULLDIR' on the device!" 246 exit 1 247 fi 248 fi 249} 250 251# Returns 0 if a variable containing one or more items separated 252# by spaces contains a given value. 253# $1: variable name (e.g. FOO) 254# $2: value to test 255var_list_contains () 256{ 257 echo `var_value $1` | tr ' ' '\n' | grep -q -F -x -e "$2" 258} 259 260# 261# List of stuff to actually tests 262# 263is_testable () { 264 var_list_contains TESTABLES "$1" 265} 266 267# is_buildable returns 0 if a test should be built/run for this invocation 268# $1: test path 269if [ -n "$RUN_TESTS" ] ; then 270 is_buildable () { 271 [ -f $1/build.sh -o -f $1/jni/Android.mk ] && 272 var_list_contains RUN_TESTS "`basename $1`" 273 } 274elif [ "$FULL_TESTS" = "yes" ] ; then 275 is_buildable () { 276 [ -f $1/build.sh -o -f $1/jni/Android.mk ] 277 } 278else # !FULL_TESTS 279 is_buildable () { 280 [ -f $1/build.sh -o -f $1/jni/Android.mk ] || return 1 281 ! var_list_contains LONG_TESTS "`basename $1`" || return 1 282 } 283fi # !FULL_TESTS 284 285 286mkdir -p $TEST_DIR 287setup_default_log_file "$TEST_DIR/build-tests.log" 288 289if [ -n "$NDK_PACKAGE" ] ; then 290 if [ -n "$NDK_ROOT" ] ; then 291 dump "ERROR: You can't use --ndk and --package at the same time!" 292 exit 1 293 fi 294 NDK_ROOT=/tmp/ndk-tests/install 295 mkdir -p "$NDK_ROOT" && rm -rf "$NDK_ROOT/*" 296 dump "Unpacking NDK package to $NDK_ROOT" 297 unpack_archive "$NDK_PACKAGE" "$NDK_ROOT" 298 NDK_ROOT=`ls -d $NDK_ROOT/*` 299fi 300 301# 302# Check the NDK install path. 303# 304if [ -n "$NDK_ROOT" ] ; then 305 if [ ! -d "$NDK_ROOT" ] ; then 306 dump "ERROR: Your --ndk option does not point to a directory: $NDK_ROOT" 307 dump "Please use a valid path for this option." 308 exit 1 309 fi 310 if [ ! -f "$NDK_ROOT/ndk-build" -o ! -f "$NDK_ROOT/build/tools/prebuilt-common.sh" ] ; then 311 dump "ERROR: Your --ndk option does not point to a valid NDK install: $NDK_ROOT" 312 dump "Please use a valid NDK install path for this option." 313 exit 3 314 fi 315 NDK="$NDK_ROOT" 316else 317 NDK="$ROOTDIR" 318fi 319 320# 321# Create log file 322# 323 324BUILD_DIR=$TEST_DIR/build 325mkdir -p "$BUILD_DIR" && rm -rf "$BUILD_DIR/*" 326 327# 328# Add -link-native-binary to allow linking native binaries 329# 330if [ "$NDK_ABI_FILTER" != "${NDK_ABI_FILTER%%bc*}" ] ; then 331 APP_LDFLAGS="$APP_LDFLAGS -Wl,-link-native-binary" 332fi 333 334 335### 336### RUN AWK TESTS 337### 338 339# Run a simple awk script 340# $1: awk script to run 341# $2: input file 342# $3: expected output file 343# $4+: optional additional command-line arguments for the awk command 344run_awk_test () 345{ 346 local SCRIPT="$1" 347 local SCRIPT_NAME="`basename $SCRIPT`" 348 local INPUT="$2" 349 local INPUT_NAME="`basename $INPUT`" 350 local EXPECTED="$3" 351 local EXPECTED_NAME="`basename $EXPECTED`" 352 shift; shift; shift; 353 local OUTPUT="$BUILD_DIR/$EXPECTED_NAME" 354 if [ "$VERBOSE2" = "yes" ]; then 355 echo "### COMMAND: awk -f \"$SCRIPT\" $@ < \"$INPUT\" > \"$OUTPUT\"" 356 fi 357 awk -f "$SCRIPT" $@ < "$INPUT" > "$OUTPUT" 358 fail_panic "Can't run awk script: $SCRIPT" 359 if [ "$VERBOSE2" = "yes" ]; then 360 echo "OUTPUT FROM SCRIPT:" 361 cat "$OUTPUT" 362 echo "EXPECTED VALUES:" 363 cat "$EXPECTED" 364 fi 365 cmp -s "$OUTPUT" "$EXPECTED" 366 if [ $? = 0 ] ; then 367 echo "Awk script: $SCRIPT_NAME: passed $INPUT_NAME" 368 if [ "$VERBOSE2" = "yes" ]; then 369 cat "$OUTPUT" 370 fi 371 else 372 if [ "$VERBOSE" = "yes" ]; then 373 run diff -burN "$EXPECTED" "$OUTPUT" 374 fi 375 echo "Awk script: $SCRIPT_NAME: $INPUT_NAME FAILED!!" 376 rm -f "$OUTPUT" 377 exit 1 378 fi 379} 380 381run_awk_test_dir () 382{ 383 local SCRIPT_NAME="`basename \"$DIR\"`" 384 local SCRIPT="$ROOTDIR/build/awk/$SCRIPT_NAME.awk" 385 local INPUT 386 local OUTPUT 387 if [ ! -f "$SCRIPT" ]; then 388 echo "Awk script: $SCRIPT_NAME: Missing script: $SCRIPT" 389 continue 390 fi 391 for INPUT in `ls "$PROGDIR"/awk/$SCRIPT_NAME/*.in`; do 392 OUTPUT=`echo $INPUT | sed 's/\.in$/.out/g'` 393 if [ ! -f "$OUTPUT" ]; then 394 echo "Awk script: $SCRIPT_NAME: Missing awk output file: $OUTPUT" 395 continue 396 fi 397 run_awk_test "$SCRIPT" "$INPUT" "$OUTPUT" 398 done 399} 400 401if is_testable awk; then 402 AWKDIR="$ROOTDIR/build/awk" 403 for DIR in `ls -d "$PROGDIR"/awk/*`; do 404 run_awk_test_dir "$DIR" 405 done 406fi 407 408### 409### REBUILD ALL SAMPLES FIRST 410### 411 412NDK_BUILD_FLAGS="-B" 413if [ "$WINE" ]; then 414 case "$NDK_HOST_32BIT" in 415 1|true) 416 WINE=wine12 417 ;; 418 *) 419 WINE=wine17 420 NDK_BUILD_FLAGS="" # make.exe -B hangs in wine > 1.2.x 421 if [ "$NDK_TOOLCHAIN_VERSION" != "4.4.3" ] ; then 422 APP_LDFLAGS="$APP_LDFLAGS -fuse-ld=mcld" # 64-bit ld.gold can't run in any wine! 423 fi 424 ;; 425 esac 426 find_program WINE_PROG $WINE 427 fail_panic "Can't locate $WINE" 428fi 429 430# $1: output bitcode path 431gen_empty_bitcode() { 432 TEMP_FILE=`mktemp` 433 mv $TEMP_FILE ${TEMP_FILE}.c 434 run $NDK/$(get_llvm_toolchain_binprefix $DEFAULT_LLVM_VERSION)/clang -shared -target le32-none-ndk -emit-llvm -o $1 ${TEMP_FILE}.c 435 rm -f ${TEMP_FILE}.c 436} 437 438# $1: output archive path 439gen_empty_archive() { 440 run ar crs $1 441} 442 443case $ABI in 444 default) # Let the APP_ABI in jni/Application.mk decide what to build 445 ;; 446 armeabi|armeabi-v7a|arm64-v8a|x86|x86_64|mips|mips64|armeabi-v7a-hard) 447 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_ABI=$ABI" 448 ;; 449 *) 450 if [ -n "$(filter_out "$PREBUILT_ABIS" "$ABI")" ] && [ -n "$(find_ndk_unknown_archs)" ]; then 451 ABI=$(find_ndk_unknown_archs) 452 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_ABI=$ABI" 453 454 # Create those temporarily files to make testing happy 455 GCC_TOOLCHAIN_VERSION=`cat $NDK/toolchains/llvm-$DEFAULT_LLVM_VERSION/setup.mk | grep '^TOOLCHAIN_VERSION' | awk '{print $3'}` 456 run mkdir -p $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$ABI 457 run mkdir -p $NDK/$GABIXX_SUBDIR/libs/$ABI 458 run mkdir -p $NDK/$LIBPORTABLE_SUBDIR/libs/$ABI 459 run gen_empty_archive $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$ABI/libsupc++.a 460 run gen_empty_archive $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$ABI/libgnustl_static.a 461 run gen_empty_bitcode $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$ABI/libgnustl_shared.bc 462 run gen_empty_archive $NDK/$GABIXX_SUBDIR/libs/$ABI/libgabi++_static.a 463 run gen_empty_bitcode $NDK/$GABIXX_SUBDIR/libs/$ABI/libgabi++_shared.bc 464 run cp -a $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$(get_default_abi_for_arch arm)/include $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$ABI 465 else 466 echo "ERROR: Unsupported abi value: $ABI" 467 exit 1 468 fi 469 ;; 470esac 471 472# Force all tests to run at one API level 473if [ "$PLATFORM" != "" ]; then 474 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_PLATFORM=$PLATFORM" 475fi 476 477# Use --verbose twice to see build commands for the tests 478if [ "$VERBOSE2" = "yes" ] ; then 479 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS V=1" 480fi 481 482run_ndk_build () 483{ 484 if [ "$WINE" ]; then 485 if [ "$WINE" = "wine12" ]; then 486 run $WINE cmd /c Z:$NDK/ndk-build.cmd -j$JOBS "$@" APP_LDFLAGS="$APP_LDFLAGS" APP_CFLAGS="$APP_CFLAGS" 487 else 488 # do "clean" instead of -B 489 run $WINE cmd /c Z:$NDK/ndk-build.cmd clean 490 # make.exe can't do parallel build in wine > 1.2.x 491 run $WINE cmd /c Z:$NDK/ndk-build.cmd "$@" -j1 APP_LDFLAGS="$APP_LDFLAGS" APP_CFLAGS="$APP_CFLAGS" 492 fi 493 else 494 run $NDK/ndk-build -j$JOBS "$@" APP_LDFLAGS="$APP_LDFLAGS" APP_CFLAGS="$APP_CFLAGS" 495 fi 496} 497 498# get build var 499# $1: project directory 500# $2: var 501get_build_var () 502{ 503 local PROJECT=$1 504 local VAR=$2 505 506 if [ -z "$GNUMAKE" ] ; then 507 GNUMAKE=make 508 fi 509 $GNUMAKE --no-print-dir -f $NDK/build/core/build-local.mk -C $PROJECT DUMP_$VAR | tail -1 510} 511 512 513# check if the project is broken and shouldn't be built 514# $1: project directory 515# $2: optional error message 516is_broken_build () 517{ 518 local PROJECT="$1" 519 local ERRMSG="$2" 520 521 if [ -z "$RUN_TESTS" ] ; then 522 if [ -f "$PROJECT/BROKEN_BUILD" ] ; then 523 if [ ! -s "$PROJECT/BROKEN_BUILD" ] ; then 524 # skip all 525 if [ -z "$ERRMSG" ] ; then 526 echo "Skipping `basename $PROJECT`: (build)" 527 else 528 echo "Skipping $ERRMSG: `basename $PROJECT`" 529 fi 530 return 0 531 else 532 # only skip listed in file 533 TARGET_TOOLCHAIN=`get_build_var $PROJECT TARGET_TOOLCHAIN` 534 TARGET_TOOLCHAIN_VERSION=`echo $TARGET_TOOLCHAIN | tr '-' '\n' | tail -1` 535 grep -q -e "$TARGET_TOOLCHAIN_VERSION" "$PROJECT/BROKEN_BUILD" 536 if [ $? = 0 ] ; then 537 if [ -z "$ERRMSG" ] ; then 538 echo "Skipping `basename $PROJECT`: (no build for $TARGET_TOOLCHAIN_VERSION)" 539 else 540 echo "Skipping $ERRMSG: `basename $PROJECT` (no build for $TARGET_TOOLCHAIN_VERSION)" 541 fi 542 return 0 543 fi 544 # skip incompatible forced platform 545 if [ "$PLATFORM" != "" ] ; then 546 grep -q -e "$PLATFORM" "$PROJECT/BROKEN_BUILD" || grep -q -e "android-forced" "$PROJECT/BROKEN_BUILD" 547 if [ $? = 0 ] ; then 548 if [ -z "$ERRMSG" ] ; then 549 echo "Skipping `basename $PROJECT`: (no build for $PLATFORM)" 550 else 551 echo "Skipping $ERRMSG: `basename $PROJECT` (no build for $PLATFORM)" 552 fi 553 return 0 554 fi 555 fi 556 fi 557 fi 558 fi 559 return 1 560} 561 562# check if $ABI is incompatible and shouldn't be built 563# $1: project directory 564is_incompatible_abi () 565{ 566 local PROJECT="$1" 567 # Basically accept all for unknown arch, even some cases may not be suitable for this way 568 if [ "$ABI" != "default" -a "$ABI" != "$(find_ndk_unknown_archs)" ] ; then 569 # check APP_ABI 570 local APP_ABIS=`get_build_var $PROJECT APP_ABI` 571 APP_ABIS=$APP_ABIS" " 572 if [ "$APP_ABIS" != "${APP_ABIS%%all*}" ] ; then 573 # replace the first "all" with all available ABIs 574 ALL_ABIS=`get_build_var $PROJECT NDK_ALL_ABIS` 575 APP_ABIS_FRONT="${APP_ABIS%%all*}" 576 APP_ABIS_BACK="${APP_ABIS#*all}" 577 APP_ABIS="${APP_ABIS_FRONT}${ALL_ABIS}${APP_ABIS_BACK}" 578 fi 579 if [ "$APP_ABIS" = "${APP_ABIS%$ABI *}" ] ; then 580 echo "Skipping `basename $PROJECT`: incompatible ABI, needs $APP_ABIS" 581 return 0 582 fi 583 fi 584 return 1 585} 586 587compile_on_the_fly() 588{ 589 local DSTDIR="$1" 590 local COMPILER_PKGNAME="compiler.abcc" 591 if [ -z "`$ADB_CMD -s "$DEVICE" shell pm path $COMPILER_PKGNAME`" ]; then 592 dump "ERROR: No abcc found for unknown arch testing" 593 return 1 594 fi 595 run $ADB_CMD -s "$DEVICE" shell am force-stop $COMPILER_PKGNAME 596 run $ADB_CMD -s "$DEVICE" shell am startservice --user 0 -a ${COMPILER_PKGNAME}.BITCODE_COMPILE_TEST -n $COMPILER_PKGNAME/.AbccService -e working_dir $DSTDIR 597 598 old_pid="`$ADB_CMD -s "$DEVICE" shell top -n 1 | grep $COMPILER_PKGNAME | awk '{print $1}'`" 599 threshold=`echo $((60*10))` # Wait at most 10 minutes for large testcases 600 sleep_seconds=0 601 while [ 2 -eq 2 ]; do 602 if [ $sleep_seconds -gt $threshold ]; then 603 pid="`$ADB_CMD -s "$DEVICE" shell top -n 1 | grep $COMPILER_PKGNAME | awk '{print $1}'`" 604 if [ "$pid" = "$old_pid" ]; then 605 # Too much time 606 break 607 fi 608 old_pid="$pid" 609 sleep_seconds=0 610 fi 611 if [ -n "`$ADB_CMD -s "$DEVICE" shell ls $DSTDIR | grep compile_result`" ]; then 612 # Compile done 613 break 614 fi 615 sleep 3 616 sleep_seconds="`echo $sleep_seconds + 3 | bc`" 617 done 618 ret="`$ADB_CMD -s "$DEVICE" shell cat $DSTDIR/compile_result`" 619 ret=`echo $ret | tr -d "\r\n"` 620 if [ $sleep_seconds -gt $threshold ] || [ "$ret" != "0" ]; then 621 dump "ERROR: Could not compile bitcodes for $TEST_NAME on device" 622 if [ $sleep_seconds -gt $threshold ]; then 623 dump "- Reason: Compile time too long" 624 elif [ -n "`$ADB_CMD -s "$DEVICE" shell ls $DSTDIR | grep compile_error`" ]; then 625 dump "- Reason: `$ADB_CMD -s "$DEVICE" shell cat $DSTDIR/compile_error`" 626 fi 627 run $ADB_CMD -s "$DEVICE" shell am force-stop $COMPILER_PKGNAME 628 return 1 629 fi 630 run $ADB_CMD -s "$DEVICE" shell am force-stop $COMPILER_PKGNAME 631 return 0 632} 633 634 635build_project () 636{ 637 local NAME=`basename $1` 638 local CHECK_ABI=$2 639 local DIR="$BUILD_DIR/$NAME" 640 641 if is_broken_build $1; then 642 return 0; 643 fi 644 if [ "$CHECK_ABI" = "yes" ] ; then 645 if is_incompatible_abi $1 ; then 646 return 0 647 fi 648 fi 649 rm -rf "$DIR" && cp -r "$1" "$DIR" 650 # build it 651 (run cd "$DIR" && run_ndk_build $NDK_BUILD_FLAGS) 652 RET=$? 653 if [ -f "$1/BUILD_SHOULD_FAIL" ]; then 654 if [ $RET = 0 ]; then 655 echo "!!! FAILURE: BUILD SHOULD HAVE FAILED [$1]" 656 if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then 657 exit 1 658 fi 659 fi 660 log "!!! SUCCESS: BUILD FAILED AS EXPECTED [$(basename $1)]" 661 RET=0 662 fi 663 if [ $RET != 0 ] ; then 664 echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!" 665 if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then 666 exit 1 667 fi 668 fi 669} 670 671# 672# Determine list of samples directories. 673# 674if is_testable samples; then 675 if [ -f "$NDK/RELEASE.TXT" ] ; then 676 # This is a release package, all samples should be under $NDK/samples 677 SAMPLES_DIRS="$NDK/samples" 678 if [ ! -d "$SAMPLES_DIRS" ] ; then 679 dump "ERROR: Missing samples directory: $SAMPLES_DIRS" 680 dump "Your NDK release installation is broken!" 681 exit 1 682 fi 683 log "Using release NDK samples from: $SAMPLES_DIRS" 684 else 685 # This is a development work directory, we will take the samples 686 # directly from development/ndk. 687 DEVNDK_DIR=`dirname $NDK`/development/ndk 688 if [ ! -d "$DEVNDK_DIR" ] ; then 689 dump "ERROR: Could not find development NDK directory: $DEVNDK_DIR" 690 dump "Please clone platform/development.git from android.googlesource.com" 691 exit 1 692 fi 693 SAMPLES_DIRS="$DEVNDK_DIR/samples" 694 for DIR in `ls -d $DEVNDK_DIR/platforms/android-*/samples`; do 695 SAMPLES_DIRS="$SAMPLES_DIRS $DIR" 696 done 697 dump "Using development NDK samples from $DEVNDK_DIR" 698 if [ "$VERBOSE" = "yes" ] ; then 699 echo "$SAMPLES_DIRS" | tr ' ' '\n' 700 fi 701 fi 702 703 # 704 # Copy the samples to a temporary build directory 705 706 build_sample () 707 { 708 echo "Building NDK sample: `basename $1`" 709 build_project $1 "no" 710 } 711 712 for DIR in $SAMPLES_DIRS; do 713 for SUBDIR in `ls -d $DIR/*`; do 714 if is_buildable $SUBDIR; then 715 build_sample $SUBDIR 716 fi 717 done 718 done 719fi 720 721### 722### BUILD PROJECTS UNDER tests/build/ 723### 724 725if is_testable build; then 726 build_build_test () 727 { 728 local NAME="$(basename $1)" 729 echo "Building NDK build test: `basename $1`" 730 if [ -f $1/build.sh ]; then 731 local DIR="$BUILD_DIR/$NAME" 732 if [ -f "$1/jni/Android.mk" -a -f "$1/jni/Application.mk" ] ; then 733 # exclude jni/Android.mk with import-module because it needs NDK_MODULE_PATH 734 grep -q "call import-module" "$1/jni/Android.mk" 735 if [ $? != 0 ] ; then 736 if (is_broken_build $1 || is_incompatible_abi $1) then 737 return 0; 738 fi 739 fi 740 fi 741 rm -rf "$DIR" && cp -r "$1" "$DIR" 742 export NDK 743 (cd "$DIR" && run ./build.sh -j$JOBS $NDK_BUILD_FLAGS) 744 if [ $? != 0 ]; then 745 echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!" 746 if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then 747 exit 1 748 fi 749 fi 750 else 751 build_project $1 "yes" 752 fi 753 } 754 755 for DIR in `ls -d $ROOTDIR/tests/build/*`; do 756 if is_buildable $DIR; then 757 build_build_test $DIR 758 fi 759 done 760fi 761 762### 763### BUILD PROJECTS UNDER tests/device/ 764### 765 766CPU_ABIS= 767if is_testable device; then 768 build_device_test () 769 { 770 if is_broken_build $1 "broken device test build"; then 771 return 0; 772 fi 773 echo "Building NDK device test: `basename $1`" 774 build_project $1 "yes" 775 } 776 777 # $1: DEVICE 778 # $2: DEVICE CPU ABI 779 # $3: test 780 # $4: tmp dir 781 run_device_test () 782 { 783 local DEVICE=$1 784 local CPU_ABI=$2 785 local TEST=$3 786 local TEST_NAME="$(basename $TEST)" 787 local SRCDIR 788 local DSTDIR="$4/$TARGET_TEST_SUBDIR" 789 local SRCFILE 790 local DSTFILE 791 local PROGRAM 792 # Do not run the test if BROKEN_RUN is defined 793 if [ -z "$RUN_TESTS" ]; then 794 if is_broken_build $TEST "NDK device test not built"; then 795 return 0 796 fi 797 if [ -f "$TEST/BROKEN_RUN" ] ; then 798 if [ ! -s "$TEST/BROKEN_RUN" ] ; then 799 # skip all 800 dump "Skipping NDK device test run: $TEST_NAME" 801 return 0 802 else 803 # skip all tests built by toolchain 804 TARGET_TOOLCHAIN=`get_build_var $TEST TARGET_TOOLCHAIN` 805 TARGET_TOOLCHAIN_VERSION=`echo $TARGET_TOOLCHAIN | tr '-' '\n' | tail -1` 806 grep -q -e "$TARGET_TOOLCHAIN_VERSION" "$TEST/BROKEN_RUN" 807 if [ $? = 0 ] ; then 808 dump "Skipping NDK device test run: $TEST_NAME (no run for binary built by $TARGET_TOOLCHAIN_VERSION)" 809 return 0 810 fi 811 # skip tests listed in file 812 SKIPPED_EXECUTABLES=`cat $TEST/BROKEN_RUN | tr '\n' ' '` 813 dump "Skipping NDK device test run: $TEST_NAME ($SKIPPED_EXECUTABLES)" 814 fi 815 fi 816 fi 817 if [ "$ABI" = "$(find_ndk_unknown_archs)" ] && [ -d "$BUILD_DIR/`basename $TEST`/libs" ]; then 818 cd $BUILD_DIR/`basename $TEST`/libs && cp -a $ABI $CPU_ABI 819 fi 820 SRCDIR="$BUILD_DIR/`basename $TEST`/libs/$CPU_ABI" 821 if [ ! -d "$SRCDIR" ] || [ -z "`ls $SRCDIR`" ]; then 822 dump "Skipping NDK device test run (no $CPU_ABI binaries): $TEST_NAME" 823 return 0 824 fi 825 # First, copy all files to the device, except for gdbserver, gdb.setup, and 826 # those declared in $TEST/BROKEN_RUN 827 adb_shell_mkdir "$DEVICE" $DSTDIR 828 829 if [ "$ABI" = "$(find_ndk_unknown_archs)" ]; then # on-the-fly on-device compilation 830 run $ADB_CMD -s "$DEVICE" shell rm -rf $DSTDIR/abcc_tmp 831 adb_shell_mkdir "$DEVICE" $DSTDIR/abcc_tmp 832 run $ADB_CMD -s "$DEVICE" shell chmod 0777 $DSTDIR/abcc_tmp 833 for SRCFILE in `ls $SRCDIR`; do 834 run $ADB_CMD -s "$DEVICE" push "$SRCDIR/$SRCFILE" $DSTDIR/abcc_tmp 835 run $ADB_CMD -s "$DEVICE" shell chmod 0644 $DSTDIR/abcc_tmp/$SRCFILE 836 done 837 compile_on_the_fly $DSTDIR/abcc_tmp 838 if [ $? -ne 0 ]; then 839 test "$CONTINUE_ON_BUILD_FAIL" != "yes" && exit 1 840 return 1 841 fi 842 run rm -f $SRCDIR/* 843 run $ADB_CMD -s "$DEVICE" pull $DSTDIR/abcc_tmp $SRCDIR 844 run rm -f $SRCDIR/compile_result 845 run rm -f $SRCDIR/compile_error 846 run rm -f $SRCDIR/*$(get_lib_suffix_for_abi $ABI) 847 run $ADB_CMD -s "$DEVICE" shell rm -rf $DSTDIR/abcc_tmp 848 fi 849 850 for SRCFILE in `ls $SRCDIR`; do 851 DSTFILE=`basename $SRCFILE` 852 echo "$DSTFILE" | grep -q -e '\.so$' 853 if [ $? != 0 ] ; then 854 continue 855 fi 856 SRCPATH="$SRCDIR/$SRCFILE" 857 if [ $HOST_OS = cygwin ]; then 858 SRCPATH=`cygpath -m $SRCPATH` 859 fi 860 DSTPATH="$DSTDIR/$DSTFILE" 861 run $ADB_CMD -s "$DEVICE" push "$SRCPATH" "$DSTPATH" && 862 run $ADB_CMD -s "$DEVICE" shell chmod 0755 $DSTPATH 863 if [ $? != 0 ] ; then 864 dump "ERROR: Could not install $SRCPATH to device $DEVICE!" 865 exit 1 866 fi 867 done 868 869 for SRCFILE in `ls $SRCDIR`; do 870 DSTFILE=`basename $SRCFILE` 871 if [ "$DSTFILE" = "gdbserver" -o "$DSTFILE" = "gdb.setup" ] ; then 872 continue 873 fi 874 echo "$DSTFILE" | grep -q -e '\.so$' 875 if [ $? = 0 ] ; then 876 continue 877 fi 878 if [ -z "$RUN_TESTS" -o "$RUN_TESTS_FILTERED" = "yes" ]; then 879 if [ -f "$TEST/BROKEN_RUN" ]; then 880 grep -q -w -e "$DSTFILE" "$TEST/BROKEN_RUN" 881 if [ $? = 0 ] ; then 882 continue 883 fi 884 fi 885 fi 886 SRCPATH="$SRCDIR/$SRCFILE" 887 if [ $HOST_OS = cygwin ]; then 888 SRCPATH=`cygpath -m $SRCPATH` 889 fi 890 DSTPATH="$DSTDIR/$DSTFILE" 891 run $ADB_CMD -s "$DEVICE" push "$SRCPATH" "$DSTPATH" && 892 run $ADB_CMD -s "$DEVICE" shell chmod 0755 $DSTPATH 893 DATAPATHS= 894 if [ -f "$TEST/DATA" ]; then 895 if grep -q -e "$DSTFILE" "$TEST/DATA"; then 896 DATAPATHS=`grep -e "$DSTFILE" "$TEST/DATA" | awk '{print $2}'` 897 DATAPATHS=$NDK/$DATAPATHS 898 for DATA in $(ls $DATAPATHS); do 899 run $ADB_CMD -s "$DEVICE" push "$DATA" "$DSTDIR" 900 done 901 fi 902 fi 903 if [ $? != 0 ] ; then 904 dump "ERROR: Could not install $SRCPATH to device $DEVICE!" 905 exit 1 906 fi 907 PROGRAM="`basename $DSTPATH`" 908 dump "Running device test [$CPU_ABI]: $TEST_NAME (`basename $PROGRAM`)" 909 adb_var_shell_cmd "$DEVICE" "" "cd $DSTDIR && LD_LIBRARY_PATH=$DSTDIR ./$PROGRAM" 910 if [ $? != 0 ] ; then 911 dump " ---> TEST FAILED!!" 912 fi 913 adb_var_shell_cmd "$DEVICE" "" "rm -f $DSTPATH" 914 for DATA in $(ls $DATAPATHS); do 915 adb_var_shell_cmd "$DEVICE" "" "rm -f $DSTDIR/`basename $DATA`" 916 done 917 done 918 # Cleanup 919 adb_var_shell_cmd "$DEVICE" "" rm -r $DSTDIR 920 } 921 922 for DIR in `ls -d $ROOTDIR/tests/device/*`; do 923 if is_buildable $DIR; then 924 build_device_test $DIR 925 fi 926 done 927 928 # Do we have adb and any device connected here? 929 # If not, we can't run our tests. 930 # 931 SKIP_TESTS=no 932 if [ -z "$ADB_CMD" ] ; then 933 dump "WARNING: No 'adb' in your path!" 934 SKIP_TESTS=yes 935 else 936 # Get list of online devices, turn ' ' in device into '#' 937 ADB_DEVICES=`$ADB_CMD devices | grep -v offline | awk 'NR>1 {gsub(/[ \t]+device$/,""); print;}' | sed '/^$/d' | sort | tr ' ' '#'` 938 ADB_DEVICES=$(echo $ADB_DEVICES | tr '\n' ' ') 939 log2 "ADB online devices (sorted): $ADB_DEVICES" 940 ADB_DEVCOUNT=`echo "$ADB_DEVICES" | wc -w` 941 if [ "$ADB_DEVCOUNT" = "0" ]; then 942 dump "WARNING: No device connected to adb!" 943 SKIP_TESTS=yes 944 else 945 ADB_DEVICES="$ADB_DEVICES " 946 if [ -n "$ANDROID_SERIAL" ] ; then 947 # Expect ANDROID_SERIAL is comma-delimited of one or more devices 948 ANDROID_SERIAL=$(echo "$ANDROID_SERIAL" | tr ' ' '#') # turn ' ' into '#' 949 ANDROID_SERIAL=$(commas_to_spaces $ANDROID_SERIAL) 950 for SERIAL in $ANDROID_SERIAL; do 951 if [ "$ADB_DEVICES" = "${ADB_DEVICES%$SERIAL *}" ] ; then 952 dump "WARNING: Device $SERIAL cannot be found or offline!" 953 SKIP_TESTS=yes 954 fi 955 done 956 if [ "$SKIP_TESTS" != "yes" ] ; then 957 ADB_DEVICES="$ANDROID_SERIAL" 958 fi 959 fi 960 fi 961 fi 962 if [ "$SKIP_TESTS" = "yes" ] ; then 963 dump "SKIPPING RUNNING TESTS ON DEVICE!" 964 else 965 AT_LEAST_CPU_ABI_MATCH= 966 for DEVICE in $ADB_DEVICES; do 967 # undo earlier ' '-to-'#' translation 968 DEVICE=$(echo "$DEVICE" | tr '#' ' ') 969 # get device CPU_ABI and CPU_ABI2, each may contain list of abi, comma-delimited. 970 adb_var_shell_cmd "$DEVICE" CPU_ABI1 getprop ro.product.cpu.abi 971 adb_var_shell_cmd "$DEVICE" CPU_ABI2 getprop ro.product.cpu.abi2 972 CPU_ABIS="$CPU_ABI1,$CPU_ABI2" 973 CPU_ABIS=$(commas_to_spaces $CPU_ABIS) 974 if [ "$_NDK_TESTING_ALL_" = "yes" ]; then 975 if [ "$CPU_ABI1" = "armeabi-v7a" -o "$CPU_ABI2" = "armeabi-v7a" ]; then 976 CPU_ABIS="$CPU_ABIS armeabi-v7a-hard" 977 fi 978 fi 979 if [ "$CPU_ABIS" = " " ]; then 980 # Very old cupcake-based Android devices don't have these properties 981 # defined. Fortunately, they are all armeabi-based. 982 CPU_ABIS=armeabi 983 fi 984 log "CPU_ABIS=$CPU_ABIS" 985 for CPU_ABI in $CPU_ABIS; do 986 if [ "$ABI" = "default" -o "$ABI" = "$CPU_ABI" -o "$ABI" = "$(find_ndk_unknown_archs)" ] ; then 987 AT_LEAST_CPU_ABI_MATCH="yes" 988 for DIR in `ls -d $ROOTDIR/tests/device/*`; do 989 if is_buildable $DIR; then 990 log "Running device test on $DEVICE [$CPU_ABI]: $DIR" 991 run_device_test "$DEVICE" "$CPU_ABI" "$DIR" /data/local/tmp 992 fi 993 done 994 fi 995 done 996 done 997 if [ "$AT_LEAST_CPU_ABI_MATCH" != "yes" ] ; then 998 dump "WARNING: No device matches ABI $ABI! SKIPPING RUNNING TESTS ON DEVICE!" 999 fi 1000 fi 1001fi 1002 1003dump "Cleaning up..." 1004if [ "$ABI" = "$(find_ndk_unknown_archs)" ]; then 1005 # Cleanup some intermediate files for testing 1006 run rm -rf $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$ABI 1007 run rm -rf $NDK/$GABIXX_SUBDIR/libs/$ABI 1008 run rm -rf $NDK/$LIBPORTABLE_SUBDIR/libs/$ABI 1009fi 1010rm -rf $BUILD_DIR 1011dump "Done." 1012