1#!/bin/sh 2# //===--------------------------- testit ---------------------------------===// 3# // 4# // The LLVM Compiler Infrastructure 5# // 6# // This file is distributed under the University of Illinois Open Source 7# // License. See LICENSE.TXT for details. 8# // 9# //===--------------------------------------------------------------------===// 10 11currentpath=`pwd` 12origpath=$currentpath 13currentdir=`basename $currentpath` 14while [ $currentdir != "test" ]; do 15 if [ $currentdir = "/" ] 16 then 17 echo "current directory must be in or under \"test\"." 18 exit 1 19 fi 20 cd .. 21 currentpath=`pwd` 22 currentdir=`basename $currentpath` 23done 24 25cd .. 26LIBCXX_ROOT=`pwd` 27cd $origpath 28 29ANDROID_SUPPORT=$(cd "$LIBCXX_ROOT"/../../../android/support && pwd) 30 31VERBOSE=1 32 33run () { 34 if [ "$VERBOSE" -gt 1 ]; then 35 echo "COMMAND: $@" 36 fi 37 case $VERBOSE in 38 0|1) 39 # Hide command output and errors. 40 "$@" >/dev/null 2>&1 41 ;; 42 2) 43 # Only hide command output 44 "$@" >/dev/null 45 ;; 46 *) 47 # Show command output and errors. 48 "$@" 49 ;; 50 esac 51} 52 53run2 () { 54 if [ "$VERBOSE" -gt 2 ]; then 55 echo "COMMAND: $@" 56 fi 57 case $VERBOSE in 58 0|1) 59 # Hide command output and errors. 60 "$@" >/dev/null 2>&1 61 ;; 62 2) 63 # Only hide command output 64 "$@" >/dev/null 65 ;; 66 *) 67 # Show command output and errors. 68 "$@" 69 ;; 70 esac 71} 72 73# The list of valid target abis supported by this script. 74VALID_ABIS="armeabi armeabi-v7a x86 mips" 75 76DO_HELP= 77DO_STATIC= 78TARGET_ABI= 79TARGET_ARCH= 80CXX= 81for OPT; do 82 case $OPT in 83 --help|-?) 84 DO_HELP=true 85 ;; 86 --abi=*) 87 TARGET_ABI=${OPT##--abi=} 88 ;; 89 --static) 90 DO_STATIC=true 91 ;; 92 --cxx=*) 93 CXX=${OPT##--cxx=} 94 ;; 95 --verbose) 96 VERBOSE=$(( $VERBOSE + 1 )) 97 ;; 98 -*) 99 echo "Unknown option: $OPT. See --help." 100 exit 1 101 ;; 102 *) 103 echo "This script doesn't take parameters. See --help." 104 exit 1 105 ;; 106 esac 107done 108 109if [ "$DO_HELP" ]; then 110 echo \ 111"Usage: $(basename $0) [options] 112 113This script is used to run the libc++ test suite for Android. 114You will need the following things: 115 116 - The prebuild libc++ libraries in your NDK install. 117 - A prebuilt Android toolchain in your path. 118 - The 'adb' tool in your path. 119 - An Android device connected to ADB. 120 121The toolchain and device must match your target ABI. For example, if 122you use --abi=armeabi-v7a, your device must run ARMv7-A Android binaries, 123and arm-linux-androideabi-g++ will be used to compile all tests, unless 124you use --cxx=<command> to override it. 125 126Valid options: 127 --help|-? Display this message. 128 --abi=<name> Specify target ABI. Use --abi=list for list. 129 --static Link against static libc++ library. 130 --cxx=<program> Override C++ compiler/linker. 131 --verbose Increase verbosity. 132" 133 exit 0 134fi 135 136# Check target ABI. 137if [ "$TARGET_ABI" = "list" ]; then 138 echo "List of valid target ABIs:" 139 for ABI in $VALID_ABIS; do 140 printf " %s" $ABI 141 done 142 printf "\n" 143 exit 0 144fi 145 146if [ -z "$TARGET_ABI" ]; then 147 echo "ERROR: Please specify a target ABI (--abi=<name>)." 148 exit 1 149fi 150 151FOUND_ABI= 152for ABI in $VALID_ABIS; do 153 if [ "$ABI" = "$TARGET_ABI" ]; then 154 FOUND_ABI=true 155 break 156 fi 157done 158 159if [ -z "$FOUND_ABI" ]; then 160 echo "ERROR: Invalid abi '$TARGET_ABI'. Must be one of: $VALID_ABIS" 161 exit 1 162fi 163 164LIBCXX_LIBS=$(cd $LIBCXX_ROOT/.. && pwd)/libs/$TARGET_ABI 165for LIB in libc++_static.a libc++_shared.so; do 166 if [ ! -f "$LIBCXX_LIBS/$LIB" ]; then 167 echo "ERROR: Missing prebuilt library: $LIBCXX_LIBS/$LIB" 168 echo "Please run: build/tools/build-cxx-stl.sh --stl=libc++" 169 exit 1 170 fi 171done 172 173# Check or detect C++ toolchain. 174TOOLCHAIN_CFLAGS= 175TOOLCHAIN_LDFLAGS= 176if [ -z "$TOOLCHAIN_PREFIX" ]; then 177 # Compute 178 case $TARGET_ABI in 179 armeabi) 180 TOOLCHAIN_PREFIX=arm-linux-androideabi 181 ;; 182 armeabi-v7a) 183 TOOLCHAIN_PREFIX=arm-linux-androideabi 184 TOOLCHAIN_CFLAGS="-march=armv7-a -mfpu=vfpv3-d16" 185 TOOLCHAIN_LDFLAGS="-march=armv7-a -Wl,--fix-cortex-a8" 186 ;; 187 x86) 188 TOOLCHAIN_PREFIX=i686-linux-android 189 ;; 190 mips) 191 TOOLCHAIN_PREFIX=mipsel-linux-android 192 ;; 193 *) 194 echo "ERROR: Unknown ABI '$ABI'" 195 exit 1 196 ;; 197 esac 198 CXX=$TOOLCHAIN_PREFIX-g++ 199fi 200 201REAL_CXX=$(which "$CXX" 2>/dev/null) 202if [ -z "$REAL_CXX" ]; then 203 echo "ERROR: Missing C++ compiler: $CXX" 204 exit 1 205fi 206CC=$CXX 207 208if [ -z "$OPTIONS" ] 209then 210 OPTIONS="-std=c++11" 211fi 212OPTIONS="$OPTIONS -I$LIBCXX_ROOT/test/support" 213 214if [ -z "$HEADER_INCLUDE" ] 215then 216 HEADER_INCLUDE="-I$LIBCXX_ROOT/include -I$ANDROID_SUPPORT/include" 217fi 218 219if [ -z "$SOURCE_LIB" ] 220then 221 SOURCE_LIB="-L$LIBCXX_LIBS" 222fi 223if [ -z "$ADB" ] 224then 225 ADB=adb 226fi 227 228if [ "$DO_STATIC" ]; then 229 # Statically link to ensure the executable can be run easily through ADB 230 LIBS=-lc++_static 231else 232 run2 $ADB push $LIBCXX_LIBS/libc++_shared.so /data/local/tmp 2>/dev/null 233 if [ $? != 0 ]; then 234 echo "ERROR: Can't push shared libc++ to target device!" 235 exit 1 236 fi 237 LIBS=-lc++_shared 238fi 239 240case $TRIPLE in 241 *-*-mingw* | *-*-cygwin* | *-*-win*) 242 TEST_EXE=test.exe 243 ;; 244 *) 245 TEST_EXE=a.out 246 ;; 247esac 248 249TEST_EXE=/tmp/testit_android-$USER-$$-$TEST_EXE 250 251FAIL=0 252PASS=0 253UNIMPLEMENTED=0 254IMPLEMENTED_FAIL=0 255IMPLEMENTED_PASS=0 256 257# Run a shell command through ADB, return its status. 258adb_shell () { 259 # We need a temporary file to store the output of our command 260 local CMD_OUT RET OUTPUT 261 CMD_OUT=$(mktemp /tmp/testit_android-cmdout-XXXXXX) 262 # Run the command, while storing the standard output to CMD_OUT 263 # and appending the exit code as the last line. 264 if [ "$VERBOSE" -gt 2 ]; then 265 echo "COMMAND: $ADB shell $@" 266 fi 267 $ADB shell "$@ ; echo \$?" | sed -e 's![[:cntrl:]]!!g' > $CMD_OUT 2>&1 268 # Get last line in log, which contains the exit code from the command 269 RET=$(sed -e '$!d' $CMD_OUT) 270 # Get output, which corresponds to everything except the last line 271 OUT=$(sed -e '$d' $CMD_OUT) 272 rm -f $CMD_OUT 273 if [ "$VERBOSE" -gt 2 ]; then 274 printf "%s" "$OUT" 275 fi 276 return $RET 277} 278 279# Run a given executable through ADB. 280# $1: Executable path 281# $2+: arguments. 282adb_run () { 283 local EXECUTABLE EXECUTABLE_BASENAME TARGET_PATH 284 EXECUTABLE=$1 285 EXECUTABLE_BASENAME=$(basename "$EXECUTABLE") 286 shift 287 TARGET_PATH=/data/local/tmp 288 run2 $ADB push $EXECUTABLE $TARGET_PATH/$EXECUTABLE_BASENAME 2>/dev/null && 289 adb_shell "LD_LIBRARY_PATH=$TARGET_PATH; cd $TARGET_PATH; ./$EXECUTABLE_BASENAME" 290} 291 292afunc() { 293 fail=0 294 pass=0 295 if (ls *.fail.cpp > /dev/null 2>&1) 296 then 297 for FILE in $(ls *.fail.cpp); do 298 if run $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o $TEST_EXE > /dev/null 2>&1 299 then 300 rm $TEST_EXE 301 echo "$FILE should not compile" 302 fail=$(($fail+1)) 303 else 304 pass=$(($pass+1)) 305 fi 306 done 307 fi 308 309 if (ls *.pass.cpp > /dev/null 2>&1) 310 then 311 for FILE in $(ls *.pass.cpp); do 312 if [ "$VERBOSE" -gt 1 ]; then 313 echo "Running test: " $FILE 314 fi 315 if run $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o $TEST_EXE 316 then 317 if adb_run $TEST_EXE 318 then 319 rm $TEST_EXE 320 pass=$(($pass+1)) 321 else 322 echo "`pwd`/$FILE failed at run time" 323 echo "Compile line was:" $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS 324 fail=$(($fail+1)) 325 rm $TEST_EXE 326 fi 327 else 328 echo "`pwd`/$FILE failed to compile" 329 echo "Compile line was:" $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS 330 fail=$(($fail+1)) 331 fi 332 done 333 fi 334 335 if [ $fail -gt 0 ] 336 then 337 echo "failed $fail tests in `pwd`" 338 IMPLEMENTED_FAIL=$(($IMPLEMENTED_FAIL+1)) 339 fi 340 if [ $pass -gt 0 ] 341 then 342 echo "passed $pass tests in `pwd`" 343 if [ $fail -eq 0 ] 344 then 345 IMPLEMENTED_PASS=$((IMPLEMENTED_PASS+1)) 346 fi 347 fi 348 if [ $fail -eq 0 -a $pass -eq 0 ] 349 then 350 echo "not implemented: `pwd`" 351 UNIMPLEMENTED=$(($UNIMPLEMENTED+1)) 352 fi 353 354 FAIL=$(($FAIL+$fail)) 355 PASS=$(($PASS+$pass)) 356 357 for FILE in * 358 do 359 if [ -d "$FILE" ]; 360 then 361 cd $FILE 362 afunc 363 cd .. 364 fi 365 done 366} 367 368afunc 369 370echo "****************************************************" 371echo "Results for `pwd`:" 372echo "using `$CC --version`" 373echo "with $OPTIONS $HEADER_INCLUDE $SOURCE_LIB" 374echo "----------------------------------------------------" 375echo "sections without tests : $UNIMPLEMENTED" 376echo "sections with failures : $IMPLEMENTED_FAIL" 377echo "sections without failures: $IMPLEMENTED_PASS" 378echo " + ----" 379echo "total number of sections : $(($UNIMPLEMENTED+$IMPLEMENTED_FAIL+$IMPLEMENTED_PASS))" 380echo "----------------------------------------------------" 381echo "number of tests failed : $FAIL" 382echo "number of tests passed : $PASS" 383echo " + ----" 384echo "total number of tests : $(($FAIL+$PASS))" 385echo "****************************************************" 386 387exit $FAIL 388