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 11 currentpath=`pwd` 12 origpath=$currentpath 13 currentdir=`basename $currentpath` 14 while [ $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` 23 done 24 25 cd .. 26 LIBCXX_ROOT=`pwd` 27 cd $origpath 28 29 ANDROID_SUPPORT=$(cd "$LIBCXX_ROOT"/../../../android/support && pwd) 30 31 VERBOSE=1 32 33 run () { 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 53 run2 () { 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. 74 VALID_ABIS="armeabi armeabi-v7a x86 mips" 75 76 DO_HELP= 77 DO_STATIC= 78 TARGET_ABI= 79 TARGET_ARCH= 80 CXX= 81 for 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 107 done 108 109 if [ "$DO_HELP" ]; then 110 echo \ 111 "Usage: $(basename $0) [options] 112 113 This script is used to run the libc++ test suite for Android. 114 You 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 121 The toolchain and device must match your target ABI. For example, if 122 you use --abi=armeabi-v7a, your device must run ARMv7-A Android binaries, 123 and arm-linux-androideabi-g++ will be used to compile all tests, unless 124 you use --cxx=<command> to override it. 125 126 Valid 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 134 fi 135 136 # Check target ABI. 137 if [ "$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 144 fi 145 146 if [ -z "$TARGET_ABI" ]; then 147 echo "ERROR: Please specify a target ABI (--abi=<name>)." 148 exit 1 149 fi 150 151 FOUND_ABI= 152 for ABI in $VALID_ABIS; do 153 if [ "$ABI" = "$TARGET_ABI" ]; then 154 FOUND_ABI=true 155 break 156 fi 157 done 158 159 if [ -z "$FOUND_ABI" ]; then 160 echo "ERROR: Invalid abi '$TARGET_ABI'. Must be one of: $VALID_ABIS" 161 exit 1 162 fi 163 164 LIBCXX_LIBS=$(cd $LIBCXX_ROOT/.. && pwd)/libs/$TARGET_ABI 165 for 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 171 done 172 173 # Check or detect C++ toolchain. 174 TOOLCHAIN_CFLAGS= 175 TOOLCHAIN_LDFLAGS= 176 if [ -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++ 199 fi 200 201 REAL_CXX=$(which "$CXX" 2>/dev/null) 202 if [ -z "$REAL_CXX" ]; then 203 echo "ERROR: Missing C++ compiler: $CXX" 204 exit 1 205 fi 206 CC=$CXX 207 208 if [ -z "$OPTIONS" ] 209 then 210 OPTIONS="-std=c++11" 211 fi 212 OPTIONS="$OPTIONS -I$LIBCXX_ROOT/test/support" 213 214 if [ -z "$HEADER_INCLUDE" ] 215 then 216 HEADER_INCLUDE="-I$LIBCXX_ROOT/include -I$ANDROID_SUPPORT/include" 217 fi 218 219 if [ -z "$SOURCE_LIB" ] 220 then 221 SOURCE_LIB="-L$LIBCXX_LIBS" 222 fi 223 if [ -z "$ADB" ] 224 then 225 ADB=adb 226 fi 227 228 if [ "$DO_STATIC" ]; then 229 # Statically link to ensure the executable can be run easily through ADB 230 LIBS=-lc++_static 231 else 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 238 fi 239 240 case $TRIPLE in 241 *-*-mingw* | *-*-cygwin* | *-*-win*) 242 TEST_EXE=test.exe 243 ;; 244 *) 245 TEST_EXE=a.out 246 ;; 247 esac 248 249 TEST_EXE=/tmp/testit_android-$USER-$$-$TEST_EXE 250 251 FAIL=0 252 PASS=0 253 UNIMPLEMENTED=0 254 IMPLEMENTED_FAIL=0 255 IMPLEMENTED_PASS=0 256 257 # Run a shell command through ADB, return its status. 258 adb_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. 282 adb_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 292 afunc() { 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 368 afunc 369 370 echo "****************************************************" 371 echo "Results for `pwd`:" 372 echo "using `$CC --version`" 373 echo "with $OPTIONS $HEADER_INCLUDE $SOURCE_LIB" 374 echo "----------------------------------------------------" 375 echo "sections without tests : $UNIMPLEMENTED" 376 echo "sections with failures : $IMPLEMENTED_FAIL" 377 echo "sections without failures: $IMPLEMENTED_PASS" 378 echo " + ----" 379 echo "total number of sections : $(($UNIMPLEMENTED+$IMPLEMENTED_FAIL+$IMPLEMENTED_PASS))" 380 echo "----------------------------------------------------" 381 echo "number of tests failed : $FAIL" 382 echo "number of tests passed : $PASS" 383 echo " + ----" 384 echo "total number of tests : $(($FAIL+$PASS))" 385 echo "****************************************************" 386 387 exit $FAIL 388