Blame scripts/check-installed-headers.sh

Packit 6c4009
#! /bin/sh
Packit 6c4009
# Copyright (C) 2016-2018 Free Software Foundation, Inc.
Packit 6c4009
# This file is part of the GNU C Library.
Packit 6c4009
#
Packit 6c4009
# The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
# modify it under the terms of the GNU Lesser General Public
Packit 6c4009
# License as published by the Free Software Foundation; either
Packit 6c4009
# version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
#
Packit 6c4009
# The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
# Lesser General Public License for more details.
Packit 6c4009
#
Packit 6c4009
# You should have received a copy of the GNU Lesser General Public
Packit 6c4009
# License along with the GNU C Library; if not, see
Packit 6c4009
# <http://www.gnu.org/licenses/>.
Packit 6c4009
Packit Bot 0c2104
# Check installed headers for cleanliness.  For each header, confirm
Packit Bot 0c2104
# that it's possible to compile a file that includes that header and
Packit Bot 0c2104
# does nothing else, in several different compilation modes.  Also,
Packit Bot 0c2104
# scan the header for a set of obsolete typedefs that should no longer
Packit Bot 0c2104
# appear.
Packit 6c4009
Packit 6c4009
# These compilation switches assume GCC or compatible, which is probably
Packit 6c4009
# fine since we also assume that when _building_ glibc.
Packit 6c4009
c_modes="-std=c89 -std=gnu89 -std=c11 -std=gnu11"
Packit 6c4009
cxx_modes="-std=c++98 -std=gnu++98 -std=c++11 -std=gnu++11"
Packit 6c4009
Packit 6c4009
# An exhaustive test of feature selection macros would take far too long.
Packit 6c4009
# These are probably the most commonly used three.
Packit 6c4009
lib_modes="-D_DEFAULT_SOURCE=1 -D_GNU_SOURCE=1 -D_XOPEN_SOURCE=700"
Packit 6c4009
Packit Bot 0c2104
# sys/types.h+bits/types.h have to define the obsolete types.
Packit Bot 0c2104
# rpc(svc)/* have the obsolete types too deeply embedded in their API
Packit Bot 0c2104
# to remove.
Packit Bot 0c2104
skip_obsolete_type_check='*/sys/types.h|*/bits/types.h|*/rpc/*|*/rpcsvc/*'
Packit Bot 0c2104
obsolete_type_re=\
Packit Bot 0c2104
'\<((__)?(quad_t|u(short|int|long|_(char|short|int([0-9]+_t)?|long|quad_t))))\>'
Packit Bot 0c2104
Packit 6c4009
if [ $# -lt 3 ]; then
Packit 6c4009
    echo "usage: $0 c|c++ \"compile command\" header header header..." >&2
Packit 6c4009
    exit 2
Packit 6c4009
fi
Packit 6c4009
case "$1" in
Packit 6c4009
    (c)
Packit 6c4009
        lang_modes="$c_modes"
Packit 6c4009
        cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.c)
Packit Bot 0c2104
        already="$skip_obsolete_type_check"
Packit 6c4009
    ;;
Packit 6c4009
    (c++)
Packit 6c4009
        lang_modes="$cxx_modes"
Packit 6c4009
        cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.cc)
Packit Bot 0c2104
        # The obsolete-type check can be skipped for C++; it is
Packit Bot 0c2104
        # sufficient to do it for C.
Packit Bot 0c2104
        already="*"
Packit 6c4009
    ;;
Packit 6c4009
    (*)
Packit 6c4009
        echo "usage: $0 c|c++ \"compile command\" header header header..." >&2
Packit 6c4009
        exit 2;;
Packit 6c4009
esac
Packit 6c4009
shift
Packit 6c4009
cc_cmd="$1"
Packit 6c4009
shift
Packit 6c4009
trap "rm -f '$cih_test_c'" 0
Packit 6c4009
Packit 6c4009
failed=0
Packit 6c4009
is_x86_64=unknown
Packit 6c4009
is_x32=unknown
Packit 6c4009
for header in "$@"; do
Packit 6c4009
    # Skip various headers for which this test gets a false failure.
Packit 6c4009
    case "$header" in
Packit 6c4009
        # bits/* are not meant to be included directly and usually #error
Packit 6c4009
        # out if you try it.
Packit 6c4009
        # regexp.h is a stub containing only an #error.
Packit 6c4009
        # Sun RPC's .x files are traditionally installed in
Packit 6c4009
        # $prefix/include/rpcsvc, but they are not C header files.
