]> granicus.if.org Git - postgresql/commitdiff
Provide for contrib and pgxs modules to install include files.
authorAndrew Gierth <rhodiumtoad@postgresql.org>
Tue, 31 Jul 2018 18:58:39 +0000 (19:58 +0100)
committerAndrew Gierth <rhodiumtoad@postgresql.org>
Tue, 31 Jul 2018 18:58:39 +0000 (19:58 +0100)
This allows out-of-tree PLs and similar code to get access to
definitions needed to work with extension data types.

The following existing modules now install headers: contrib/cube,
contrib/hstore, contrib/isn, contrib/ltree, contrib/seg.

Discussion: https://postgr.es/m/87y3euomjh.fsf%40news-spur.riddles.org.uk

contrib/cube/Makefile
contrib/hstore/Makefile
contrib/isn/Makefile
contrib/ltree/Makefile
contrib/seg/Makefile
doc/src/sgml/extend.sgml
src/makefiles/pgxs.mk
src/tools/msvc/Install.pm

index accb7d28a39f73c69c338457605b636380e4090f..a679ac626eea3d9e28b443314ac6891c29a4a199 100644 (file)
@@ -9,6 +9,8 @@ DATA = cube--1.2.sql cube--1.2--1.3.sql cube--1.3--1.4.sql \
        cube--unpackaged--1.0.sql
 PGFILEDESC = "cube - multidimensional cube data type"
 
+HEADERS = cubedata.h
+
 REGRESS = cube
 
 EXTRA_CLEAN = y.tab.c y.tab.h
index ab7fef3979385d71faa6b64b70fdd804e7d15af4..46d26f8052d869278cc15979c6749142019011d1 100644 (file)
@@ -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
index ab6b175f9a7d8e64a14291824a962922dd23b61a..c3600dac300ea38faa141a26a09239b32e332231 100644 (file)
@@ -7,6 +7,9 @@ DATA = isn--1.1.sql isn--1.1--1.2.sql \
        isn--1.0--1.1.sql isn--unpackaged--1.0.sql
 PGFILEDESC = "isn - data types for international product numbering standards"
 
+# the other .h files are data tables, we don't install those
+HEADERS_isn = isn.h
+
 REGRESS = isn
 
 ifdef USE_PGXS
index c101603e6cdd11cee7816cde5045b71226f1c010..416c8da3127b1f937ad7da5bc1bc2ddadccaf06c 100644 (file)
@@ -9,6 +9,8 @@ EXTENSION = ltree
 DATA = ltree--1.1.sql ltree--1.0--1.1.sql ltree--unpackaged--1.0.sql
 PGFILEDESC = "ltree - hierarchical label data type"
 
+HEADERS = ltree.h
+
 REGRESS = ltree
 
 ifdef USE_PGXS
index 41270f84f626cb710f92c59b67c3dcc5bcc2b9b4..62b658e724353d97e7d45773c634d885c7bc5c73 100644 (file)
@@ -8,6 +8,8 @@ DATA = seg--1.1.sql seg--1.1--1.2.sql seg--1.2--1.3.sql \
        seg--1.0--1.1.sql seg--unpackaged--1.0.sql
 PGFILEDESC = "seg - line segment data type"
 
+HEADERS = segdata.h
+
 REGRESS = seg
 
 EXTRA_CLEAN = y.tab.c y.tab.h
index 348ae71423f4ec9c32452c302fb07f1e271c668c..a3cb064131b9e48adc3e9b26f24b487a032b46ef 100644 (file)
@@ -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)
@@ -1220,6 +1222,28 @@ include $(PGXS)
       </listitem>
      </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>
index bfae02f90ce773c02ccd06a7a306893ad1e42e14..158581b3f50a7b89222308d2ed008e53fc7bdcb4 100644 (file)
 #   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,43 @@ 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
+ifdef HEADERS
+HEADER_dirs := $(MODULE_big)
+HEADERS_$(MODULE_big) = $(HEADERS)
+else
+HEADER_dirs := $(filter $(MODULE_big),$(HEADER_alldirs))
+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 +198,9 @@ endif # SCRIPTS
 ifdef SCRIPTS_built
        $(INSTALL_SCRIPT) $(SCRIPTS_built) '$(DESTDIR)$(bindir)/'
 endif # SCRIPTS_built
+ifneq ($(strip $(HEADER_dirs)),)
+       $(foreach dir,$(HEADER_dirs),$(if $(HEADERS_$(dir)),$(call install_headers,$(dir),$(HEADERS_$(dir)))))
+endif # HEADERS
 ifdef MODULE_big
 ifeq ($(with_llvm), yes)
        $(call install_llvm_module,$(MODULE_big),$(OBJS))
@@ -218,6 +265,9 @@ endif
 ifdef SCRIPTS_built
        rm -f $(addprefix '$(DESTDIR)$(bindir)'/, $(SCRIPTS_built))
 endif
+ifneq ($(strip $(HEADER_dirs)),)
+       $(foreach dir,$(HEADER_dirs),$(if $(HEADERS_$(dir)),$(call uninstall_headers,$(dir),$(HEADERS_$(dir)))))
+endif # HEADERS
 
 ifdef MODULE_big
 ifeq ($(with_llvm), yes)
index 429608fde61b00037965a2574747a2ee7c2bbda9..60b5639df85724a4499fe2745b69e3121a62c0ee 100644 (file)
@@ -554,6 +554,49 @@ 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", "include/server",
+                                                         "include/server/$moduledir",
+                                                         "include/server/$moduledir/$mod");
+                       foreach my $f (split /\s+/, $flist)
+                       {
+                               lcopy("$subdir/$module/$f",
+                                         "$target/include/server/$moduledir/$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 '')