| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- #!/usr/bin/python3
- # Check that a wrapper header exist for each non-sysdeps header.
- # Copyright (C) 2019-2026 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
- # <https://www.gnu.org/licenses/>.
- # Non-sysdeps subdirectories are not on the C include path, so
- # installed headers need to have a sysdep wrapper header.
- #
- # usage: scripts/checl-wrapper-headers.py \
- # --root=$(..) --subdir=$(subdir) $(headers) \
- # [--generated $(common-generated)]
- #
- # If invoked with --root=., the script is invoked from the root of the
- # source tree, so paths starting with "include/" are skipped (because
- # those do not require wrappers).
- import argparse
- import os
- import sys
- # Some subdirectories are only compiled for essentially one target.
- # In this case, we do not need to check for consistent wrapper
- # headers. Hurd uses a custom way to Hurd-specific inject wrapper
- # headers; see sysdeps/mach/Makefiles under "ifdef in-Makerules".
- SINGLE_TARGET_SUBDIRS = frozenset(("hurd", "mach"))
- # Name of the special subdirectory with the wrapper headers.
- INCLUDE = "include"
- def check_sysdeps_bits(args):
- """Check that the directory sysdeps/generic/bits does not exist."""
- bits = os.path.join(args.root, 'sysdeps', 'generic', 'bits')
- if os.path.exists(bits):
- # See commit c72565e5f1124c2dc72573e83406fe999e56091f and
- # <https://sourceware.org/ml/libc-alpha/2016-05/msg00189.html>.
- print('error: directory {} has been added, use bits/ instead'.format(
- os.path.relpath(os.path.realpath(bits), args.root)))
- return False
- return True
- def check_headers_root(args):
- """Check headers located at the top level of the source tree."""
- good = True
- generated = frozenset(args.generated)
- for header in args.headers:
- if not (header.startswith('bits/')
- or os.path.exists(os.path.join(args.root, INCLUDE, header))
- or header in generated):
- print('error: top-level header {} must be in bits/ or {}/'
- .format(header, INCLUDE))
- good = False
- return good
- def check_headers(args):
- """Check headers located in a subdirectory."""
- good = True
- for header in args.headers:
- # Whitelist .x files, which never have include wrappers.
- if header.endswith(".x"):
- continue
- is_nonsysdep_header = os.access(header, os.R_OK)
- if is_nonsysdep_header:
- # Skip Fortran header files.
- if header.startswith("finclude/"):
- continue
- include_path = os.path.join(args.root, INCLUDE, header)
- if not os.access(include_path, os.R_OK):
- print('error: missing wrapper header {} for {}'.format(
- os.path.join(INCLUDE, header),
- os.path.relpath(os.path.realpath(header), args.root)))
- good = False
- return good
- def main():
- """The main entry point."""
- parser = argparse.ArgumentParser(
- description='Check for missing wrapper headers in include/.')
- parser.add_argument('--root', metavar='DIRECTORY', required=True,
- help='Path to the top-level of the source tree')
- parser.add_argument('--subdir', metavar='DIRECTORY', required=True,
- help='Name of the subdirectory being processed')
- parser.add_argument('--generated', metavar='FILE', default="", nargs="*",
- help="Generated files (which are ignored)")
- parser.add_argument('headers', help='Header files to process', nargs='+')
- args = parser.parse_args()
- good = (args.root == '.') == (args.subdir == '.')
- if not good:
- print('error: --root/--subdir disagree about top-of-tree location')
- if args.subdir == '.':
- good &= check_sysdeps_bits(args)
- good &= check_headers_root(args)
- elif args.subdir not in SINGLE_TARGET_SUBDIRS:
- good &= check_headers(args)
- if not good:
- sys.exit(1)
- if __name__ == '__main__':
- main()
|