Add "headerscheck" script to test header-file compilability under C.

We already had "cpluspluscheck", which served the dual purposes of
verifying that headers compile standalone and that they compile as C++.
However, C++ compilers don't have the exact same set of error conditions
as C compilers, so this doesn't really prove that a header will compile
standalone as C.

Hence, add a second script that's largely similar but runs the C
compiler not C++.

Also add a bit more documentation than the none-at-all we had before.

Discussion: https://postgr.es/m/14803.1566175851@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2019-08-19 14:22:56 -04:00
parent a120791096
commit 55ea109188
4 changed files with 210 additions and 1 deletions

View File

@ -128,7 +128,10 @@ distcheck: dist
rm -rf $(distdir) $(dummy)
@echo "Distribution integrity checks out."
headerscheck: submake-generated-headers
$(top_srcdir)/src/tools/pginclude/headerscheck $(top_srcdir) $(abs_top_builddir)
cpluspluscheck: submake-generated-headers
$(top_srcdir)/src/tools/pginclude/cpluspluscheck $(top_srcdir) $(abs_top_builddir)
.PHONY: dist distdir distcheck docs install-docs world check-world install-world installcheck-world
.PHONY: dist distdir distcheck docs install-docs world check-world install-world installcheck-world headerscheck cpluspluscheck

View File

@ -53,3 +53,51 @@ Another tools that does a similar task is at:
An include file visualizer script is available at:
http://archives.postgresql.org/pgsql-hackers/2011-09/msg00311.php
headerscheck
============
This script can be run to verify that all Postgres include files meet
the project convention that they will compile "standalone", that is
with no prerequisite headers other than postgres.h (or postgres_fe.h
or c.h, as appropriate).
A small number of header files are exempted from this requirement,
and are whitelisted in the headerscheck script.
The easy way to run the script is to say "make -s headerscheck" in
the top-level build directory after completing a build. You should
have included "--with-perl --with-python" in your configure options,
else you're likely to get errors about related headers not being found.
A limitation of the current script is that it doesn't know which headers
are for frontend or backend, so it tests everything with postgres.h
as prerequisite, even if postgres_fe.h would be more appropriate. Also
note that the contents of macros are not checked; this is intentional.
cpluspluscheck
==============
This script can be run to verify that all Postgres include files meet
the project convention that they will compile as C++ code. Although
the project's coding language is C, some people write extensions in C++,
so it's helpful for include files to be C++-clean.
A small number of header files are exempted from this requirement,
and are whitelisted in the cpluspluscheck script.
The easy way to run the script is to say "make -s cpluspluscheck" in
the top-level build directory after completing a build. You should
have included "--with-perl --with-python" in your configure options,
else you're likely to get errors about related headers not being found.
If you are using a non-g++-compatible C++ compiler, you may need to
override the script's CXXFLAGS setting by setting a suitable environment
value.
A limitation of the current script is that it doesn't know which headers
are for frontend or backend, so it tests everything with postgres.h
as prerequisite, even if postgres_fe.h would be more appropriate. Also
note that the contents of macros are not checked; this is intentional.

View File

@ -7,8 +7,13 @@
# default to the current directory.
#
# Needs to be run after configuring and creating all generated headers.
# It's advisable to configure --with-perl --with-python, else you're
# likely to get errors from associated headers.
#
# No output if everything is OK, else compiler errors.
#
# src/tools/pginclude/cpluspluscheck
# Copyright (c) 2009-2019, PostgreSQL Global Development Group
if [ -z "$1" ]; then
srcdir="."

153
src/tools/pginclude/headerscheck Executable file
View File

