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)
</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>
# 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
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
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)
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))
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)
}
}
+ {
+ $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 '')