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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.18. Extension Building Infrastructure</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension" /><link rel="next" href="triggers.html" title="Chapter 39. Triggers" /></head><body id="docContent" class="container-fluid col-10"><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.18. Extension Building Infrastructure</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym xmlns="http://www.w3.org/1999/xhtml" class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 14.5 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="triggers.html" title="Chapter 39. Triggers">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="EXTEND-PGXS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.18. Extension Building Infrastructure</h2></div></div></div><a id="id-1.8.3.21.2" class="indexterm"></a><p>
If you are thinking about distributing your
<span class="productname">PostgreSQL</span> extension modules, setting up a
portable build system for them can be fairly difficult. Therefore
the <span class="productname">PostgreSQL</span> installation provides a build
infrastructure for extensions, called <acronym class="acronym">PGXS</acronym>, so
that simple extension modules can be built simply against an
already installed server. <acronym class="acronym">PGXS</acronym> is mainly intended
for extensions that include C code, although it can be used for
pure-SQL extensions too. Note that <acronym class="acronym">PGXS</acronym> is not
intended to be a universal build system framework that can be used
to build any software interfacing to <span class="productname">PostgreSQL</span>;
it simply automates common build rules for simple server extension
modules. For more complicated packages, you might need to write your
own build system.
</p><p>
To use the <acronym class="acronym">PGXS</acronym> infrastructure for your extension,
you must write a simple makefile.
In the makefile, you need to set some variables
and include the global <acronym class="acronym">PGXS</acronym> makefile.
Here is an example that builds an extension module named
<code class="literal">isbn_issn</code>, consisting of a shared library containing
some C code, an extension control file, an 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:
</p><pre class="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)
include $(PGXS)
</pre><p>
The last three lines should always be the same. Earlier in the
file, you assign variables or add custom
<span class="application">make</span> rules.
</p><p>
Set one of these three variables to specify what is built:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">MODULES</code></span></dt><dd><p>
list of shared-library objects to be built from source files with same
stem (do not include library suffixes in this list)
</p></dd><dt><span class="term"><code class="varname">MODULE_big</code></span></dt><dd><p>
a shared library to build from multiple source files
(list object files in <code class="varname">OBJS</code>)
</p></dd><dt><span class="term"><code class="varname">PROGRAM</code></span></dt><dd><p>
an executable program to build
(list object files in <code class="varname">OBJS</code>)
</p></dd></dl></div><p>
The following variables can also be set:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">EXTENSION</code></span></dt><dd><p>
extension name(s); for each name you must provide an
<code class="literal"><em class="replaceable"><code>extension</code></em>.control</code> file,
which will be installed into
<code class="literal"><em class="replaceable"><code>prefix</code></em>/share/extension</code>
</p></dd><dt><span class="term"><code class="varname">MODULEDIR</code></span></dt><dd><p>
subdirectory of <code class="literal"><em class="replaceable"><code>prefix</code></em>/share</code>
into which DATA and DOCS files should be installed
(if not set, default is <code class="literal">extension</code> if
<code class="varname">EXTENSION</code> is set,
or <code class="literal">contrib</code> if not)
</p></dd><dt><span class="term"><code class="varname">DATA</code></span></dt><dd><p>
random files to install into <code class="literal"><em class="replaceable"><code>prefix</code></em>/share/$MODULEDIR</code>
</p></dd><dt><span class="term"><code class="varname">DATA_built</code></span></dt><dd><p>
random files to install into
<code class="literal"><em class="replaceable"><code>prefix</code></em>/share/$MODULEDIR</code>,
which need to be built first
</p></dd><dt><span class="term"><code class="varname">DATA_TSEARCH</code></span></dt><dd><p>
random files to install under
<code class="literal"><em class="replaceable"><code>prefix</code></em>/share/tsearch_data</code>
</p></dd><dt><span class="term"><code class="varname">DOCS</code></span></dt><dd><p>
random files to install under
<code class="literal"><em class="replaceable"><code>prefix</code></em>/doc/$MODULEDIR</code>
</p></dd><dt><span class="term"><code class="varname">HEADERS</code><br /></span><span class="term"><code class="varname">HEADERS_built</code></span></dt><dd><p>
Files to (optionally build and) install under
<code class="literal"><em class="replaceable"><code>prefix</code></em>/include/server/$MODULEDIR/$MODULE_big</code>.
</p><p>
Unlike <code class="literal">DATA_built</code>, files in <code class="literal">HEADERS_built</code>
are not removed by the <code class="literal">clean</code> target; if you want them removed,
also add them to <code class="literal">EXTRA_CLEAN</code> or add your own rules to do it.
</p></dd><dt><span class="term"><code class="varname">HEADERS_$MODULE</code><br /></span><span class="term"><code class="varname">HEADERS_built_$MODULE</code></span></dt><dd><p>
Files to install (after building if specified) under
<code class="literal"><em class="replaceable"><code>prefix</code></em>/include/server/$MODULEDIR/$MODULE</code>,
where <code class="literal">$MODULE</code> must be a module name used
in <code class="literal">MODULES</code> or <code class="literal">MODULE_big</code>.
</p><p>
Unlike <code class="literal">DATA_built</code>, files in <code class="literal">HEADERS_built_$MODULE</code>
are not removed by the <code class="literal">clean</code> target; if you want them removed,
also add them to <code class="literal">EXTRA_CLEAN</code> or add your own rules to do it.
</p><p>
It is legal to use both variables for the same module, or any
combination, unless you have two module names in the
<code class="literal">MODULES</code> list that differ only by the presence of a
prefix <code class="literal">built_</code>, which would cause ambiguity. In
that (hopefully unlikely) case, you should use only the
<code class="literal">HEADERS_built_$MODULE</code> variables.
</p></dd><dt><span class="term"><code class="varname">SCRIPTS</code></span></dt><dd><p>
script files (not binaries) to install into
<code class="literal"><em class="replaceable"><code>prefix</code></em>/bin</code>
</p></dd><dt><span class="term"><code class="varname">SCRIPTS_built</code></span></dt><dd><p>
script files (not binaries) to install into
<code class="literal"><em class="replaceable"><code>prefix</code></em>/bin</code>,
which need to be built first
</p></dd><dt><span class="term"><code class="varname">REGRESS</code></span></dt><dd><p>
list of regression test cases (without suffix), see below
</p></dd><dt><span class="term"><code class="varname">REGRESS_OPTS</code></span></dt><dd><p>
additional switches to pass to <span class="application">pg_regress</span>
</p></dd><dt><span class="term"><code class="varname">ISOLATION</code></span></dt><dd><p>
list of isolation test cases, see below for more details
</p></dd><dt><span class="term"><code class="varname">ISOLATION_OPTS</code></span></dt><dd><p>
additional switches to pass to
<span class="application">pg_isolation_regress</span>
</p></dd><dt><span class="term"><code class="varname">TAP_TESTS</code></span></dt><dd><p>
switch defining if TAP tests need to be run, see below
</p></dd><dt><span class="term"><code class="varname">NO_INSTALL</code></span></dt><dd><p>
don't define an <code class="literal">install</code> target, useful for test
modules that don't need their build products to be installed
</p></dd><dt><span class="term"><code class="varname">NO_INSTALLCHECK</code></span></dt><dd><p>
don't define an <code class="literal">installcheck</code> target, useful e.g., if tests require special configuration, or don't use <span class="application">pg_regress</span>
</p></dd><dt><span class="term"><code class="varname">EXTRA_CLEAN</code></span></dt><dd><p>
extra files to remove in <code class="literal">make clean</code>
</p></dd><dt><span class="term"><code class="varname">PG_CPPFLAGS</code></span></dt><dd><p>
will be prepended to <code class="varname">CPPFLAGS</code>
</p></dd><dt><span class="term"><code class="varname">PG_CFLAGS</code></span></dt><dd><p>
will be appended to <code class="varname">CFLAGS</code>
</p></dd><dt><span class="term"><code class="varname">PG_CXXFLAGS</code></span></dt><dd><p>
will be appended to <code class="varname">CXXFLAGS</code>
</p></dd><dt><span class="term"><code class="varname">PG_LDFLAGS</code></span></dt><dd><p>
will be prepended to <code class="varname">LDFLAGS</code>
</p></dd><dt><span class="term"><code class="varname">PG_LIBS</code></span></dt><dd><p>
will be added to <code class="varname">PROGRAM</code> link line
</p></dd><dt><span class="term"><code class="varname">SHLIB_LINK</code></span></dt><dd><p>
will be added to <code class="varname">MODULE_big</code> link line
</p></dd><dt><span class="term"><code class="varname">PG_CONFIG</code></span></dt><dd><p>
path to <span class="application">pg_config</span> program for the
<span class="productname">PostgreSQL</span> installation to build against
(typically just <code class="literal">pg_config</code> to use the first one in your
<code class="varname">PATH</code>)
</p></dd></dl></div><p>
</p><p>
Put this makefile as <code class="literal">Makefile</code> in the directory
which holds your extension. Then you can do
<code class="literal">make</code> to compile, and then <code class="literal">make
install</code> to install your module. By default, the extension is
compiled and installed for the
<span class="productname">PostgreSQL</span> installation that
corresponds to the first <code class="command">pg_config</code> program
found in your <code class="varname">PATH</code>. You can use a different installation by
setting <code class="varname">PG_CONFIG</code> to point to its
<code class="command">pg_config</code> program, either within the makefile
or on the <code class="literal">make</code> command line.
</p><p>
You can also run <code class="literal">make</code> in a directory outside the source
tree of your extension, if you want to keep the build directory separate.
This procedure is also called a
<a id="id-1.8.3.21.7.2" class="indexterm"></a><em class="firstterm">VPATH</em>
build. Here's how:
</p><pre class="programlisting">
mkdir build_dir
cd build_dir
make -f /path/to/extension/source/tree/Makefile
make -f /path/to/extension/source/tree/Makefile install
</pre><p>
</p><p>
Alternatively, you can set up a directory for a VPATH build in a similar
way to how it is done for the core code. One way to do this is using the
core script <code class="filename">config/prep_buildtree</code>. Once this has been done
you can build by setting the <code class="literal">make</code> variable
<code class="varname">VPATH</code> like this:
</p><pre class="programlisting">
make VPATH=/path/to/extension/source/tree
make VPATH=/path/to/extension/source/tree install
</pre><p>
This procedure can work with a greater variety of directory layouts.
</p><p>
The scripts listed in the <code class="varname">REGRESS</code> variable are used for
regression testing of your module, which can be invoked by <code class="literal">make
installcheck</code> after doing <code class="literal">make install</code>. For this to
work you must have a running <span class="productname">PostgreSQL</span> server.
The script files listed in <code class="varname">REGRESS</code> must appear in a
subdirectory named <code class="literal">sql/</code> in your extension's directory.
These files must have extension <code class="literal">.sql</code>, which must not be
included in the <code class="varname">REGRESS</code> list in the makefile. For each
test there should also be a file containing the expected output in a
subdirectory named <code class="literal">expected/</code>, with the same stem and
extension <code class="literal">.out</code>. <code class="literal">make installcheck</code>
executes each test script with <span class="application">psql</span>, and compares the
resulting output to the matching expected file. Any differences will be
written to the file <code class="literal">regression.diffs</code> in <code class="command">diff
-c</code> format. Note that trying to run a test that is missing its
expected file will be reported as <span class="quote">“<span class="quote">trouble</span>”</span>, so make sure you
have all expected files.
</p><p>
The scripts listed in the <code class="varname">ISOLATION</code> variable are used
for tests stressing behavior of concurrent session with your module, which
can be invoked by <code class="literal">make installcheck</code> after doing
<code class="literal">make install</code>. For this to work you must have a
running <span class="productname">PostgreSQL</span> server. The script files
listed in <code class="varname">ISOLATION</code> must appear in a subdirectory
named <code class="literal">specs/</code> in your extension's directory. These files
must have extension <code class="literal">.spec</code>, which must not be included
in the <code class="varname">ISOLATION</code> list in the makefile. For each test
there should also be a file containing the expected output in a
subdirectory named <code class="literal">expected/</code>, with the same stem and
extension <code class="literal">.out</code>. <code class="literal">make installcheck</code>
executes each test script, and compares the resulting output to the
matching expected file. Any differences will be written to the file
<code class="literal">output_iso/regression.diffs</code> in
<code class="command">diff -c</code> format. Note that trying to run a test that is
missing its expected file will be reported as <span class="quote">“<span class="quote">trouble</span>”</span>, so
make sure you have all expected files.
</p><p>
<code class="literal">TAP_TESTS</code> enables the use of TAP tests. Data from each
run is present in a subdirectory named <code class="literal">tmp_check/</code>.
See also <a class="xref" href="regress-tap.html" title="33.4. TAP Tests">Section 33.4</a> for more details.
</p><div class="tip"><h3 class="title">Tip</h3><p>
The easiest way to create the expected files is to create empty files,
then do a test run (which will of course report differences). Inspect
the actual result files found in the <code class="literal">results/</code>
directory (for tests in <code class="literal">REGRESS</code>), or
<code class="literal">output_iso/results/</code> directory (for tests in
<code class="literal">ISOLATION</code>), then copy them to
<code class="literal">expected/</code> if they match what you expect from the test.
</p></div></div><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navfooter"><hr></hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="triggers.html" title="Chapter 39. Triggers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.17. Packaging Related Objects into an Extension </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 14.5 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 39. Triggers</td></tr></table></div></body></html>
|