@ -0,0 +1,153 @@
#!/bin/sh
# Check (almost) all PostgreSQL include files for standalone build.
#
# Argument 1 is the top-level source directory, argument 2 the
# top-level build directory (they might be the same). If not set, they
# default to the current directory.
#
# Needs to be run after configuring and creating all generated headers.
# It's advisable to configure --with-perl --with-python, else you're
# likely to get errors from associated headers.
#
# No output if everything is OK, else compiler errors.
#
# src/tools/pginclude/headerscheck
# Copyright (c) 2009-2019, PostgreSQL Global Development Group
if [ -z "$1" ]; then
srcdir="."
else
srcdir="$1"
fi
if [ -z "$2" ]; then
builddir="."
else
builddir="$2"
fi
me=`basename $0`
# Pull some info from configure's results.
MGLOB="$builddir/src/Makefile.global"
CPPFLAGS=`sed -n 's/^CPPFLAGS[ ]*=[ ]*//p' "$MGLOB"`
CFLAGS=`sed -n 's/^CFLAGS[ ]*=[ ]*//p' "$MGLOB"`
CC=`sed -n 's/^CC[ ]*=[ ]*//p' "$MGLOB"`
PG_SYSROOT=`sed -n 's/^PG_SYSROOT[ ]*=[ ]*//p' "$MGLOB"`
perl_includespec=`sed -n 's/^perl_includespec[ ]*=[ ]*//p' "$MGLOB"`
python_includespec=`sed -n 's/^python_includespec[ ]*=[ ]*//p' "$MGLOB"`
# needed on Darwin
CPPFLAGS=`echo "$CPPFLAGS" | sed "s|\\\$(PG_SYSROOT)|$PG_SYSROOT|g"`
# (EXTRAFLAGS is not set here, but user can pass it in if need be.)
# Create temp directory.
tmp=`mktemp -d /tmp/$me.XXXXXX`
trap 'rm -rf $tmp' 0 1 2 3 15
# Scan all of src/ and contrib/ for header files.
for f in `cd "$srcdir" && find src contrib -name '*.h' -print`
do
# Ignore files that are unportable or intentionally not standalone.
# These files are platform-specific, and c.h will include the
# one that's relevant for our current platform anyway.
test "$f" = src/include/port/aix.h && continue
test "$f" = src/include/port/cygwin.h && continue
test "$f" = src/include/port/darwin.h && continue
test "$f" = src/include/port/freebsd.h && continue
test "$f" = src/include/port/hpux.h && continue
test "$f" = src/include/port/linux.h && continue
test "$f" = src/include/port/netbsd.h && continue
test "$f" = src/include/port/openbsd.h && continue
test "$f" = src/include/port/solaris.h && continue
test "$f" = src/include/port/win32.h && continue
# Additional Windows-specific headers.
test "$f" = src/include/port/win32_port.h && continue
test "$f" = src/include/port/win32/sys/socket.h && continue
test "$f" = src/include/port/win32_msvc/dirent.h && continue
test "$f" = src/port/pthread-win32.h && continue
# Likewise, these files are platform-specific, and the one
# relevant to our platform will be included by atomics.h.
test "$f" = src/include/port/atomics/arch-arm.h && continue
test "$f" = src/include/port/atomics/arch-hppa.h && continue
test "$f" = src/include/port/atomics/arch-ia64.h && continue
test "$f" = src/include/port/atomics/arch-ppc.h && continue
test "$f" = src/include/port/atomics/arch-x86.h && continue
test "$f" = src/include/port/atomics/fallback.h && continue
test "$f" = src/include/port/atomics/generic.h && continue
test "$f" = src/include/port/atomics/generic-acc.h && continue
test "$f" = src/include/port/atomics/generic-gcc.h && continue
test "$f" = src/include/port/atomics/generic-msvc.h && continue
test "$f" = src/include/port/atomics/generic-sunpro.h && continue
test "$f" = src/include/port/atomics/generic-xlc.h && continue
# rusagestub.h is also platform-specific, and will be included
# by utils/pg_rusage.h if necessary.
test "$f" = src/include/rusagestub.h && continue
# sepgsql.h depends on headers that aren't there on most platforms.
test "$f" = contrib/sepgsql/sepgsql.h && continue
# These files are not meant to be included standalone, because
# they contain lists that might have multiple use-cases.
test "$f" = src/include/access/rmgrlist.h && continue
test "$f" = src/include/parser/kwlist.h && continue
test "$f" = src/pl/plpgsql/src/pl_reserved_kwlist.h && continue
test "$f" = src/pl/plpgsql/src/pl_unreserved_kwlist.h && continue
test "$f" = src/interfaces/ecpg/preproc/c_kwlist.h && continue
test "$f" = src/interfaces/ecpg/preproc/ecpg_kwlist.h && continue
test "$f" = src/include/regex/regerrs.h && continue
test "$f" = src/pl/plpgsql/src/plerrcodes.h && continue
test "$f" = src/pl/plpython/spiexceptions.h && continue
test "$f" = src/pl/tcl/pltclerrcodes.h && continue
# We can't make these Bison output files compilable standalone
# without using "%code require", which old Bison versions lack.
# parser/gram.h will be included by parser/gramparse.h anyway.
test "$f" = src/include/parser/gram.h && continue
test "$f" = src/backend/parser/gram.h && continue
test "$f" = src/pl/plpgsql/src/pl_gram.h && continue
test "$f" = src/interfaces/ecpg/preproc/preproc.h && continue
# This produces a "no previous prototype" warning.
test "$f" = src/include/storage/checksum_impl.h && continue
# ppport.h is not under our control, so we can't make it standalone.
test "$f" = src/pl/plperl/ppport.h && continue
# regression.h is not actually C, but ECPG code.
test "$f" = src/interfaces/ecpg/test/regression.h && continue
# printf_hack.h produces "unused function" warnings.
test "$f" = src/interfaces/ecpg/test/printf_hack.h && continue
# OK, create .c file to include this .h file.
{
test "$f" != src/include/postgres_fe.h && echo '#include "postgres.h"'
echo "#include \"$f\""
} >$tmp/test.c
# Some subdirectories need extra -I switches.
case "$f" in
src/pl/plperl/*)
EXTRAINCLUDES="$perl_includespec" ;;
src/pl/plpython/*)
EXTRAINCLUDES="$python_includespec" ;;
src/interfaces/ecpg/*)
EXTRAINCLUDES="-I $builddir/src/interfaces/ecpg/include -I $srcdir/src/interfaces/ecpg/include" ;;
*)
EXTRAINCLUDES="" ;;
esac
# Run the test.
${CC:-gcc} $CPPFLAGS $CFLAGS -I $builddir -I $srcdir \
-I $builddir/src/include -I $srcdir/src/include \
-I $builddir/src/interfaces/libpq -I $srcdir/src/interfaces/libpq \
$EXTRAINCLUDES $EXTRAFLAGS -c $tmp/test.c -o $tmp/test.o
done