summaryrefslogtreecommitdiffstats
path: root/src/tools/pginclude/headerscheck
blob: f8b0674a661803ee95ddfe7f6d04e620aa60e7e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/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-2022, 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/include/port/win32_msvc/utime.h && continue
	test "$f" = src/include/port/win32ntdll.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

	# 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/include/tcop/cmdtaglist.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

	# Also not meant to be included standalone.
	test "$f" = src/include/common/unicode_combining_table.h && continue
	test "$f" = src/include/common/unicode_east_asian_fw_table.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