Installed header hygiene (BZ#20366): Test of installed headers.
This adds a test to ensure that the problems fixed in the last several
patches do not recur. Each directory checks the headers that it
installs for two properties: first, each header must be compilable in
isolation, as both C and C++, under a representative combination of
language and library conformance levels; second, there is a blacklist
of identifiers that may not appear in any installed header, currently
consisting of the legacy BSD typedefs. (There is an exemption for the
headers that define those typedefs, and for the RPC headers. It may be
necessary to make this more sophisticated if we add more stuff to the
blacklist in the future.)
In order for this test to work correctly, every wrapper header
that actually defines something must guard those definitions with
#ifndef _ISOMAC. This is the existing mechanism used by the conform/
tests to tell wrapper headers not to define anything that the public
header wouldn't, and not to use anything from libc-symbols.h. conform/
only cares for headers that we need to check for standards conformance,
whereas this test applies to *every* header. (Headers in include/ that
are either installed directly, or are internal-use-only and do *not*
correspond to any installed header, are not affected.)
* scripts/check-installed-headers.sh: New script.
* Rules: In each directory that defines header files to be installed,
run check-installed-headers.sh on them as a special test.
* Makefile: Likewise for the headers installed at top level.
* include/aliases.h, include/alloca.h, include/argz.h
* include/arpa/nameser.h, include/arpa/nameser_compat.h
* include/elf.h, include/envz.h, include/err.h
* include/execinfo.h, include/fpu_control.h, include/getopt.h
* include/gshadow.h, include/ifaddrs.h, include/libintl.h
* include/link.h, include/malloc.h, include/mcheck.h
* include/mntent.h, include/netinet/ether.h
* include/nss.h, include/obstack.h, include/printf.h
* include/pty.h, include/resolv.h, include/rpc/auth.h
* include/rpc/auth_des.h, include/rpc/auth_unix.h
* include/rpc/clnt.h, include/rpc/des_crypt.h
* include/rpc/key_prot.h, include/rpc/netdb.h
* include/rpc/pmap_clnt.h, include/rpc/pmap_prot.h
* include/rpc/pmap_rmt.h, include/rpc/rpc.h
* include/rpc/rpc_msg.h, include/rpc/svc.h
* include/rpc/svc_auth.h, include/rpc/xdr.h
* include/rpcsvc/nis_callback.h, include/rpcsvc/nislib.h
* include/rpcsvc/yp.h, include/rpcsvc/ypclnt.h
* include/rpcsvc/ypupd.h, include/shadow.h
* include/stdio_ext.h, include/sys/epoll.h
* include/sys/file.h, include/sys/gmon.h, include/sys/ioctl.h
* include/sys/prctl.h, include/sys/profil.h
* include/sys/statfs.h, include/sys/sysctl.h
* include/sys/sysinfo.h, include/ttyent.h, include/utmp.h
* sysdeps/arm/nacl/include/bits/setjmp.h
* sysdeps/mips/include/sys/asm.h
* sysdeps/unix/sysv/linux/include/sys/sysinfo.h
* sysdeps/unix/sysv/linux/include/sys/timex.h
* sysdeps/x86/fpu/include/bits/fenv.h:
Add #ifndef _ISOMAC guard around internal declarations.
Add multiple-inclusion guard if not already present.
2016-08-24 09:19:17 +08:00
|
|
|
#! /bin/sh
|
2018-01-01 08:32:25 +08:00
|
|
|
# Copyright (C) 2016-2018 Free Software Foundation, Inc.
|
Installed header hygiene (BZ#20366): Test of installed headers.
This adds a test to ensure that the problems fixed in the last several
patches do not recur. Each directory checks the headers that it
installs for two properties: first, each header must be compilable in
isolation, as both C and C++, under a representative combination of
language and library conformance levels; second, there is a blacklist
of identifiers that may not appear in any installed header, currently
consisting of the legacy BSD typedefs. (There is an exemption for the
headers that define those typedefs, and for the RPC headers. It may be
necessary to make this more sophisticated if we add more stuff to the
blacklist in the future.)
In order for this test to work correctly, every wrapper header
that actually defines something must guard those definitions with
#ifndef _ISOMAC. This is the existing mechanism used by the conform/
tests to tell wrapper headers not to define anything that the public
header wouldn't, and not to use anything from libc-symbols.h. conform/
only cares for headers that we need to check for standards conformance,
whereas this test applies to *every* header. (Headers in include/ that
are either installed directly, or are internal-use-only and do *not*
correspond to any installed header, are not affected.)
* scripts/check-installed-headers.sh: New script.
* Rules: In each directory that defines header files to be installed,
run check-installed-headers.sh on them as a special test.
* Makefile: Likewise for the headers installed at top level.
* include/aliases.h, include/alloca.h, include/argz.h
* include/arpa/nameser.h, include/arpa/nameser_compat.h
* include/elf.h, include/envz.h, include/err.h
* include/execinfo.h, include/fpu_control.h, include/getopt.h
* include/gshadow.h, include/ifaddrs.h, include/libintl.h
* include/link.h, include/malloc.h, include/mcheck.h
* include/mntent.h, include/netinet/ether.h
* include/nss.h, include/obstack.h, include/printf.h
* include/pty.h, include/resolv.h, include/rpc/auth.h
* include/rpc/auth_des.h, include/rpc/auth_unix.h
* include/rpc/clnt.h, include/rpc/des_crypt.h
* include/rpc/key_prot.h, include/rpc/netdb.h
* include/rpc/pmap_clnt.h, include/rpc/pmap_prot.h
* include/rpc/pmap_rmt.h, include/rpc/rpc.h
* include/rpc/rpc_msg.h, include/rpc/svc.h
* include/rpc/svc_auth.h, include/rpc/xdr.h
* include/rpcsvc/nis_callback.h, include/rpcsvc/nislib.h
* include/rpcsvc/yp.h, include/rpcsvc/ypclnt.h
* include/rpcsvc/ypupd.h, include/shadow.h
* include/stdio_ext.h, include/sys/epoll.h
* include/sys/file.h, include/sys/gmon.h, include/sys/ioctl.h
* include/sys/prctl.h, include/sys/profil.h
* include/sys/statfs.h, include/sys/sysctl.h
* include/sys/sysinfo.h, include/ttyent.h, include/utmp.h
* sysdeps/arm/nacl/include/bits/setjmp.h
* sysdeps/mips/include/sys/asm.h
* sysdeps/unix/sysv/linux/include/sys/sysinfo.h
* sysdeps/unix/sysv/linux/include/sys/timex.h
* sysdeps/x86/fpu/include/bits/fenv.h:
Add #ifndef _ISOMAC guard around internal declarations.
Add multiple-inclusion guard if not already present.
2016-08-24 09:19:17 +08:00
|
|
|
# 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
|
2016-11-08 07:32:17 +08:00
|
|
|
is_x32=unknown
|
Installed header hygiene (BZ#20366): Test of installed headers.
This adds a test to ensure that the problems fixed in the last several
patches do not recur. Each directory checks the headers that it
installs for two properties: first, each header must be compilable in
isolation, as both C and C++, under a representative combination of
language and library conformance levels; second, there is a blacklist
of identifiers that may not appear in any installed header, currently
consisting of the legacy BSD typedefs. (There is an exemption for the
headers that define those typedefs, and for the RPC headers. It may be
necessary to make this more sophisticated if we add more stuff to the
blacklist in the future.)
In order for this test to work correctly, every wrapper header
that actually defines something must guard those definitions with
#ifndef _ISOMAC. This is the existing mechanism used by the conform/
tests to tell wrapper headers not to define anything that the public
header wouldn't, and not to use anything from libc-symbols.h. conform/
only cares for headers that we need to check for standards conformance,
whereas this test applies to *every* header. (Headers in include/ that
are either installed directly, or are internal-use-only and do *not*
correspond to any installed header, are not affected.)
* scripts/check-installed-headers.sh: New script.
* Rules: In each directory that defines header files to be installed,
run check-installed-headers.sh on them as a special test.
* Makefile: Likewise for the headers installed at top level.
* include/aliases.h, include/alloca.h, include/argz.h
* include/arpa/nameser.h, include/arpa/nameser_compat.h
* include/elf.h, include/envz.h, include/err.h
* include/execinfo.h, include/fpu_control.h, include/getopt.h
* include/gshadow.h, include/ifaddrs.h, include/libintl.h
* include/link.h, include/malloc.h, include/mcheck.h
* include/mntent.h, include/netinet/ether.h
* include/nss.h, include/obstack.h, include/printf.h
* include/pty.h, include/resolv.h, include/rpc/auth.h
* include/rpc/auth_des.h, include/rpc/auth_unix.h
* include/rpc/clnt.h, include/rpc/des_crypt.h
* include/rpc/key_prot.h, include/rpc/netdb.h
* include/rpc/pmap_clnt.h, include/rpc/pmap_prot.h
* include/rpc/pmap_rmt.h, include/rpc/rpc.h
* include/rpc/rpc_msg.h, include/rpc/svc.h
* include/rpc/svc_auth.h, include/rpc/xdr.h
* include/rpcsvc/nis_callback.h, include/rpcsvc/nislib.h
* include/rpcsvc/yp.h, include/rpcsvc/ypclnt.h
* include/rpcsvc/ypupd.h, include/shadow.h
* include/stdio_ext.h, include/sys/epoll.h
* include/sys/file.h, include/sys/gmon.h, include/sys/ioctl.h
* include/sys/prctl.h, include/sys/profil.h
* include/sys/statfs.h, include/sys/sysctl.h
* include/sys/sysinfo.h, include/ttyent.h, include/utmp.h
* sysdeps/arm/nacl/include/bits/setjmp.h
* sysdeps/mips/include/sys/asm.h
* sysdeps/unix/sysv/linux/include/sys/sysinfo.h
* sysdeps/unix/sysv/linux/include/sys/timex.h
* sysdeps/x86/fpu/include/bits/fenv.h:
Add #ifndef _ISOMAC guard around internal declarations.
Add multiple-inclusion guard if not already present.
2016-08-24 09:19:17 +08:00
|
|
|
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;;
|
|
|
|
|
2016-09-28 19:28:00 +08:00
|
|
|
# All extant versions of sys/elf.h contain nothing more than an
|
|
|
|
# exhortation (either a #warning or an #error) to use sys/procfs.h
|
|
|
|
# instead, plus an inclusion of that header.
|
|
|
|
(sys/elf.h)
|
|
|
|
continue;;
|
|
|
|
|
Deprecate external use of libio.h and _G_config.h.
libio.h was originally the header for a set of supported GNU
extensions, but they have not been maintained as such in many years,
they are now standing in the way of improvements to stdio, and we
don't think there are any remaining external users. _G_config.h was
never intended for public use, but predates the bits convention.
Move both of these headers into the bits directory and provide stubs
at top level which issue deprecation warnings.
The contents of (bits/)libio.h and (bits/)_G_config.h are still
exposed to external software via stdio.h; changing that requires more
complex surgery than I have time to attempt right now.
* libio/libio.h, libio/_G_config.h: New stub headers which issue a
deprecation warning and then include <bits/libio.h>, <bits/_G_config.h>
respectively.
* libio/libio.h: Rename the original version of this file to
libio/bits/libio.h. Error out if not included by stdio.h or the
stub libio.h.
* include/libio.h: Move to include/bits. Forward to libio/bits/libio.h.
* sysdeps/generic/_G_config.h: Move to top-level bits/. Error out
if not included by bits/libio.h or the stub _G_config.h.
* sysdeps/unix/sysv/linux/_G_config.h: Move to
sysdeps/unix/sysv/linux/bits. Error out if not included by
bits/libio.h or the stub _G_config.h.
* libio/stdio.h: Include bits/libio.h, not libio.h.
* libio/Makefile: Install bits/libio.h and bits/_G_config.h as
well as libio.h and _G_config.h.
* csu/init.c, libio/fmemopen.c, libio/iolibio.h, libio/oldfmemopen.c
* libio/strfile.h, stdio-common/vfscanf.c
* sysdeps/pthread/flockfile.c, sysdeps/pthread/funlockfile.c
Include stdio.h, not _G_config.h nor libio.h.
* libio/iofgetpos.c: Also rename fgetpos64 out of the way.
* libio/iofsetpos.c: Also rename fsetpos64 out of the way.
* scripts/check-installed-headers.sh: Skip libio.h and _G_config.h.
2017-12-23 13:06:03 +08:00
|
|
|
# libio.h and _G_config.h are deprecation stubs containing #warnings
|
|
|
|
# to use stdio.h instead.
|
|
|
|
(libio.h | _G_config.h)
|
|
|
|
continue;;
|
|
|
|
|
2016-11-08 07:32:17 +08:00
|
|
|
# sys/sysctl.h is unsupported for x32.
|
|
|
|
(sys/sysctl.h)
|
|
|
|
case "$is_x32" in
|
|
|
|
(yes) continue;;
|
|
|
|
(no) ;;
|
|
|
|
(unknown)
|
|
|
|
cat >"$cih_test_c" <<EOF
|
|
|
|
#if defined __x86_64__ && defined __ILP32__
|
|
|
|
# error "is x32"
|
|
|
|
#endif
|
|
|
|
EOF
|
|
|
|
if $cc_cmd -fsyntax-only "$cih_test_c" > /dev/null 2>&1
|
|
|
|
then
|
|
|
|
is_x32=no
|
|
|
|
else
|
|
|
|
is_x32=yes
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
;;
|
|
|
|
|
2016-09-28 19:28:00 +08:00
|
|
|
# sys/vm86.h is "unsupported on x86-64" and errors out on that target.
|
|
|
|
(sys/vm86.h)
|
Installed header hygiene (BZ#20366): Test of installed headers.
This adds a test to ensure that the problems fixed in the last several
patches do not recur. Each directory checks the headers that it
installs for two properties: first, each header must be compilable in
isolation, as both C and C++, under a representative combination of
language and library conformance levels; second, there is a blacklist
of identifiers that may not appear in any installed header, currently
consisting of the legacy BSD typedefs. (There is an exemption for the
headers that define those typedefs, and for the RPC headers. It may be
necessary to make this more sophisticated if we add more stuff to the
blacklist in the future.)
In order for this test to work correctly, every wrapper header
that actually defines something must guard those definitions with
#ifndef _ISOMAC. This is the existing mechanism used by the conform/
tests to tell wrapper headers not to define anything that the public
header wouldn't, and not to use anything from libc-symbols.h. conform/
only cares for headers that we need to check for standards conformance,
whereas this test applies to *every* header. (Headers in include/ that
are either installed directly, or are internal-use-only and do *not*
correspond to any installed header, are not affected.)
* scripts/check-installed-headers.sh: New script.
* Rules: In each directory that defines header files to be installed,
run check-installed-headers.sh on them as a special test.
* Makefile: Likewise for the headers installed at top level.
* include/aliases.h, include/alloca.h, include/argz.h
* include/arpa/nameser.h, include/arpa/nameser_compat.h
* include/elf.h, include/envz.h, include/err.h
* include/execinfo.h, include/fpu_control.h, include/getopt.h
* include/gshadow.h, include/ifaddrs.h, include/libintl.h
* include/link.h, include/malloc.h, include/mcheck.h
* include/mntent.h, include/netinet/ether.h
* include/nss.h, include/obstack.h, include/printf.h
* include/pty.h, include/resolv.h, include/rpc/auth.h
* include/rpc/auth_des.h, include/rpc/auth_unix.h
* include/rpc/clnt.h, include/rpc/des_crypt.h
* include/rpc/key_prot.h, include/rpc/netdb.h
* include/rpc/pmap_clnt.h, include/rpc/pmap_prot.h
* include/rpc/pmap_rmt.h, include/rpc/rpc.h
* include/rpc/rpc_msg.h, include/rpc/svc.h
* include/rpc/svc_auth.h, include/rpc/xdr.h
* include/rpcsvc/nis_callback.h, include/rpcsvc/nislib.h
* include/rpcsvc/yp.h, include/rpcsvc/ypclnt.h
* include/rpcsvc/ypupd.h, include/shadow.h
* include/stdio_ext.h, include/sys/epoll.h
* include/sys/file.h, include/sys/gmon.h, include/sys/ioctl.h
* include/sys/prctl.h, include/sys/profil.h
* include/sys/statfs.h, include/sys/sysctl.h
* include/sys/sysinfo.h, include/ttyent.h, include/utmp.h
* sysdeps/arm/nacl/include/bits/setjmp.h
* sysdeps/mips/include/sys/asm.h
* sysdeps/unix/sysv/linux/include/sys/sysinfo.h
* sysdeps/unix/sysv/linux/include/sys/timex.h
* sysdeps/x86/fpu/include/bits/fenv.h:
Add #ifndef _ISOMAC guard around internal declarations.
Add multiple-inclusion guard if not already present.
2016-08-24 09:19:17 +08:00
|
|
|
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
|
|
|
|
/* 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
|