• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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