Bash程序  |  258行  |  9.07 KB

# 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