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