Packit 6c4009
        (bits/* | regexp.h | rpcsvc/*.x)
Packit 6c4009
            continue;;
Packit 6c4009
Packit 6c4009
        # All extant versions of sys/elf.h contain nothing more than an
Packit 6c4009
        # exhortation (either a #warning or an #error) to use sys/procfs.h
Packit 6c4009
        # instead, plus an inclusion of that header.
Packit 6c4009
        (sys/elf.h)
Packit 6c4009
            continue;;
Packit 6c4009
Packit 6c4009
	# sys/sysctl.h is unsupported for x32.
Packit 6c4009
	(sys/sysctl.h)
Packit 6c4009
            case "$is_x32" in
Packit 6c4009
                (yes) continue;;
Packit 6c4009
                (no)  ;;
Packit 6c4009
                (unknown)
Packit 6c4009
                    cat >"$cih_test_c" <
Packit 6c4009
#if defined __x86_64__ && defined __ILP32__
Packit 6c4009
# error "is x32"
Packit 6c4009
#endif
Packit 6c4009
EOF
Packit 6c4009
                    if $cc_cmd -fsyntax-only "$cih_test_c" > /dev/null 2>&1
Packit 6c4009
                    then
Packit 6c4009
                        is_x32=no
Packit 6c4009
                    else
Packit 6c4009
                        is_x32=yes
Packit 6c4009
                        continue
Packit 6c4009
                    fi
Packit 6c4009
                ;;
Packit 6c4009
            esac
Packit 6c4009
	    ;;
Packit 6c4009
Packit 6c4009
        # sys/vm86.h is "unsupported on x86-64" and errors out on that target.
Packit 6c4009
        (sys/vm86.h)
Packit 6c4009
            case "$is_x86_64" in
Packit 6c4009
                (yes) continue;;
Packit 6c4009
                (no)  ;;
Packit 6c4009
                (unknown)
Packit 6c4009
                    cat >"$cih_test_c" <
Packit 6c4009
#if defined __x86_64__ && __x86_64__
Packit 6c4009
#error "is x86-64"
Packit 6c4009
#endif
Packit 6c4009
EOF
Packit 6c4009
                    if $cc_cmd -fsyntax-only "$cih_test_c" > /dev/null 2>&1
Packit 6c4009
                    then
Packit 6c4009
                        is_x86_64=no
Packit 6c4009
                    else
Packit 6c4009
                        is_x86_64=yes
Packit 6c4009
                        continue
Packit 6c4009
                    fi
Packit 6c4009
                ;;
Packit 6c4009
            esac
Packit 6c4009
            ;;
Packit 6c4009
    esac
Packit 6c4009
Packit 6c4009
    echo :: "$header"
Packit 6c4009
    for lang_mode in "" $lang_modes; do
Packit 6c4009
        for lib_mode in "" $lib_modes; do
Packit 6c4009
            echo :::: $lang_mode $lib_mode
Packit 6c4009
            if [ -z "$lib_mode" ]; then
Packit 6c4009
                expanded_lib_mode='/* default library mode */'
Packit 6c4009
            else
Packit 6c4009
                expanded_lib_mode=$(echo : $lib_mode | \
Packit 6c4009
                    sed 's/^: -D/#define /; s/=/ /')
Packit 6c4009
            fi
Packit 6c4009
            cat >"$cih_test_c" <
Packit 6c4009
/* These macros may have been defined on the command line.  They are
Packit 6c4009
   inappropriate for this test.  */
Packit 6c4009
#undef _LIBC
Packit 6c4009
#undef _GNU_SOURCE
Packit 6c4009
/* The library mode is selected here rather than on the command line to
Packit 6c4009
   ensure that this selection wins. */
Packit 6c4009
$expanded_lib_mode
Packit 6c4009
#include <$header>
Packit 6c4009
int avoid_empty_translation_unit;
Packit 6c4009
EOF
Packit 6c4009
            if $cc_cmd -fsyntax-only $lang_mode "$cih_test_c" 2>&1
Packit Bot 0c2104
            then
Packit Bot 0c2104
                includes=$($cc_cmd -fsyntax-only -H $lang_mode \
Packit Bot 0c2104
                              "$cih_test_c" 2>&1 | sed -ne 's/^[.][.]* //p')
Packit Bot 0c2104
                for h in $includes; do
Packit Bot 0c2104
                    # Don't repeat work.
Packit Bot 0c2104
                    eval 'case "$h" in ('"$already"') continue;; esac'
Packit Bot 0c2104
Packit Bot 0c2104
                    if grep -qE "$obsolete_type_re" "$h"; then
Packit Bot 0c2104
                        echo "*** Obsolete types detected:"
Packit Bot 0c2104
                        grep -HE "$obsolete_type_re" "$h"
Packit Bot 0c2104
                        failed=1
Packit Bot 0c2104
                    fi
Packit Bot 0c2104
                    already="$already|$h"
Packit Bot 0c2104
                done
Packit Bot 0c2104
            else
Packit Bot 0c2104
                failed=1
Packit 6c4009
            fi
Packit 6c4009
        done
Packit 6c4009
    done
Packit 6c4009
done
Packit 6c4009
exit $failed