postgresql/doc/src/sgml/dfunc.sgml

346 lines
11 KiB
Plaintext
Raw Normal View History

<!--
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.21 2002/08/26 23:22:47 momjian 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 functions written in
C, they must be compiled and linked in a special way to produce a file
that can be dynamically loaded 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>
2001-11-12 20:19:39 +01:00
<indexterm><primary>PIC</></>
2002-01-20 23:19:57 +01:00
Creating shared libraries is generally analogous 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 usually 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
2002-01-07 03:29:15 +01:00
file <filename>foo.c</filename> and we will create a 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
<productname>PostgreSQL</> source code are not
necessarily ideal.
-->
<variablelist>
<varlistentry>
<term><productname>BSD/OS</productname></term>
2001-11-12 20:19:39 +01:00
<indexterm><primary>BSD/OS</></>
<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>
2001-11-12 20:19:39 +01:00
<indexterm><primary>FreeBSD</></>
<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>
1998-03-01 09:16:16 +01:00
<varlistentry>
<term><productname>HP-UX</productname></term>
2001-11-12 20:19:39 +01:00
<indexterm><primary>HP-UX</></>
<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>
1998-03-01 09:16:16 +01:00
<varlistentry>
2002-01-07 03:29:15 +01:00
<term><productname>IRIX</productname></term>
<indexterm><primary>IRIX</></>
<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>
2001-11-12 20:19:39 +01:00
<indexterm><primary>Linux</></>
<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>
2001-11-12 20:19:39 +01:00
<indexterm><primary>NetBSD</></>
<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>
2001-11-12 20:19:39 +01:00
<indexterm><primary>OpenBSD</></>
<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><productname>OS X</productname></term>
<indexterm><primary>OS X</></>
<listitem>
<para>
Here is a sample. It assumes the developer tools are installed.
<programlisting>
cc -c foo.c
cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><productname>Solaris</productname></term>
2001-11-12 20:19:39 +01:00
<indexterm><primary>Solaris</></>
<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>
1998-03-01 09:16:16 +01:00
2001-11-12 20:19:39 +01:00
<varlistentry>
<term>Tru64 UNIX</term>
<indexterm><primary>Tru64 UNIX</></>
<indexterm><primary>Digital UNIX</><see>Tru64 UNIX</></>
<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>UnixWare</productname></term>
<indexterm><primary>UnixWare</></>
<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>
1998-03-01 09:16:16 +01:00
<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>
1998-03-01 09:16:16 +01:00
<para>
The resulting shared library file can then be loaded into
<productname>PostgreSQL</productname>. When specifying the file name
to the <command>CREATE FUNCTION</command> command, one must give it
the name of the shared library file, not the intermediate object file.
Note that the system's standard shared-library extension (usually
<literal>.so</literal> or <literal>.sl</literal>) can be omitted from
the <command>CREATE FUNCTION</command> command, and normally should
be omitted for best portability.
</para>
<para>
Refer back to <xref linkend="xfunc-c-dynload"> about where the
server expects to find the shared library files.
</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 <citetitle>PostgreSQL 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-tabs-mode:nil
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/share/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->