>>>>> "Andrew" == Andrew Gierth <and...@tao11.riddles.org.uk> writes:

Patch with docs (including an example) and Install.pm changes (blind).
I'll stick this in the open CF to see what cfbot thinks of it.

Anyone have any objection to putting this into 11beta if it works, as
well as 12devel?

-- 
Andrew (irc:RhodiumToad)

diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile
index ab7fef3979..46d26f8052 100644
--- a/contrib/hstore/Makefile
+++ b/contrib/hstore/Makefile
@@ -11,6 +11,8 @@ DATA = hstore--1.4.sql hstore--1.4--1.5.sql \
 	hstore--unpackaged--1.0.sql
 PGFILEDESC = "hstore - key/value pair data type"
 
+HEADERS = hstore.h
+
 REGRESS = hstore
 
 ifdef USE_PGXS
diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml
index 348ae71423..a3cb064131 100644
--- a/doc/src/sgml/extend.sgml
+++ b/doc/src/sgml/extend.sgml
@@ -1100,13 +1100,15 @@ include $(PGXS)
     and include the global <acronym>PGXS</acronym> makefile.
     Here is an example that builds an extension module named
     <literal>isbn_issn</literal>, consisting of a shared library containing
-    some C code, an extension control file, a SQL script, and a documentation
-    text file:
+    some C code, an extension control file, a SQL script, an include file
+    (only needed if other modules might need to access the extension functions
+    without going via SQL), and a documentation text file:
 <programlisting>
 MODULES = isbn_issn
 EXTENSION = isbn_issn
 DATA = isbn_issn--1.0.sql
 DOCS = README.isbn_issn
+HEADERS_isbn_issn = isbn_issn.h
 
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
@@ -1221,6 +1223,28 @@ include $(PGXS)
      </varlistentry>
 
      <varlistentry>
+      <term><varname>HEADERS</varname></term>
+      <listitem>
+       <para>
+        files to install under
+        <literal><replaceable>prefix</replaceable>/include/server/$MODULEDIR/$MODULE_big</literal>
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><varname>HEADERS_$MODULE</varname></term>
+      <listitem>
+       <para>
+        files to install under
+        <literal><replaceable>prefix</replaceable>/include/server/$MODULEDIR/$MODULE</literal>,
+        where <literal>$MODULE</literal> must be a module name used
+        in <literal>MODULES</literal> or <literal>MODULE_big</literal>
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><varname>SCRIPTS</varname></term>
       <listitem>
        <para>
diff --git a/src/makefiles/pgxs.mk b/src/makefiles/pgxs.mk
index bfae02f90c..80c02a08d0 100644
--- a/src/makefiles/pgxs.mk
+++ b/src/makefiles/pgxs.mk
@@ -38,6 +38,10 @@
 #   SCRIPTS -- script files (not binaries) to install into $PREFIX/bin
 #   SCRIPTS_built -- script files (not binaries) to install into $PREFIX/bin,
 #     which need to be built first
+#   HEADERS -- files to install into $(includedir_server)/$MODULEDIR/$MODULE_big
+#   HEADERS_$(MODULE) -- files to install into
+#     $(includedir_server)/$MODULEDIR/$MODULE; the value of $MODULE must be
+#     listed in MODULES or MODULE_big
 #   REGRESS -- list of regression test cases (without suffix)
 #   REGRESS_OPTS -- additional switches to pass to pg_regress
 #   NO_INSTALLCHECK -- don't define an installcheck target, useful e.g. if
@@ -94,13 +98,16 @@ endif
 ifdef MODULEDIR
 datamoduledir := $(MODULEDIR)
 docmoduledir := $(MODULEDIR)
+incmoduledir := $(MODULEDIR)
 else
 ifdef EXTENSION
 datamoduledir := extension
 docmoduledir := extension
+incmoduledir := extension
 else
 datamoduledir := contrib
 docmoduledir := contrib
+incmoduledir := contrib
 endif
 endif
 
@@ -108,6 +115,41 @@ ifdef PG_CPPFLAGS
 override CPPFLAGS := $(PG_CPPFLAGS) $(CPPFLAGS)
 endif
 
