Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
blob: f9e37e1f28b88594391955fce0dccb571518b28c (plain)
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.13 2001/01/20 20:59:28 petere Exp $
-->

<sect2 id="dfunc">
 <title id="dfunc-title">Compiling and Linking Dynamically-Loaded Functions</title>

 <para>
  Before you are able to use your
  <productname>PostgreSQL</productname> extension function written in
  C they need to be compiled and linked in a special way in order to
  allow it to be dynamically loaded as needed by the server.  To be
  precise, a <firstterm>shared library</firstterm> needs to be created.
 </para>

 <para>
  For more information you should read the documentation of your
  operating system, in particular the manual pages for the C compiler,
  <command>cc</command>, and the link editor, <command>ld</command>.
  In addition, the <productname>PostgreSQL</productname> source code
  contains several working examples in the
  <filename>contrib</filename> directory.  If you rely on these
  examples you will make your modules dependent on the availability
  of the <productname>PostgreSQL</productname> source code, however.
 </para>

 <para>
  Creating shared libraries is generally analoguous to linking
  executables:  first the source files are compiled into object files,
  then the object files are linked together.  The object files need to
  be created as <firstterm>position-independent code</firstterm>
  (<acronym>PIC</acronym>), which conceptually means that they can be
  placed at an arbitrary location in memory when they are loaded by the
  executable.  (Object files intended for executables are not compiled
  that way.)  The command to link a shared library contains special
  flags to distinguish it from linking an executable. --- At least
  this is the theory.  On some systems the practice is much uglier.
 </para>

 <para>
  In the following examples we assume that your source code is in a
  file <filename>foo.c</filename> and we will create an shared library
  <filename>foo.so</filename>.  The intermediate object file will be
  called <filename>foo.o</filename> unless otherwise noted.  A shared
  library can contain more than one object file, but we only use one
  here.
 </para>

 <para>

<!--
  Note:  Reading GNU Libtool sources is generally a good way of figuring out
  this information.  The methods used within PostgreSQL source code are not
  necessarily ideal.
-->

  <variablelist>
   <varlistentry>
    <term><productname>BSD/OS</productname></term>
    <listitem>
     <para>
      The compiler flag to create <acronym>PIC</acronym> is
      <option>-fpic</option>.  The linker flag to create shared
      libraries is <option>-shared</option>.
<programlisting>
gcc -fpic -c foo.c
ld -shared -o foo.so foo.o
</programlisting>
      This is applicable as of version 4.0 of
      <productname>BSD/OS</productname>.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>FreeBSD</productname></term>
    <listitem>
     <para>
      The compiler flag to create <acronym>PIC</acronym> is
      <option>-fpic</option>.  To create shared libraries the compiler
      flag is <option>-shared</option>.
<programlisting>
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
      This is applicable as of version 3.0 of
      <productname>FreeBSD</productname>.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>HP-UX</productname></term>
    <listitem>
     <para>
      The compiler flag of the system compiler to create
      <acronym>PIC</acronym> is <option>+z</option>.  When using
      <productname>GCC</productname> it's <option>-fpic</option>. The
      linker flag for shared libraries is <option>-b</option>.  So
<programlisting>
cc +z -c foo.c
</programlisting>
      or
<programlisting>
gcc -fpic -c foo.c
</programlisting>
      and then
<programlisting>
ld -b -o foo.sl foo.o
</programlisting>
      <productname>HP-UX</productname> uses the extension
      <filename>.sl</filename> for shared libraries, unlike most other
      systems.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Irix</productname></term>
    <listitem>
     <para>
      <acronym>PIC</acronym> is the default, no special compiler
      options are necessary.  The linker option to produce shared
      libraries is <option>-shared</option>.
<programlisting>
cc -c foo.c
ld -shared -o foo.so foo.o
</programlisting>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Linux</productname></term>
    <listitem>
     <para>
      The compiler flag to create <acronym>PIC</acronym> is
      <option>-fpic</option>.  On some platforms in some situations
      <option>-fPIC</option> must be used if <option>-fpic</option>
      does not work.  Refer to the GCC manual for more information.
      The compiler flag to create a shared library is
      <option>-shared</option>.  A complete example looks like this:
<programlisting>
cc -fpic -c foo.c
cc -shared -o foo.so foo.o
</programlisting>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>NetBSD</productname></term>
    <listitem>
     <para>
      The compiler flag to create <acronym>PIC</acronym> is
      <option>-fpic</option>.  For <acronym>ELF</acronym> systems, the
      compiler with the flag <option>-shared</option> is used to link
      shared libraries.  On the older non-ELF systems, <literal>ld
      -Bshareable</literal> is used.
