postgresql/doc/src/sgml/dfunc.sgml

410 lines
13 KiB
Plaintext
Raw Normal View History

<!--
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.11 2000/09/29 20:21:33 petere Exp $
-->
<chapter id="dfunc">
<title id="dfunc-title">Linking Dynamically-Loaded Functions</title>
1998-03-01 09:16:16 +01:00
1999-10-09 04:26:52 +02:00
<para>
After you have created and registered a user-defined
1999-10-09 04:26:52 +02:00
function, your work is essentially done.
<productname>Postgres</productname>,
however, must load the object code
(e.g., a <literal>.o</literal> file, or
a shared library) that implements your function. As
1999-10-09 04:26:52 +02:00
previously mentioned, <productname>Postgres</productname>
loads your code at
runtime, as required. In order to allow your code to be
dynamically loaded, you may have to compile and
link-edit it in a special way. This section briefly
describes how to perform the compilation and
link-editing required before you can load your user-defined
1999-10-09 04:26:52 +02:00
functions into a running <productname>Postgres</productname> server.
</para>
<!--
<tip>
<para>
The old <productname>Postgres</productname> dynamic
loading mechanism required
in-depth knowledge in terms of executable format, placement
and alignment of executable instructions within memory, etc.
on the part of the person writing the dynamic loader. Such
loaders tended to be slow and buggy. As of Version 4.2, the
1999-10-09 04:26:52 +02:00
<productname>Postgres</productname> dynamic loading mechanism
has been rewritten to use
the dynamic loading mechanism provided by the operating
system. This approach is generally faster, more reliable and
more portable than our previous dynamic loading mechanism.
The reason for this is that nearly all modern versions of
Unix use a dynamic loading mechanism to implement shared
libraries and must therefore provide a fast and reliable
mechanism. On the other hand, the object file must be
1999-10-09 04:26:52 +02:00
postprocessed a bit before it can be loaded into
<productname>Postgres</productname>. We
hope that the large increase in speed and reliability will
make up for the slight decrease in convenience.
</para>
</tip>
</para>
-->
<para>
You should expect to read (and reread, and re-reread) the
manual pages for the C compiler, cc(1), and the link
editor, ld(1), if you have specific questions. In
addition, the contrib area (<filename>PGROOT/contrib</filename>)
and the regression test suites in the directory
<filename>PGROOT/src/test/regress</filename> contain several
working examples of this process. If you copy an example then
you should not have any problems.
</para>
<para>
The following terminology will be used below:
<itemizedlist>
<listitem>
<para>
<firstterm>Dynamic loading</firstterm>
is what <productname>Postgres</productname> does to an object file. The
object file is copied into the running <productname>Postgres</productname>
server and the functions and variables within the
file are made available to the functions within
the <productname>Postgres</productname> process.
<productname>Postgres</productname> does this using
the dynamic loading mechanism provided by the
operating system.
</para>
</listitem>
<listitem>
<para>
<firstterm>Loading and link editing</firstterm>
is what you do to an object file in order to produce
another kind of object file (e.g., an executable
program or a shared library). You perform
this using the link editing program, ld(1).
</para>
</listitem>
</itemizedlist>
</para>
1998-03-01 09:16:16 +01:00
<para>
The following general restrictions and notes also apply
to the discussion below:
<itemizedlist>
<listitem>
<para>
Paths given to the create function command must be
absolute paths (i.e., start with "/") that refer to
directories visible on the machine on which the
<productname>Postgres</productname> server is running.
1998-03-01 09:16:16 +01:00
<tip>
<para>
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!
</para>
</tip>
</para>
</listitem>
1998-03-01 09:16:16 +01:00
<listitem>
<para>
The <productname>Postgres</productname> user must be able to traverse the path
given to the create function command and be able to
read the object file. This is because the <productname>Postgres</productname>
server runs as the <productname>Postgres</productname> user, not as the user
who starts up the frontend process. (Making the
file or a higher-level directory unreadable and/or
unexecutable by the "postgres" user is an extremely
common mistake.)
</para>
</listitem>
<listitem>
<para>
Symbol names defined within object files must not
conflict with each other or with symbols defined in
<productname>Postgres</productname>.
</para>
</listitem>
<listitem>
<para>
The GNU C compiler usually does not provide the special
options that are required to use the operating
system's dynamic loader interface. In such cases,
the C compiler that comes with the operating system
must be used.
</para>
</listitem>
</itemizedlist>
</para>
<sect1 id="dload-linux">
<title>Linux</title>
<para>
Under Linux ELF, object files can be generated by specifying the compiler
flag -fpic.
</para>
<para>
For example,
<programlisting>
# simple Linux example
% cc -fpic -c <replaceable>foo.c</replaceable>
</programlisting>
produces an object file called <replaceable>foo.o</replaceable>
that can then be
dynamically loaded into <productname>Postgres</productname>.
No additional loading or link-editing must be performed.
</para>
</sect1>
<!--
<sect1 id="dload-ultrix">
<title><acronym>ULTRIX</acronym></title>
<para>
It is very easy to build dynamically-loaded object
files under ULTRIX. ULTRIX does not have any shared library
mechanism and hence does not place any restrictions on
the dynamic loader interface. On the other
hand, we had to (re)write a non-portable dynamic loader
ourselves and could not use true shared libraries.
Under ULTRIX, the only restriction is that you must
produce each object file with the option -G 0. (Notice
that that's the numeral ``0'' and not the letter
``O''). For example,
<programlisting>
1998-03-01 09:16:16 +01:00
# simple ULTRIX example
% cc -G 0 -c foo.c
</programlisting>
produces an object file called foo.o that can then be
dynamically loaded into <productname>Postgres</productname>.
No additional loading or link-editing must be performed.
</para>
</sect1>
-->
1998-03-01 09:16:16 +01:00
<sect1 id="dload-osf">
<title><acronym>DEC OSF/1</acronym></title>
1998-03-01 09:16:16 +01:00
<para>
Under DEC OSF/1, you can take any simple object file
and produce a shared object file by running the ld command
over it with the correct options. The commands to
do this look like:
<programlisting>
1998-03-01 09:16:16 +01:00
# simple DEC OSF/1 example
% cc -c foo.c
% ld -shared -expect_unresolved '*' -o foo.so foo.o
</programlisting>
The resulting shared object file can then be loaded
into <productname>Postgres</productname>. When specifying the object file name to
the create function command, one must give it the name
of the shared object file (ending in .so) rather than
the simple object file.
1998-03-01 09:16:16 +01:00
<tip>
<para>
Actually, <productname>Postgres</productname> does not care
what you name the
file as long as it is a shared object file. If you prefer
to name your shared object files with the extension .o, this
is fine with <productname>Postgres</productname>
so long as you make sure that the correct
file name is given to the create function command. In
other words, you must simply be consistent. However, from a
pragmatic point of view, we discourage this practice because
you will undoubtedly confuse yourself with regards to which
files have been made into shared object files and which have
not. For example, it's very hard to write Makefiles to do
the link-editing automatically if both the object file and
the shared object file end in .o!
</para>
</tip>
1998-03-01 09:16:16 +01:00
If the file you specify is
not a shared object, the backend will hang!
</para>
</sect1>
1998-03-01 09:16:16 +01:00
<sect1 id="dload-other">
<title>
<acronym>SunOS 4.x</acronym>, <acronym>Solaris 2.x</acronym> and
<acronym>HP-UX</acronym></title>
1998-03-01 09:16:16 +01:00
<para>
Under SunOS 4.x, Solaris 2.x and HP-UX, the simple
object file must be created by compiling the source
file with special compiler flags and a shared library
must be produced.
The necessary steps with HP-UX are as follows. The +z
flag to the HP-UX C compiler produces
<firstterm>Position Independent Code</firstterm> (PIC)
and the +u flag removes
some alignment restrictions that the PA-RISC architecture
normally enforces. The object file must be turned
into a shared library using the HP-UX link editor with
the -b option. This sounds complicated but is actually
very simple, since the commands to do it are just:
<programlisting>
1998-03-01 09:16:16 +01:00
# simple HP-UX example
% cc +z +u -c foo.c
% ld -b -o foo.sl foo.o
</programlisting>
</para>
1998-03-01 09:16:16 +01:00
<para>
As with the .so files mentioned in the last subsection,
the create function command must be told which file is
the correct file to load (i.e., you must give it the
location of the shared library, or .sl file).
Under SunOS 4.x, the commands look like:
<programlisting>
1998-03-01 09:16:16 +01:00
# simple SunOS 4.x example
% cc -PIC -c foo.c
% ld -dc -dp -Bdynamic -o foo.so foo.o
</programlisting>
1998-03-01 09:16:16 +01:00
and the equivalent lines under Solaris 2.x are:
<programlisting>
1998-03-01 09:16:16 +01:00
# simple Solaris 2.x example
% cc -K PIC -c foo.c
% ld -G -Bdynamic -o foo.so foo.o
</programlisting>
1998-04-28 16:54:24 +02:00
or
<programlisting>
1998-04-28 16:54:24 +02:00
# simple Solaris 2.x example
% gcc -fPIC -c foo.c
% ld -G -Bdynamic -o foo.so foo.o
</programlisting>
</para>
1998-03-01 09:16:16 +01:00
<para>
When linking shared libraries, you may have to specify
some additional shared libraries (typically system
libraries, such as the C and math libraries) on your ld
command line.
</para>
</sect1>
<!--
Future integration: Create separate sections for these operating
systems and integrate the info from this old man page.
- thomas 2000-04-21
Under HP-UX, DEC OSF/1, AIX and SunOS 4, all object files must be
turned into
.IR "shared libraries"
using the operating system's native object file loader,
.IR ld(1).
.PP
Under HP-UX, an object file must be compiled using the native HP-UX C
compiler,
.IR /bin/cc ,
with both the \*(lq+z\*(rq and \*(lq+u\*(rq flags turned on. The
first flag turns the object file into \*(lqposition-independent
code\*(rq (PIC); the second flag removes some alignment restrictions
that the PA-RISC architecture normally enforces. The object file must
then be turned into a shared library using the HP-UX loader,
.IR /bin/ld .
The command lines to compile a C source file, \*(lqfoo.c\*(rq, look
like:
.nf
cc <other flags> +z +u -c foo.c
ld <other flags> -b -o foo.sl foo.o
.fi
The object file name in the
.BR as
clause should end in \*(lq.sl\*(rq.
.PP
An extra step is required under versions of HP-UX prior to 9.00. If
the Postgres header file
.nf
include/c.h
.fi
is not included in the source file, then the following line must also
be added at the top of every source file:
.nf
#pragma HP_ALIGN HPUX_NATURAL_S500
.fi
However, this line must not appear in programs compiled under HP-UX
9.00 or later.
.PP
Under DEC OSF/1, an object file must be compiled and then turned
into a shared library using the OSF/1 loader,
.IR /bin/ld .
In this case, the command lines look like:
.nf
cc <other flags> -c foo.c
ld <other flags> -shared -expect_unresolved '*' -o foo.so foo.o
.fi
The object file name in the
.BR as
clause should end in \*(lq.so\*(rq.
.PP
Under SunOS 4, an object file must be compiled and then turned into a
shared library using the SunOS 4 loader,
.IR /bin/ld .
The command lines look like:
.nf
cc <other flags> -PIC -c foo.c
ld <other flags> -dc -dp -Bdynamic -o foo.so foo.o
.fi
The object file name in the
.BR as
clause should end in \*(lq.so\*(rq.
.PP
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.
-->
</chapter>
<!-- 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:
-->