Amit's complaint about unnecessary headers got me thinking about src/tools/pginclude. I think the the stuff in this directory is trying to do something useful, because I think extra #include directives that we don't need are a useful thing to eliminate. However, in practice the contents are very hard for anybody to use except maybe Bruce, who wrote it with his own environment in mind. On my system, any attempt to rerun pgcompinclude -- which is described as a prerequisite to running pgrminclude -- produces enormous numbers of bogus errors and warnings, both because of the attempt to call every defined macro with made-up arguments and because I configure with stuff like --with-includes=/opt/local/include which pgcompinclude knows nothing about.
I wonder if we can do better. The attached patch is the rest of a couple of hours of hacking on a "see whether all of our includes compile separately" project. Directions: 1. configure 2. go to src/tools/pginclude 3. make test-compile-include It strikes me that if we could make this robust enough to include in the buidlfarm, that would be good. And maybe we could then have a pgrminclude tool which is a bit smarter also, and something that anyone can easily run. I don't think pgrminclude should be part of the buildfarm, but being able to run it every release cycle with relatively minimal pain instead of every 5 years with extensive fallout seems like it would be a win. Thoughts? -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
diff --git a/src/tools/pginclude/Makefile b/src/tools/pginclude/Makefile new file mode 100644 index 0000000..b7e5e7e --- /dev/null +++ b/src/tools/pginclude/Makefile @@ -0,0 +1,15 @@ +subdir = src/tools/pginclude +top_builddir = ../../.. +include $(top_builddir)/src/Makefile.global + +include $(top_srcdir)/src/backend/common.mk + +test-compile-include: + rm -rf compile-includes + cd $(top_builddir) && $(subdir)/gen_compile_include.pl + $(MAKE) -C $(top_builddir)/src/backend generated-headers + $(MAKE) -C compile-includes + rm -rf compile-includes + +clean: + rm -rf compile-includes diff --git a/src/tools/pginclude/gen_compile_include.pl b/src/tools/pginclude/gen_compile_include.pl new file mode 100755 index 0000000..24f858d --- /dev/null +++ b/src/tools/pginclude/gen_compile_include.pl @@ -0,0 +1,163 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $include_prefix = 'src/include'; +my $output_dir = 'src/tools/pginclude/compile-includes'; + +# +# Some include files need to be excluded from the "does it compile separately?" +# test, either because they are platform-dependent stubs or because they aren't +# actually intended to compile separately. +# +my %exclude_include = map { $_ => 1 } qw( + access/rmgrlist.h + parser/gram.h + parser/kwlist.h + port/atomics + port/cygwin.h + port/win32.h + port/win32 + port/win32_msvc + regex/regerrs.h + storage/checksum_impl.h + rusagestub.h +); + +my $top_builddir = $output_dir; +$top_builddir =~ s@[^/]+@..@g; + +my @include_dir = (''); +my @include_file; +my @frontend_obj; +my @backend_obj; + +# +# Recurse through src/include and gather a list of all include files, excluding +# those mentioned in the exclusion list, above. +# +while (@include_dir) +{ + my $include_dir = shift @include_dir; + my $include_path = $include_prefix . ($include_dir eq '' ? '' + : '/' . $include_dir); + + opendir(my $directory, $include_path) + or die "could not opendir($include_path): $!"; + + while (my $entry = readdir($directory)) + { + next if ($entry eq '.' || $entry eq '..'); + + $entry = $include_dir eq '' ? $entry : $include_dir . '/' . $entry; + next if exists $exclude_include{$entry}; + my $path = $include_prefix . '/' . $entry; + if (-f $path) + { + push @include_file, $entry; + } + elsif (-d $path) + { + push @include_dir, $entry; + } + } +} + +# +# Create output directories. +# +mkdir($output_dir) or die "mkdir($output_dir): $!"; +mkdir($output_dir . '/backend') or die "mkdir($output_dir . '/backend'): $!"; +mkdir($output_dir . '/frontend') or die "mkdir($output_dir . '/frontend'): $!"; + +# +# For each include file, create a C file which includes either postgres.h +# (for frontend includes) or postgres_fe.h (for backend includes), the +# relevant header, and nothing else. +# +for my $include_file (@include_file) +{ + my $dotc_file = $include_file; + $dotc_file =~ s/\.h$/.c/; + $dotc_file =~ s@/@-@g; + my $is_frontend = ($include_file =~ m@^fe_utils/@); + + my $dotc_path = $output_dir . ($is_frontend ? '/frontend/' : '/backend/') + . $dotc_file; + my $base_include = $is_frontend ? 'postgres_fe.h' : 'postgres.h'; + $base_include = "postgres-fe.h" if $include_file =~ m@^fe_utils/@; + + write_file($dotc_path, <<EOM); +#include "postgres.h" + +#include "$include_file" +EOM + + # Record the name of the expected object file in the appropriate list. + my $object_file = $dotc_file; + $object_file =~ s/\.c$/.o/; + if ($is_frontend) + { + push @frontend_obj, $object_file; + } + else + { + push @backend_obj, $object_file; + } +} + +# +# Write a Makefile for the backend subdirectory. +# +my $backend_object_list = join(' ', @backend_obj); +write_file($output_dir . '/backend/Makefile', <<EOM); +subdir = $output_dir/backend +top_builddir = $top_builddir/.. +include \$(top_builddir)/src/Makefile.global + +OBJS = $backend_object_list + +include \$(top_srcdir)/src/backend/common.mk + +EOM + +# +# Write a Makefile for the frontend subdirectory. +# +my $frontend_object_list = join(' ', @frontend_obj); +write_file($output_dir . '/frontend/Makefile', <<EOM); +subdir = $output_dir/frontend +top_builddir = $top_builddir/.. +include \$(top_builddir)/src/Makefile.global + +override CPPFLAGS := -DFRONTEND -I\$(libpq_srcdir) \$(CPPFLAGS) + +OBJS = $frontend_object_list + +include \$(top_srcdir)/src/backend/common.mk + +EOM + +# +# Write a Makefile for the main output directory. +# +write_file($output_dir . '/Makefile', <<EOM); +subdir = $output_dir +top_builddir = $top_builddir +include \$(top_builddir)/src/Makefile.global + +SUBDIRS = frontend backend + +include \$(top_srcdir)/src/backend/common.mk + +EOM + +sub write_file +{ + my ($path, $content) = @_; + + open(my $file, '>', $path) or die "open($path): $!"; + print $file $content; + close($file); +}
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers