blob: 7963a35cdd09ab3357562b7ff900e1dde4d643da [file] [log] [blame]
#!/bin/sh
# //===--------------------------- testit ---------------------------------===//
# //
# // The LLVM Compiler Infrastructure
# //
# // This file is distributed under the University of Illinois Open Source
# // License. See LICENSE.TXT for details.
# //
# //===--------------------------------------------------------------------===//
currentpath=`pwd`
origpath=$currentpath
currentdir=`basename $currentpath`
while [ $currentdir != "test" ]; do
if [ $currentdir = "/" ]
then
echo "current directory must be in or under \"test\"."
exit 1
fi
cd ..
currentpath=`pwd`
currentdir=`basename $currentpath`
done
cd ..
LIBCXX_ROOT=`pwd`
cd $origpath
ANDROID_SUPPORT=$(cd "$LIBCXX_ROOT"/../../../android/support && pwd)
VERBOSE=1
run () {
if [ "$VERBOSE" -gt 1 ]; then
echo "COMMAND: $@"
fi
case $VERBOSE in
0|1)
# Hide command output and errors.
"$@" >/dev/null 2>&1
;;
2)
# Only hide command output
"$@" >/dev/null
;;
*)
# Show command output and errors.
"$@"
;;
esac
}
run2 () {
if [ "$VERBOSE" -gt 2 ]; then
echo "COMMAND: $@"
fi
case $VERBOSE in
0|1)
# Hide command output and errors.
"$@" >/dev/null 2>&1
;;
2)
# Only hide command output
"$@" >/dev/null
;;
*)
# Show command output and errors.
"$@"
;;
esac
}
# The list of valid target abis supported by this script.
VALID_ABIS="armeabi armeabi-v7a x86 mips"
DO_HELP=
DO_STATIC=
TARGET_ABI=
TARGET_ARCH=
CXX=
for OPT; do
case $OPT in
--help|-?)
DO_HELP=true
;;
--abi=*)
TARGET_ABI=${OPT##--abi=}
;;
--static)
DO_STATIC=true
;;
--cxx=*)
CXX=${OPT##--cxx=}
;;
--verbose)
VERBOSE=$(( $VERBOSE + 1 ))
;;
-*)
echo "Unknown option: $OPT. See --help."
exit 1
;;
*)
echo "This script doesn't take parameters. See --help."
exit 1
;;
esac
done
if [ "$DO_HELP" ]; then
echo \
"Usage: $(basename $0) [options]
This script is used to run the libc++ test suite for Android.
You will need the following things:
- The prebuild libc++ libraries in your NDK install.
- A prebuilt Android toolchain in your path.
- The 'adb' tool in your path.
- An Android device connected to ADB.
The toolchain and device must match your target ABI. For example, if
you use --abi=armeabi-v7a, your device must run ARMv7-A Android binaries,
and arm-linux-androideabi-g++ will be used to compile all tests, unless
you use --cxx=<command> to override it.
Valid options:
--help|-? Display this message.
--abi=<name> Specify target ABI. Use --abi=list for list.
--static Link against static libc++ library.
--cxx=<program> Override C++ compiler/linker.
--verbose Increase verbosity.
"
exit 0
fi
# Check target ABI.
if [ "$TARGET_ABI" = "list" ]; then
echo "List of valid target ABIs:"
for ABI in $VALID_ABIS; do
printf " %s" $ABI
done
printf "\n"
exit 0
fi
if [ -z "$TARGET_ABI" ]; then
echo "ERROR: Please specify a target ABI (--abi=<name>)."
exit 1
fi
FOUND_ABI=
for ABI in $VALID_ABIS; do
if [ "$ABI" = "$TARGET_ABI" ]; then
FOUND_ABI=true
break
fi
done
if [ -z "$FOUND_ABI" ]; then
echo "ERROR: Invalid abi '$TARGET_ABI'. Must be one of: $VALID_ABIS"
exit 1
fi
LIBCXX_LIBS=$(cd $LIBCXX_ROOT/.. && pwd)/libs/$TARGET_ABI
for LIB in libc++_static.a libc++_shared.so; do
if [ ! -f "$LIBCXX_LIBS/$LIB" ]; then
echo "ERROR: Missing prebuilt library: $LIBCXX_LIBS/$LIB"
echo "Please run: build/tools/build-cxx-stl.sh --stl=libc++"
exit 1
fi
done
# Check or detect C++ toolchain.
TOOLCHAIN_CFLAGS=
TOOLCHAIN_LDFLAGS=
if [ -z "$TOOLCHAIN_PREFIX" ]; then
# Compute
case $TARGET_ABI in
armeabi)
TOOLCHAIN_PREFIX=arm-linux-androideabi
;;
armeabi-v7a)
TOOLCHAIN_PREFIX=arm-linux-androideabi
TOOLCHAIN_CFLAGS="-march=armv7-a -mfpu=vfpv3-d16"
TOOLCHAIN_LDFLAGS="-march=armv7-a -Wl,--fix-cortex-a8"
;;
x86)
TOOLCHAIN_PREFIX=i686-linux-android
;;
mips)
TOOLCHAIN_PREFIX=mipsel-linux-android
;;
*)
echo "ERROR: Unknown ABI '$ABI'"
exit 1
;;
esac
CXX=$TOOLCHAIN_PREFIX-g++
fi
REAL_CXX=$(which "$CXX" 2>/dev/null)
if [ -z "$REAL_CXX" ]; then
echo "ERROR: Missing C++ compiler: $CXX"
exit 1
fi
CC=$CXX
if [ -z "$OPTIONS" ]
then
OPTIONS="-std=c++11"
fi
OPTIONS="$OPTIONS -I$LIBCXX_ROOT/test/support"
if [ -z "$HEADER_INCLUDE" ]
then
HEADER_INCLUDE="-I$LIBCXX_ROOT/include -I$ANDROID_SUPPORT/include"
fi
if [ -z "$SOURCE_LIB" ]
then
SOURCE_LIB="-L$LIBCXX_LIBS"
fi
if [ -z "$ADB" ]
then
ADB=adb
fi
if [ "$DO_STATIC" ]; then
# Statically link to ensure the executable can be run easily through ADB
LIBS=-lc++_static
else
run2 $ADB push $LIBCXX_LIBS/libc++_shared.so /data/local/tmp 2>/dev/null
if [ $? != 0 ]; then
echo "ERROR: Can't push shared libc++ to target device!"
exit 1
fi
LIBS=-lc++_shared
fi
case $TRIPLE in
*-*-mingw* | *-*-cygwin* | *-*-win*)
TEST_EXE=test.exe
;;
*)
TEST_EXE=a.out
;;
esac
TEST_EXE=/tmp/testit_android-$USER-$$-$TEST_EXE
FAIL=0
PASS=0
UNIMPLEMENTED=0
IMPLEMENTED_FAIL=0
IMPLEMENTED_PASS=0
# Run a shell command through ADB, return its status.
adb_shell () {
# We need a temporary file to store the output of our command
local CMD_OUT RET OUTPUT
CMD_OUT=$(mktemp /tmp/testit_android-cmdout-XXXXXX)
# Run the command, while storing the standard output to CMD_OUT
# and appending the exit code as the last line.
if [ "$VERBOSE" -gt 2 ]; then
echo "COMMAND: $ADB shell $@"
fi
$ADB shell "$@ ; echo \$?" | sed -e 's![[:cntrl:]]!!g' > $CMD_OUT 2>&1
# Get last line in log, which contains the exit code from the command
RET=$(sed -e '$!d' $CMD_OUT)
# Get output, which corresponds to everything except the last line
OUT=$(sed -e '$d' $CMD_OUT)
rm -f $CMD_OUT
if [ "$VERBOSE" -gt 2 ]; then
printf "%s" "$OUT"
fi
return $RET
}
# Run a given executable through ADB.
# $1: Executable path
# $2+: arguments.
adb_run () {
local EXECUTABLE EXECUTABLE_BASENAME TARGET_PATH
EXECUTABLE=$1
EXECUTABLE_BASENAME=$(basename "$EXECUTABLE")
shift
TARGET_PATH=/data/local/tmp
run2 $ADB push $EXECUTABLE $TARGET_PATH/$EXECUTABLE_BASENAME 2>/dev/null &&
adb_shell "LD_LIBRARY_PATH=$TARGET_PATH; cd $TARGET_PATH; ./$EXECUTABLE_BASENAME"
}
afunc() {
fail=0
pass=0
if (ls *.fail.cpp > /dev/null 2>&1)
then
for FILE in $(ls *.fail.cpp); do
if run $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o $TEST_EXE > /dev/null 2>&1
then
rm $TEST_EXE
echo "$FILE should not compile"
fail=$(($fail+1))
else
pass=$(($pass+1))
fi
done
fi
if (ls *.pass.cpp > /dev/null 2>&1)
then
for FILE in $(ls *.pass.cpp); do
if [ "$VERBOSE" -gt 1 ]; then
echo "Running test: " $FILE
fi
if run $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o $TEST_EXE
then
if adb_run $TEST_EXE
then
rm $TEST_EXE
pass=$(($pass+1))
else
echo "`pwd`/$FILE failed at run time"
echo "Compile line was:" $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS
fail=$(($fail+1))
rm $TEST_EXE
fi
else
echo "`pwd`/$FILE failed to compile"
echo "Compile line was:" $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS
fail=$(($fail+1))
fi
done
fi
if [ $fail -gt 0 ]
then
echo "failed $fail tests in `pwd`"
IMPLEMENTED_FAIL=$(($IMPLEMENTED_FAIL+1))
fi
if [ $pass -gt 0 ]
then
echo "passed $pass tests in `pwd`"
if [ $fail -eq 0 ]
then
IMPLEMENTED_PASS=$((IMPLEMENTED_PASS+1))
fi
fi
if [ $fail -eq 0 -a $pass -eq 0 ]
then
echo "not implemented: `pwd`"
UNIMPLEMENTED=$(($UNIMPLEMENTED+1))
fi
FAIL=$(($FAIL+$fail))
PASS=$(($PASS+$pass))
for FILE in *
do
if [ -d "$FILE" ];
then
cd $FILE
afunc
cd ..
fi
done
}
afunc
echo "****************************************************"
echo "Results for `pwd`:"
echo "using `$CC --version`"
echo "with $OPTIONS $HEADER_INCLUDE $SOURCE_LIB"
echo "----------------------------------------------------"
echo "sections without tests : $UNIMPLEMENTED"
echo "sections with failures : $IMPLEMENTED_FAIL"
echo "sections without failures: $IMPLEMENTED_PASS"
echo " + ----"
echo "total number of sections : $(($UNIMPLEMENTED+$IMPLEMENTED_FAIL+$IMPLEMENTED_PASS))"
echo "----------------------------------------------------"
echo "number of tests failed : $FAIL"
echo "number of tests passed : $PASS"
echo " + ----"
echo "total number of tests : $(($FAIL+$PASS))"
echo "****************************************************"
exit $FAIL