testit_android revision ad46d2248426e810edc5878c7cb086b7093f3cf5
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
223
224if [ "$DO_STATIC" ]; then
225  # Statically link to ensure the executable can be run easily through ADB
226  LIBS=-lc++_static
227else
228  run2 adb push $LIBCXX_LIBS/libc++_shared.so /data/local/tmp 2>/dev/null
229  if [ $? != 0 ]; then
230    echo "ERROR: Can't push shared libc++ to target device!"
231    exit 1
232  fi
233  LIBS=-lc++_shared
234fi
235
236case $TRIPLE in
237  *-*-mingw* | *-*-cygwin* | *-*-win*)
238    TEST_EXE=test.exe
239    ;;
240  *)
241    TEST_EXE=a.out
242    ;;
243esac
244
245TEST_EXE=/tmp/testit_android-$USER-$$-$TEST_EXE
246
247FAIL=0
248PASS=0
249UNIMPLEMENTED=0
250IMPLEMENTED_FAIL=0
251IMPLEMENTED_PASS=0
252
253# Run a shell command through ADB, return its status.
254adb_shell () {
255  # We need a temporary file to store the output of our command
256  local CMD_OUT RET OUTPUT
257  CMD_OUT=$(mktemp /tmp/testit_android-cmdout-XXXXXX)
258  # Run the command, while storing the standard output to CMD_OUT
259  # and appending the exit code as the last line.
260  if [ "$VERBOSE" -gt 2 ]; then
261    echo "COMMAND: adb shell $@"
262  fi
263  adb shell "$@ ; echo \$?" | sed -e 's![[:cntrl:]]!!g' > $CMD_OUT 2>&1
264  # Get last line in log, which contains the exit code from the command
265  RET=$(sed -e '$!d' $CMD_OUT)
266  # Get output, which corresponds to everything except the last line
267  OUT=$(sed -e '$d' $CMD_OUT)
268  rm -f $CMD_OUT
269  if [ "$VERBOSE" -gt 2 ]; then
270    printf "%s" "$OUT"
271  fi
272  return $RET
273}
274
275# Run a given executable through ADB.
276# $1: Executable path
277# $2+: arguments.
278adb_run () {
279  local EXECUTABLE EXECUTABLE_BASENAME TARGET_PATH
280  EXECUTABLE=$1
281  EXECUTABLE_BASENAME=$(basename "$EXECUTABLE")
282  shift
283  TARGET_PATH=/data/local/tmp
284  run2 adb push $EXECUTABLE $TARGET_PATH/$EXECUTABLE_BASENAME 2>/dev/null &&
285  adb_shell "LD_LIBRARY_PATH=$TARGET_PATH; cd $TARGET_PATH; ./$EXECUTABLE_BASENAME"
286}
287
288afunc() {
289	fail=0
290	pass=0
291	if (ls *.fail.cpp > /dev/null 2>&1)
292	then
293		for FILE in $(ls *.fail.cpp); do
294			if run $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o $TEST_EXE > /dev/null 2>&1
295			then
296				rm $TEST_EXE
297				echo "$FILE should not compile"
298				fail=$(($fail+1))
299			else
300				pass=$(($pass+1))
301			fi
302		done
303	fi
304
305	if (ls *.pass.cpp > /dev/null 2>&1)
306	then
307		for FILE in $(ls *.pass.cpp); do
308                      if [ "$VERBOSE" -gt 1 ]; then
309                          echo "Running test: " $FILE
310                      fi
311			if run $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o $TEST_EXE
312			then
313				if adb_run $TEST_EXE
314				then
315					rm $TEST_EXE
316					pass=$(($pass+1))
317				else
318					echo "`pwd`/$FILE failed at run time"
319					echo "Compile line was:" $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS
320					fail=$(($fail+1))
321					rm $TEST_EXE
322				fi
323			else
324				echo "`pwd`/$FILE failed to compile"
325				echo "Compile line was:" $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS
326				fail=$(($fail+1))
327			fi
328		done
329	fi
330
331	if [ $fail -gt 0 ]
332	then
333		echo "failed $fail tests in `pwd`"
334		IMPLEMENTED_FAIL=$(($IMPLEMENTED_FAIL+1))
335	fi
336	if [ $pass -gt 0 ]
337	then
338		echo "passed $pass tests in `pwd`"
339		if [ $fail -eq 0 ]
340		then
341			IMPLEMENTED_PASS=$((IMPLEMENTED_PASS+1))
342		fi
343	fi
344	if [ $fail -eq 0 -a $pass -eq 0 ]
345	then
346		echo "not implemented:  `pwd`"
347		UNIMPLEMENTED=$(($UNIMPLEMENTED+1))
348	fi
349
350	FAIL=$(($FAIL+$fail))
351	PASS=$(($PASS+$pass))
352
353	for FILE in *
354	do
355		if [ -d "$FILE" ];
356		then
357			cd $FILE
358			afunc
359			cd ..
360		fi
361	done
362}
363
364afunc
365
366echo "****************************************************"
367echo "Results for `pwd`:"
368echo "using `$CC --version`"
369echo "with $OPTIONS $HEADER_INCLUDE $SOURCE_LIB"
370echo "----------------------------------------------------"
371echo "sections without tests   : $UNIMPLEMENTED"
372echo "sections with failures   : $IMPLEMENTED_FAIL"
373echo "sections without failures: $IMPLEMENTED_PASS"
374echo "                       +   ----"
375echo "total number of sections : $(($UNIMPLEMENTED+$IMPLEMENTED_FAIL+$IMPLEMENTED_PASS))"
376echo "----------------------------------------------------"
377echo "number of tests failed   : $FAIL"
378echo "number of tests passed   : $PASS"
379echo "                       +   ----"
380echo "total number of tests    : $(($FAIL+$PASS))"
381echo "****************************************************"
382
383exit $FAIL
384