<programlisting>
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>OpenBSD</productname></term>
    <listitem>
     <para>
      The compiler flag to create <acronym>PIC</acronym> is
      <option>-fpic</option>.  <literal>ld -Bshareable</literal> is
      used to link shared libraries.
<programlisting>
gcc -fpic -c foo.c
ld -Bshareable -o foo.so foo.o
</programlisting>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term>Digital Unix/Tru64 UNIX</term>   

    <listitem>
     <para>
      <acronym>PIC</acronym> is the default, so the compilation command
      is the usual one.  <command>ld</command> with special options is
      used to do the linking:
<programlisting>
cc -c foo.c
ld -shared -expect_unresolved '*' -o foo.so foo.o
</programlisting>
      The same procedure is used with GCC instead of the system
      compiler; no special options are required.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Solaris</productname></term>
    <listitem>
     <para>
      The compiler flag to create <acronym>PIC</acronym> is
      <option>-KPIC</option> with the Sun compiler and
      <option>-fpic</option> with <productname>GCC</productname>.  To
      link shared libraries, the compiler option is
      <option>-G</option> with either compiler or alternatively
      <option>-shared</option> with <productname>GCC</productname>.
<programlisting>
cc -KPIC -c foo.c
cc -G -o foo.so foo.o
</programlisting>
      or
<programlisting>
gcc -fpic -c foo.c
gcc -G -o foo.so foo.o
</programlisting>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Unixware</productname></term>
    <listitem>
     <para>
      The compiler flag to create <acronym>PIC</acronym> is <option>-K
      PIC</option> with the SCO compiler and <option>-fpic</option>
      with <productname>GCC</productname>.  To link shared libraries,
      the compiler option is <option>-G</option> with the SCO compiler
      and <option>-shared</option> with
      <productname>GCC</productname>.
<programlisting>
cc -K PIC -c foo.c
cc -G -o foo.so foo.o
</programlisting>
      or
<programlisting>
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
     </para>
    </listitem>
   </varlistentry>

  </variablelist>
 </para>

 <tip>
  <para>
   If you want to package your extension modules for wide distribution
   you should consider using <ulink
   url="http://www.gnu.org/software/libtool/"><productname>GNU
   Libtool</productname></ulink> for building shared libraries.  It
   encapsulates the platform differences into a general and powerful
   interface.  Serious packaging also requires considerations about
   library versioning, symbol resolution methods, and other issues.
  </para>
 </tip>

 <para>
  The resulting shared library file can then be loaded into
  <productname>Postgres</productname>.  When specifying the file name
  to the <command>CREATE FUNCTION</command> command, one must give it
  the name of the shared library file (ending in
  <filename>.so</filename>) rather than the simple object file.

  <note>
   <para>
    Actually, <productname>Postgres</productname> does not care what
    you name the file as long as it is a shared library file.
   </para>
  </note>

  Paths given to the <command>CREATE FUNCTION</command> command must
  be absolute paths (i.e., start with <literal>/</literal>) that refer
  to directories visible on the machine on which the
  <productname>Postgres</productname> server is running.  Relative
  paths do in fact work, but are relative to the directory where the
  database resides (which is generally invisible to the frontend
  application).  Obviously, it makes no sense to make the path
  relative to the directory in which the user started the frontend
  application, since the server could be running on a completely
  different machine!  The user id the
  <productname>Postgres</productname> server runs as must be able to
  traverse the path given to the <command>CREATE FUNCTION</command>
  command and be able to read the shared library file.  (Making the
  file or a higher-level directory not readable and/or not executable
  by the <quote>postgres</quote> user is a common mistake.)
 </para>

<!--
Under AIX, object files are compiled normally but building the shared
library requires a couple of steps.  First, create the object file:
.nf
cc <other flags> -c foo.c
.fi
You must then create a symbol \*(lqexports\*(rq file for the object
file:
.nf
mkldexport foo.o `pwd` > foo.exp
.fi
Finally, you can create the shared library:
.nf
ld <other flags> -H512 -T512 -o foo.so -e _nostart \e
   -bI:.../lib/postgres.exp -bE:foo.exp foo.o \e
   -lm -lc 2>/dev/null
.fi
You should look at the Postgres User's Manual for an explanation of this
procedure.

  -->

</sect2>

<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->