+HEADER_alldirs := $(patsubst HEADERS_%,%,$(filter HEADERS_%, $(.VARIABLES)))
+
+# HEADERS is an error in the absence of MODULE_big to provide a dir name
+ifdef MODULE_big
+HEADER_dirs := $(MODULE_big)
+ifdef HEADERS
+HEADERS_$(MODULE_big) = $(HEADERS)
+endif
+else
+ifdef HEADERS
+$(error HEADERS requires MODULE_big to be set)
+endif
+HEADER_dirs := $(filter $(MODULES),$(HEADER_alldirs))
+endif
+
+# HEADERS_foo requires that "foo" is in MODULES as a sanity check
+ifneq ($(filter-out $(HEADER_dirs),$(HEADER_alldirs)),)
+$(error $(patsubst %,HEADERS_%,$(filter-out $(HEADER_dirs),$(HEADER_alldirs))) defined with no module)
+endif
+
+# Functions for generating install/uninstall commands; the blank lines
+# before the "endef" are required, don't lose them
+# $(call install_headers,dir,headers)
+define install_headers
+$(MKDIR_P) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/'
+$(INSTALL_DATA) $(addprefix $(srcdir)/, $(2)) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/'
+
+endef
+# $(call uninstall_headers,dir,headers)
+define uninstall_headers
+rm -f $(addprefix '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)'/, $(notdir $(2)))
+
+endef
+
+
 all: $(PROGRAM) $(DATA_built) $(SCRIPTS_built) $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .control, $(EXTENSION))
 
 ifeq ($(with_llvm), yes)
@@ -154,6 +196,9 @@ endif # SCRIPTS
 ifdef SCRIPTS_built
 	$(INSTALL_SCRIPT) $(SCRIPTS_built) '$(DESTDIR)$(bindir)/'
 endif # SCRIPTS_built
+ifneq ($(strip $(HEADER_dirs)),)
+	$(foreach dir,$(HEADER_dirs),$(call install_headers,$(dir),$(HEADERS_$(dir))))
+endif # HEADERS
 ifdef MODULE_big
 ifeq ($(with_llvm), yes)
 	$(call install_llvm_module,$(MODULE_big),$(OBJS))
@@ -218,6 +263,9 @@ endif
 ifdef SCRIPTS_built
 	rm -f $(addprefix '$(DESTDIR)$(bindir)'/, $(SCRIPTS_built))
 endif
+ifneq ($(strip $(HEADER_dirs)),)
+	$(foreach dir,$(HEADER_dirs),$(call uninstall_headers,$(dir),$(HEADERS_$(dir))))
+endif # HEADERS
 
 ifdef MODULE_big
 ifeq ($(with_llvm), yes)
diff --git a/src/tools/msvc/Install.pm b/src/tools/msvc/Install.pm
index 429608fde6..0f4b464bae 100644
--- a/src/tools/msvc/Install.pm
+++ b/src/tools/msvc/Install.pm
@@ -554,6 +554,48 @@ sub CopySubdirFiles
 		}
 	}
 
+	{
+		$flist = '';
+		if ($mf =~ /^HEADERS\s*=\s*(.*)$/m) { $flist .= $1 }
+		my @modlist = ();
+		my %fmodlist = ();
+		while ($mf =~ /^HEADERS_([^\s=]+)\s*=\s*(.*)$/mg) { $fmodlist{$1} .= $2 }
+
+		if ($mf =~ /^MODULE_big\s*=\s*(.*)$/m)
+		{
+			push @modlist, $1;
+			if ($flist ne '')
+			{
+				$fmodlist{$1} = $flist;
+				$flist = '';
+			}
+		}
+		elsif ($mf =~ /^MODULES\s*=\s*(.*)$/m)
+		{
+			push @modlist, split /\s+/, $1;
+		}
+
+		croak "HEADERS requires MODULE_big in $subdir $module"
+		  if $flist ne '';
+
+		foreach my $mod (keys %fmodlist)
+		{
+			croak "HEADERS_$mod for unknown module in $subdir $module"
+			  unless grep { $_ eq $mod } @modlist;
+			$flist = ParseAndCleanRule($fmodlist{$mod}, $mf);
+			EnsureDirectories($target,
+							  "include/server/$moduledir",
+							  "include/server/$moduledir/$mod");
+			foreach my $f (split /\s+/, $flist)
+			{
+				lcopy("$subdir/$module/$f",
+					  "$target/include/server/$mod/" . basename($f))
+				  || croak("Could not copy file $f in $subdir $module");
+				print '.';
+			}
+		}
+	}
+
 	$flist = '';
 	if ($mf =~ /^DOCS\s*=\s*(.*)$/mg) { $flist .= $1 }
 	if ($flist ne '')

Reply via email to