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 "all", "all32" and "all64" 574 _EXPANDED=`get_build_var $PROJECT NDK_APP_ABI_ALL_EXPANDED` 575 _FRONT="${APP_ABIS%%all*}" 576 _BACK="${APP_ABIS#*all}" 577 APP_ABIS="${_FRONT}${_EXPANDED}${_BACK}" 578 _EXPANDED=`get_build_var $PROJECT NDK_APP_ABI_ALL32_EXPANDED` 579 _FRONT="${APP_ABIS%%all32*}" 580 _BACK="${APP_ABIS#*all32}" 581 APP_ABIS="${_FRONT}${_EXPANDED}${_BACK}" 582 _EXPANDED=`get_build_var $PROJECT NDK_APP_ABI_ALL64_EXPANDED` 583 _FRONT="${APP_ABIS%%all64*}" 584 _BACK="${APP_ABIS#*all64}" 585 APP_ABIS="${_FRONT}${_EXPANDED}${_BACK}" 586 fi 587 if [ "$APP_ABIS" = "${APP_ABIS%$ABI *}" ] ; then 588 echo "Skipping `basename $PROJECT`: incompatible ABI, needs $APP_ABIS" 589 return 0 590 fi 591 fi 592 return 1 593} 594 595compile_on_the_fly() 596{ 597 local DSTDIR="$1" 598 local COMPILER_PKGNAME="compiler.abcc" 599 if [ -z "`$ADB_CMD -s "$DEVICE" shell pm path $COMPILER_PKGNAME`" ]; then 600 dump "ERROR: No abcc found for unknown arch testing" 601 return 1 602 fi 603 run $ADB_CMD -s "$DEVICE" shell am force-stop $COMPILER_PKGNAME 604 run $ADB_CMD -s "$DEVICE" shell am startservice --user 0 -a ${COMPILER_PKGNAME}.BITCODE_COMPILE_TEST -n $COMPILER_PKGNAME/.AbccService -e working_dir $DSTDIR 605 606 old_pid="`$ADB_CMD -s "$DEVICE" shell top -n 1 | grep $COMPILER_PKGNAME | awk '{print $1}'`" 607 threshold=`echo $((60*10))` # Wait at most 10 minutes for large testcases 608 sleep_seconds=0 609 while [ 2 -eq 2 ]; do 610 if [ $sleep_seconds -gt $threshold ]; then 611 pid="`$ADB_CMD -s "$DEVICE" shell top -n 1 | grep $COMPILER_PKGNAME | awk '{print $1}'`" 612 if [ "$pid" = "$old_pid" ]; then 613 # Too much time 614 break 615 fi 616 old_pid="$pid" 617 sleep_seconds=0 618 fi 619 if [ -n "`$ADB_CMD -s "$DEVICE" shell ls $DSTDIR | grep compile_result`" ]; then 620 # Compile done 621 break 622 fi 623 sleep 3 624 sleep_seconds="`echo $sleep_seconds + 3 | bc`" 625 done 626 ret="`$ADB_CMD -s "$DEVICE" shell cat $DSTDIR/compile_result`" 627 ret=`echo $ret | tr -d "\r\n"` 628 if [ $sleep_seconds -gt $threshold ] || [ "$ret" != "0" ]; then 629 dump "ERROR: Could not compile bitcodes for $TEST_NAME on device" 630 if [ $sleep_seconds -gt $threshold ]; then 631 dump "- Reason: Compile time too long" 632 elif [ -n "`$ADB_CMD -s "$DEVICE" shell ls $DSTDIR | grep compile_error`" ]; then 633 dump "- Reason: `$ADB_CMD -s "$DEVICE" shell cat $DSTDIR/compile_error`" 634 fi 635 run $ADB_CMD -s "$DEVICE" shell am force-stop $COMPILER_PKGNAME 636 return 1 637 fi 638 run $ADB_CMD -s "$DEVICE" shell am force-stop $COMPILER_PKGNAME 639 return 0 640} 641 642 643build_project () 644{ 645 local NAME=`basename $1` 646 local CHECK_ABI=$2 647 local DIR="$BUILD_DIR/$NAME" 648 649 if is_broken_build $1; then 650 return 0; 651 fi 652 if [ "$CHECK_ABI" = "yes" ] ; then 653 if is_incompatible_abi $1 ; then 654 return 0 655 fi 656 fi 657 rm -rf "$DIR" && cp -r "$1" "$DIR" 658 # build it 659 (run cd "$DIR" && run_ndk_build $NDK_BUILD_FLAGS) 660 RET=$? 661 if [ -f "$1/BUILD_SHOULD_FAIL" ]; then 662 if [ $RET = 0 ]; then 663 echo "!!! FAILURE: BUILD SHOULD HAVE FAILED [$1]" 664 if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then 665 exit 1 666 fi 667 fi 668 log "!!! SUCCESS: BUILD FAILED AS EXPECTED [$(basename $1)]" 669 RET=0 670 fi 671 if [ $RET != 0 ] ; then 672 echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!" 673 if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then 674 exit 1 675 fi 676 fi 677} 678 679# 680# Determine list of samples directories. 681# 682if is_testable samples; then 683 if [ -f "$NDK/RELEASE.TXT" ] ; then 684 # This is a release package, all samples should be under $NDK/samples 685 SAMPLES_DIRS="$NDK/samples" 686 if [ ! -d "$SAMPLES_DIRS" ] ; then 687 dump "ERROR: Missing samples directory: $SAMPLES_DIRS" 688 dump "Your NDK release installation is broken!" 689 exit 1 690 fi 691 log "Using release NDK samples from: $SAMPLES_DIRS" 692 else 693 # This is a development work directory, we will take the samples 694 # directly from development/ndk. 695 DEVNDK_DIR=`dirname $NDK`/development/ndk 696 if [ ! -d "$DEVNDK_DIR" ] ; then 697 dump "ERROR: Could not find development NDK directory: $DEVNDK_DIR" 698 dump "Please clone platform/development.git from android.googlesource.com" 699 exit 1 700 fi 701 SAMPLES_DIRS="$DEVNDK_DIR/samples" 702 for DIR in `ls -d $DEVNDK_DIR/platforms/android-*/samples`; do 703 SAMPLES_DIRS="$SAMPLES_DIRS $DIR" 704 done 705 dump "Using development NDK samples from $DEVNDK_DIR" 706 if [ "$VERBOSE" = "yes" ] ; then 707 echo "$SAMPLES_DIRS" | tr ' ' '\n' 708 fi 709 fi 710 711 # 712 # Copy the samples to a temporary build directory 713 714 build_sample () 715 { 716 echo "Building NDK sample: `basename $1`" 717 build_project $1 "no" 718 } 719 720 for DIR in $SAMPLES_DIRS; do 721 for SUBDIR in `ls -d $DIR/*`; do 722 if is_buildable $SUBDIR; then 723 build_sample $SUBDIR 724 fi 725 done 726 done 727fi 728 729### 730### BUILD PROJECTS UNDER tests/build/ 731### 732 733if is_testable build; then 734 build_build_test () 735 { 736 local NAME="$(basename $1)" 737 echo "Building NDK build test: `basename $1`" 738 if [ -f $1/build.sh ]; then 739 local DIR="$BUILD_DIR/$NAME" 740 if [ -f "$1/jni/Android.mk" -a -f "$1/jni/Application.mk" ] ; then 741 # exclude jni/Android.mk with import-module because it needs NDK_MODULE_PATH 742 grep -q "call import-module" "$1/jni/Android.mk" 743 if [ $? != 0 ] ; then 744 if (is_broken_build $1 || is_incompatible_abi $1) then 745 return 0; 746 fi 747 fi 748 fi 749 rm -rf "$DIR" && cp -r "$1" "$DIR" 750 export NDK 751 (cd "$DIR" && run ./build.sh -j$JOBS $NDK_BUILD_FLAGS) 752 if [ $? != 0 ]; then 753 echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!" 754 if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then 755 exit 1 756 fi 757 fi 758 else 759 build_project $1 "yes" 760 fi 761 } 762 763 for DIR in `ls -d $ROOTDIR/tests/build/*`; do 764 if is_buildable $DIR; then 765 build_build_test $DIR 766 fi 767 done 768fi 769 770### 771### BUILD PROJECTS UNDER tests/device/ 772### 773 774CPU_ABIS= 775if is_testable device; then 776 build_device_test () 777 { 778 if is_broken_build $1 "broken device test build"; then 779 return 0; 780 fi 781 echo "Building NDK device test: `basename $1`" 782 build_project $1 "yes" 783 } 784 785 # $1: DEVICE 786 # $2: DEVICE CPU ABI 787 # $3: test 788 # $4: tmp dir 789 run_device_test () 790 { 791 local DEVICE=$1 792 local CPU_ABI=$2 793 local TEST=$3 794 local TEST_NAME="$(basename $TEST)" 795 local SRCDIR 796 local DSTDIR="$4/$TARGET_TEST_SUBDIR" 797 local SRCFILE 798 local DSTFILE 799 local PROGRAM 800 # Do not run the test if BROKEN_RUN is defined 801 if [ -z "$RUN_TESTS" ]; then 802 if is_broken_build $TEST "NDK device test not built"; then 803 return 0 804 fi 805 if [ -f "$TEST/BROKEN_RUN" ] ; then 806 if [ ! -s "$TEST/BROKEN_RUN" ] ; then 807 # skip all 808 dump "Skipping NDK device test run: $TEST_NAME" 809 return 0 810 else 811 # skip all tests built by toolchain 812 TARGET_TOOLCHAIN=`get_build_var $TEST TARGET_TOOLCHAIN` 813 TARGET_TOOLCHAIN_VERSION=`echo $TARGET_TOOLCHAIN | tr '-' '\n' | tail -1` 814 grep -q -e "$TARGET_TOOLCHAIN_VERSION" "$TEST/BROKEN_RUN" 815 if [ $? = 0 ] ; then 816 dump "Skipping NDK device test run: $TEST_NAME (no run for binary built by $TARGET_TOOLCHAIN_VERSION)" 817 return 0 818 fi 819 # skip tests listed in file 820 SKIPPED_EXECUTABLES=`cat $TEST/BROKEN_RUN | tr '\n' ' '` 821 dump "Skipping NDK device test run: $TEST_NAME ($SKIPPED_EXECUTABLES)" 822 fi 823 fi 824 fi 825 if [ "$ABI" = "$(find_ndk_unknown_archs)" ] && [ -d "$BUILD_DIR/`basename $TEST`/libs" ]; then 826 cd $BUILD_DIR/`basename $TEST`/libs && cp -a $ABI $CPU_ABI 827 fi 828 SRCDIR="$BUILD_DIR/`basename $TEST`/libs/$CPU_ABI" 829 if [ ! -d "$SRCDIR" ] || [ -z "`ls $SRCDIR`" ]; then 830 dump "Skipping NDK device test run (no $CPU_ABI binaries): $TEST_NAME" 831 return 0 832 fi 833 # First, copy all files to the device, except for gdbserver, gdb.setup, and 834 # those declared in $TEST/BROKEN_RUN 835 adb_shell_mkdir "$DEVICE" $DSTDIR 836 837 if [ "$ABI" = "$(find_ndk_unknown_archs)" ]; then # on-the-fly on-device compilation 838 run $ADB_CMD -s "$DEVICE" shell rm -rf $DSTDIR/abcc_tmp 839 adb_shell_mkdir "$DEVICE" $DSTDIR/abcc_tmp 840 run $ADB_CMD -s "$DEVICE" shell chmod 0777 $DSTDIR/abcc_tmp 841 for SRCFILE in `ls $SRCDIR`; do 842 run $ADB_CMD -s "$DEVICE" push "$SRCDIR/$SRCFILE" $DSTDIR/abcc_tmp 843 run $ADB_CMD -s "$DEVICE" shell chmod 0644 $DSTDIR/abcc_tmp/$SRCFILE 844 done 845 compile_on_the_fly $DSTDIR/abcc_tmp 846 if [ $? -ne 0 ]; then 847 test "$CONTINUE_ON_BUILD_FAIL" != "yes" && exit 1 848 return 1 849 fi 850 run rm -f $SRCDIR/* 851 run $ADB_CMD -s "$DEVICE" pull $DSTDIR/abcc_tmp $SRCDIR 852 run rm -f $SRCDIR/compile_result 853 run rm -f $SRCDIR/compile_error 854 run rm -f $SRCDIR/*$(get_lib_suffix_for_abi $ABI) 855 run $ADB_CMD -s "$DEVICE" shell rm -rf $DSTDIR/abcc_tmp 856 fi 857 858 for SRCFILE in `ls $SRCDIR`; do 859 DSTFILE=`basename $SRCFILE` 860 echo "$DSTFILE" | grep -q -e '\.so$' 861 if [ $? != 0 ] ; then 862 continue 863 fi 864 SRCPATH="$SRCDIR/$SRCFILE" 865 if [ $HOST_OS = cygwin ]; then 866 SRCPATH=`cygpath -m $SRCPATH` 867 fi 868 DSTPATH="$DSTDIR/$DSTFILE" 869 run $ADB_CMD -s "$DEVICE" push "$SRCPATH" "$DSTPATH" && 870 run $ADB_CMD -s "$DEVICE" shell chmod 0755 $DSTPATH 871 if [ $? != 0 ] ; then 872 dump "ERROR: Could not install $SRCPATH to device $DEVICE!" 873 exit 1 874 fi 875 done 876 877 for SRCFILE in `ls $SRCDIR`; do 878 DSTFILE=`basename $SRCFILE` 879 if [ "$DSTFILE" = "gdbserver" -o "$DSTFILE" = "gdb.setup" ] ; then 880 continue 881 fi 882 echo "$DSTFILE" | grep -q -e '\.so$' 883 if [ $? = 0 ] ; then 884 continue 885 fi 886 if [ -z "$RUN_TESTS" -o "$RUN_TESTS_FILTERED" = "yes" ]; then 887 if [ -f "$TEST/BROKEN_RUN" ]; then 888 grep -q -w -e "$DSTFILE" "$TEST/BROKEN_RUN" 889 if [ $? = 0 ] ; then 890 continue 891 fi 892 fi 893 fi 894 SRCPATH="$SRCDIR/$SRCFILE" 895 if [ $HOST_OS = cygwin ]; then 896 SRCPATH=`cygpath -m $SRCPATH` 897 fi 898 DSTPATH="$DSTDIR/$DSTFILE" 899 run $ADB_CMD -s "$DEVICE" push "$SRCPATH" "$DSTPATH" && 900 run $ADB_CMD -s "$DEVICE" shell chmod 0755 $DSTPATH 901 DATAPATHS= 902 if [ -f "$TEST/DATA" ]; then 903 if grep -q -e "$DSTFILE" "$TEST/DATA"; then 904 DATAPATHS=`grep -e "$DSTFILE" "$TEST/DATA" | awk '{print $2}'` 905 DATAPATHS=$NDK/$DATAPATHS 906 for DATA in $(ls $DATAPATHS); do 907 run $ADB_CMD -s "$DEVICE" push "$DATA" "$DSTDIR" 908 done 909 fi 910 fi 911 if [ $? != 0 ] ; then 912 dump "ERROR: Could not install $SRCPATH to device $DEVICE!" 913 exit 1 914 fi 915 PROGRAM="`basename $DSTPATH`" 916 dump "Running device test [$CPU_ABI]: $TEST_NAME (`basename $PROGRAM`)" 917 adb_var_shell_cmd "$DEVICE" "" "cd $DSTDIR && LD_LIBRARY_PATH=$DSTDIR ./$PROGRAM" 918 if [ $? != 0 ] ; then 919 dump " ---> TEST FAILED!!" 920 fi 921 adb_var_shell_cmd "$DEVICE" "" "rm -f $DSTPATH" 922 if [ -n "$DATAPATHS" ]; then 923 for DATA in $(ls $DATAPATHS); do 924 adb_var_shell_cmd "$DEVICE" "" "rm -f $DSTDIR/`basename $DATA`" 925 done 926 fi 927 done 928 # Cleanup 929 adb_var_shell_cmd "$DEVICE" "" rm -r $DSTDIR 930 } 931 932 for DIR in `ls -d $ROOTDIR/tests/device/*`; do 933 if is_buildable $DIR; then 934 build_device_test $DIR 935 fi 936 done 937 938 # Do we have adb and any device connected here? 939 # If not, we can't run our tests. 940 # 941 SKIP_TESTS=no 942 if [ -z "$ADB_CMD" ] ; then 943 dump "WARNING: No 'adb' in your path!" 944 SKIP_TESTS=yes 945 else 946 # Get list of online devices, turn ' ' in device into '#' 947 ADB_DEVICES=`$ADB_CMD devices | grep -v offline | awk 'NR>1 {gsub(/[ \t]+device$/,""); print;}' | sed '/^$/d' | sort | tr ' ' '#'` 948 ADB_DEVICES=$(echo $ADB_DEVICES | tr '\n' ' ') 949 log2 "ADB online devices (sorted): $ADB_DEVICES" 950 ADB_DEVCOUNT=`echo "$ADB_DEVICES" | wc -w` 951 if [ "$ADB_DEVCOUNT" = "0" ]; then 952 dump "WARNING: No device connected to adb!" 953 SKIP_TESTS=yes 954 else 955 ADB_DEVICES="$ADB_DEVICES " 956 if [ -n "$ANDROID_SERIAL" ] ; then 957 # Expect ANDROID_SERIAL is comma-delimited of one or more devices 958 ANDROID_SERIAL=$(echo "$ANDROID_SERIAL" | tr ' ' '#') # turn ' ' into '#' 959 ANDROID_SERIAL=$(commas_to_spaces $ANDROID_SERIAL) 960 for SERIAL in $ANDROID_SERIAL; do 961 if [ "$ADB_DEVICES" = "${ADB_DEVICES%$SERIAL *}" ] ; then 962 dump "WARNING: Device $SERIAL cannot be found or offline!" 963 SKIP_TESTS=yes 964 fi 965 done 966 if [ "$SKIP_TESTS" != "yes" ] ; then 967 ADB_DEVICES="$ANDROID_SERIAL" 968 fi 969 fi 970 fi 971 fi 972 if [ "$SKIP_TESTS" = "yes" ] ; then 973 dump "SKIPPING RUNNING TESTS ON DEVICE!" 974 else 975 AT_LEAST_CPU_ABI_MATCH= 976 for DEVICE in $ADB_DEVICES; do 977 # undo earlier ' '-to-'#' translation 978 DEVICE=$(echo "$DEVICE" | tr '#' ' ') 979 # get device CPU_ABI and CPU_ABI2, each may contain list of abi, comma-delimited. 980 adb_var_shell_cmd "$DEVICE" CPU_ABI1 getprop ro.product.cpu.abi 981 adb_var_shell_cmd "$DEVICE" CPU_ABI2 getprop ro.product.cpu.abi2 982 CPU_ABIS="$CPU_ABI1,$CPU_ABI2" 983 CPU_ABIS=$(commas_to_spaces $CPU_ABIS) 984 if [ -n "$_NDK_TESTING_ALL_" ]; then 985 if [ "$CPU_ABI1" = "armeabi-v7a" -o "$CPU_ABI2" = "armeabi-v7a" ]; then 986 CPU_ABIS="$CPU_ABIS armeabi-v7a-hard" 987 fi 988 fi 989 if [ "$CPU_ABIS" = " " ]; then 990 # Very old cupcake-based Android devices don't have these properties 991 # defined. Fortunately, they are all armeabi-based. 992 CPU_ABIS=armeabi 993 fi 994 log "CPU_ABIS=$CPU_ABIS" 995 for CPU_ABI in $CPU_ABIS; do 996 if [ "$ABI" = "default" -o "$ABI" = "$CPU_ABI" -o "$ABI" = "$(find_ndk_unknown_archs)" ] ; then 997 AT_LEAST_CPU_ABI_MATCH="yes" 998 for DIR in `ls -d $ROOTDIR/tests/device/*`; do 999 if is_buildable $DIR; then 1000 log "Running device test on $DEVICE [$CPU_ABI]: $DIR" 1001 run_device_test "$DEVICE" "$CPU_ABI" "$DIR" /data/local/tmp 1002 fi 1003 done 1004 fi 1005 done 1006 done 1007 if [ "$AT_LEAST_CPU_ABI_MATCH" != "yes" ] ; then 1008 dump "WARNING: No device matches ABI $ABI! SKIPPING RUNNING TESTS ON DEVICE!" 1009 fi 1010 fi 1011fi 1012 1013dump "Cleaning up..." 1014if [ "$ABI" = "$(find_ndk_unknown_archs)" ]; then 1015 # Cleanup some intermediate files for testing 1016 run rm -rf $NDK/$GNUSTL_SUBDIR/$GCC_TOOLCHAIN_VERSION/libs/$ABI 1017 run rm -rf $NDK/$GABIXX_SUBDIR/libs/$ABI 1018 run rm -rf $NDK/$LIBPORTABLE_SUBDIR/libs/$ABI 1019fi 1020rm -rf $BUILD_DIR 1021dump "Done." 1022