257 lines
9.1 KiB
Bash
257 lines
9.1 KiB
Bash
# This script is used to check all pre-defined built-in macros in a given
|
|
# standalone toolchain. Call from tests/standalone/run.sh only.
|
|
#
|
|
|
|
macro_assign () {
|
|
local _VARNAME=$1
|
|
local _VARVALUE="$2"
|
|
eval macro_$_VARNAME=\"$_VARVALUE\"
|
|
}
|
|
|
|
macro_val () {
|
|
eval echo -n \"\$macro_$1\"
|
|
}
|
|
|
|
# Read all the built-in macros, and assign them to our own variables.
|
|
# For cygwin/mingw, don't use $NULL defined in parent run.sh to NUL, because
|
|
# NUL can't be used as input. The non-existance /dev/null works well.
|
|
MACRO_LINES=$($CC $CFLAGS -dM -E - < /dev/null | sort -u | tr ' ' '^^^' | tr '"' '~')
|
|
|
|
for LINE in $MACRO_LINES; do
|
|
# for cygwin, it's important to remove trailing '\r' as well
|
|
LINE=$(echo "$LINE" | tr '^^^' ' ' | tr '\r' ' ')
|
|
VARNAME=$(echo "$LINE" | cut -d' ' -f 2)
|
|
VARVALUE=$(echo "$LINE" | cut -d' ' -f 3)
|
|
|
|
# Avoid macro names that contain parentheses.
|
|
echo "$VARNAME" | grep -q -v -e '('
|
|
if [ $? != 0 ]; then
|
|
continue
|
|
fi
|
|
|
|
macro_assign $VARNAME $VARVALUE
|
|
done
|
|
|
|
# Now perform some checks
|
|
|
|
FAILURES=0
|
|
COUNT=0
|
|
|
|
# $1: variable name
|
|
# $2: expected value
|
|
macro_expect () {
|
|
|
|
local VAL=$(macro_val $1)
|
|
if [ -z "$VAL" ]; then
|
|
echo "Missing built-in macro definition: $1"
|
|
return 1
|
|
fi
|
|
if [ "$VAL" != "$2" ]; then
|
|
echo "Invalid built-in macro definition: '$VAL', expected '$2'"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Check the definition of a given macro
|
|
# $1: macro name
|
|
# $2: expected value
|
|
# $3: textual description for the check
|
|
macro_check () {
|
|
if [ -n "$3" ]; then
|
|
echo -n "Checking $1 ($3): "
|
|
else
|
|
echo -n "Checking $1: "
|
|
fi
|
|
macro_expect "$1" "$2"
|
|
if [ $? != 0 ]; then
|
|
FAILURES=$(( $FAILURES + 1 ))
|
|
else
|
|
echo "ok"
|
|
fi
|
|
COUNT=$(( $COUNT + 1 ))
|
|
}
|
|
|
|
# Check the definition of a given macro against multiple values
|
|
# $1: macro name
|
|
# $2+: list of acceptable values.
|
|
macro_multi_check () {
|
|
echo -n "Checking $1: "
|
|
local VAL=$(macro_val $1)
|
|
if [ -z "$VAL" ]; then
|
|
echo "Missing built-in macro definition: $1"
|
|
return 1
|
|
fi
|
|
local VAL2 FOUND
|
|
shift
|
|
for VAL2 in "$@"; do
|
|
if [ "$VAL2" = "$VAL" ]; then
|
|
FOUND=true
|
|
break
|
|
fi
|
|
done
|
|
if [ -z "$FOUND" ]; then
|
|
echo "Invalid built-in macro definition: '$VAL', expected one of: $@"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Check that a given macro is undefined
|
|
macro_check_undef () {
|
|
echo -n "Checking undefined $1: "
|
|
local VAL="$(macro_val $1)"
|
|
if [ -n "$VAL" ]; then
|
|
echo "KO: Unexpected value '$VAL' encounteded"
|
|
FAILURES=$(( $FAILURES + 1 ))
|
|
else
|
|
echo "ok"
|
|
fi
|
|
COUNT=$(( $COUNT + 1 ))
|
|
}
|
|
|
|
echo "Checking built-in macros for: $CC $CFLAGS"
|
|
|
|
# All toolchains must define the following prebuilt macros.
|
|
macro_check __ANDROID__ 1 "Android target system"
|
|
macro_check __linux__ 1 "Linux target system"
|
|
macro_check __unix__ 1 "Unix target system"
|
|
macro_check __ELF__ 1 "ELF target system"
|
|
|
|
# Either __pic__ or __PIC__ must be defined. Defining both is ok, not
|
|
# having anyone of them defined is an error.
|
|
#
|
|
# The value should be 1 on all platforms, except x86 where it will be 2
|
|
# (No idea why).
|
|
case $ABI in
|
|
x86) PICVAL=2;;
|
|
*) PICVAL=1;;
|
|
esac
|
|
|
|
case $ABI in
|
|
armeabi|armeabi-v7a|armeabi-v7a-hard)
|
|
macro_check __arm__ 1 "ARM CPU architecture"
|
|
macro_check_undef __LP64__ "LP64 data model"
|
|
macro_check __ARM_EABI__ 1 "ARM EABI runtime"
|
|
macro_check __ARMEL__ 1 "ARM little-endian"
|
|
macro_check __THUMB_INTERWORK__ 1 "ARM thumb-interwork"
|
|
macro_check __PIC__ 1 "Position independent code (-fpic)"
|
|
macro_check __WCHAR_TYPE__ "unsigned"
|
|
macro_check __WCHAR_MAX__ "4294967295U"
|
|
# Clang doesn't define __WCHAR_MIN__ so don't check it"
|
|
|
|
case $ABI in
|
|
armeabi)
|
|
macro_check __ARM_ARCH_5TE__ 1 "ARMv5TE instructions (for armeabi)"
|
|
macro_check __SOFTFP__ 1 "ARM soft-floating point"
|
|
;;
|
|
armeabi-v7a)
|
|
macro_check __ARM_ARCH_7A__ 1 "ARMv7-A instructions (for armeabi-v7a)"
|
|
|
|
# This macro seems to be ill-named. It is only defined when we
|
|
# don't use -mfloat-abi=softfp or -mfloat-abi=hard. I can only
|
|
# assume it corresponds to -mfloat-abi=soft, which corresponds
|
|
# to all FP operations implemented (slowly) through software.
|
|
#
|
|
# Not to be confused with -mfloat-abi=softfp which indicates
|
|
# that the FPU is used for all FP operations, but that FP
|
|
# values are passsed in core registers between function calls,
|
|
# which is mandated by the armeabi-v7a definition.
|
|
#
|
|
macro_check_undef __SOFTFP__ "ARM soft-floating point"
|
|
;;
|
|
armeabi-v7a-hard)
|
|
macro_check __ARM_ARCH_7A__ 1 "ARMv7-A instructions (for armeabi-v7a)"
|
|
macro_check __ARM_PCS_VFP__ 1 "ARM hard-floating point"
|
|
macro_check_undef __SOFTFP__ "ARM soft-floating point"
|
|
;;
|
|
esac
|
|
;;
|
|
|
|
x86)
|
|
macro_check __i386__ 1 "x86 CPU architecture"
|
|
macro_check_undef __LP64__ "LP64 data model"
|
|
macro_check __i686__ 1 "i686 instruction set"
|
|
macro_check __PIC__ 2 "Position independent code (-fPIC)"
|
|
macro_check __MMX__ 1 "MMX instruction set"
|
|
macro_check __SSE__ 1 "SSE instruction set"
|
|
macro_check __SSE2__ 1 "SSE2 instruction set"
|
|
macro_check __SSE3__ 1 "SSE3 instruction set"
|
|
macro_check __SSE_MATH__ 1 "Use SSE for math operations"
|
|
macro_check __SSE2_MATH__ 1 "Use SSE2 for math operations"
|
|
# GCC defines is as 'long', and Clang as 'int'
|
|
macro_multi_check __WCHAR_TYPE__ "long" "int"
|
|
# GCC defines it with an L suffix, Clang doesn't.
|
|
macro_multi_check __WCHAR_MAX__ "2147483647L" "2147483647"
|
|
;;
|
|
|
|
mips)
|
|
macro_check __mips__ 1 "Mips CPU architecture"
|
|
macro_check_undef __LP64__ "LP64 data model"
|
|
macro_check _MIPS_ARCH_MIPS32 1 "Mips 32-bit ABI"
|
|
macro_check __MIPSEL__ 1 "Mips little-endian"
|
|
macro_check __PIC__ 1 "Position independent code (-fpic)"
|
|
# GCC defines it as "signed int", and Clang as "int"
|
|
macro_multi_check __WCHAR_TYPE__ "signed int" "int"
|
|
macro_check __WCHAR_MAX__ "2147483647"
|
|
;;
|
|
arm64-v8a)
|
|
macro_check __aarch64__ 1 "ARM CPU architecture"
|
|
macro_check __LP64__ 1 "LP64 data model"
|
|
macro_check __AARCH64EL__ 1 "ARM AARCH64 little-endian runtime"
|
|
macro_check __PIC__ 1 "Position independent code (-fpic)"
|
|
macro_check __WCHAR_TYPE__ "unsigned"
|
|
macro_check __WCHAR_MAX__ "4294967295U"
|
|
# Clang doesn't define __WCHAR_MIN__ so don't check it"
|
|
;;
|
|
|
|
x86_64)
|
|
macro_check __x86_64__ 1 "x86_64 CPU architecture"
|
|
macro_check __LP64__ 1 "LP64 data model"
|
|
macro_check __PIC__ 2 "Position independent code (-fPIC)"
|
|
macro_check __MMX__ 1 "MMX instruction set"
|
|
macro_check __SSE__ 1 "SSE instruction set"
|
|
macro_check __SSE2__ 1 "SSE2 instruction set"
|
|
macro_check __SSE3__ 1 "SSE3 instruction set"
|
|
macro_check __SSE_MATH__ 1 "Use SSE for math operations"
|
|
macro_check __SSE2_MATH__ 1 "Use SSE2 for math operations"
|
|
#macro_check __SSSE3__ 1 "SSSE3 instruction set"
|
|
macro_check __WCHAR_TYPE__ "int"
|
|
macro_check __WCHAR_MAX__ "2147483647"
|
|
;;
|
|
|
|
mips64)
|
|
macro_check __mips__ 1 "Mips CPU architecture"
|
|
macro_check __mips64 1 "Mips 64-bit CPU architecture"
|
|
macro_check __LP64__ 1 "LP64 data model"
|
|
macro_check __MIPSEL__ 1 "Mips little-endian"
|
|
macro_check __PIC__ 1 "Position independent code (-fpic)"
|
|
macro_check __WCHAR_TYPE__ "int"
|
|
macro_check __WCHAR_MAX__ "2147483647"
|
|
;;
|
|
*)
|
|
echo "Unknown ABI: $ABI"
|
|
exit 1
|
|
esac
|
|
|
|
macro_check "__SIZEOF_SHORT__" "2" "short is 16-bit"
|
|
macro_check "__SIZEOF_INT__" "4" "int is 32-bit"
|
|
macro_check "__SIZEOF_FLOAT__" "4" "float is 32-bit"
|
|
macro_check "__SIZEOF_DOUBLE__" "8" "double is 64-bit"
|
|
if [ "$ABI" = "${ABI%%64*}" ]; then
|
|
macro_check "__SIZEOF_LONG_DOUBLE__" "8" "long double is 64-bit"
|
|
macro_check "__SIZEOF_POINTER__" "4" "pointers are 32-bit"
|
|
else
|
|
macro_check "__SIZEOF_LONG_DOUBLE__" "16" "long double is 128-bit"
|
|
macro_check "__SIZEOF_POINTER__" "8" "pointers are 64-bit"
|
|
fi
|
|
macro_check "__SIZEOF_LONG_LONG__" "8" "long long is 64-bit"
|
|
macro_check "__SIZEOF_WCHAR_T__" "4" "wchar_t is 32-bit"
|
|
|
|
if [ "$FAILURES" = 0 ]; then
|
|
echo "$COUNT/$COUNT tests passed. Nice job."
|
|
exit 0
|
|
fi
|
|
|
|
echo "$FAILURES/$COUNT tests failed !!"
|
|
exit 1
|