-<Chapter>
-<Title>Linking Dynamically-Loaded Functions</Title>
-
-<Para>
- After you have created and registered a user-defined
- function, your work is essentially done. <ProductName>Postgres</ProductName>,
- however, must load the object code (e.g., a <FileName>.o</FileName> file, or
- a shared library) that implements your function. As
- 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
- linkedit it in a special way. This section briefly
- describes how to perform the compilation and
- linkediting required before you can load your user-defined
- functions into a running <ProductName>Postgres</ProductName> server. Note that
- this process has changed as of Version 4.2.
-<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
-<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
-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>
- 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 regression test suites in the directory
- <FileName>PGROOT/src/regress</FileName> contain several
- working examples of this process. If you copy what these
- tests do, you should not have any problems.
- 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>
-
-<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.
-<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>
-<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>
-
-<Sect1>
-<Title><Acronym>ULTRIX</Acronym></Title>
-
-<Para>
- It is very easy to build dynamically-loaded object
- files under ULTRIX. ULTRIX does not have any sharedlibrary
- 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>
-# 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>
-
-<Sect1>
-<Title><Acronym>DEC OSF/1</Acronym></Title>
-
-<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>
-# 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.
-<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>
-
-If the file you specify is
- not a shared object, the backend will hang!
-</Para>
-</Sect1>
-
-<Sect1>
-<Title>
-<Acronym>SunOS 4.x</Acronym>, <Acronym>Solaris 2.x</Acronym> and <Acronym>HP-UX</Acronym></Title>
-
-<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 so-called
- "Position Independent Code" (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>
-# simple HP-UX example
- % cc +z +u -c foo.c
- % ld -b -o foo.sl foo.o
-</ProgramListing>
-</Para>
-
-<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>
-# simple SunOS 4.x example
- % cc -PIC -c foo.c
- % ld -dc -dp -Bdynamic -o foo.so foo.o
-</ProgramListing>
-
- and the equivalent lines under Solaris 2.x are:
-<ProgramListing>
-# simple Solaris 2.x example
- % cc -K PIC -c foo.c
- or
- % gcc -fPIC -c foo.c
- % ld -G -Bdynamic -o foo.so foo.o
-</ProgramListing>
-</Para>
-
-<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>
-</Chapter>
+<!-- doc/src/sgml/dfunc.sgml -->
+
+<sect2 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.<indexterm><primary>shared library</></indexterm>
+
+ </para>
+
+ <para>
+ For information beyond what is contained in this section
+ 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 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>),<indexterm><primary>PIC</></> 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 in 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 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>
+
+<!--
+ 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>
+ <systemitem class="osname">FreeBSD</>
+ <indexterm><primary>FreeBSD</><secondary>shared library</></>
+ </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
+ <systemitem class="osname">FreeBSD</>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">HP-UX</>
+ <indexterm><primary>HP-UX</><secondary>shared library</></>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag of the system compiler to create
+ <acronym>PIC</acronym> is <option>+z</option>. When using
+ <application>GCC</application> 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>
+ <systemitem class="osname">HP-UX</> uses the extension
+ <filename>.sl</filename> for shared libraries, unlike most other
+ systems.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">Linux</>
+ <indexterm><primary>Linux</><secondary>shared library</></>
+ </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>
+ <systemitem class="osname">Mac OS X</>
+ <indexterm><primary>Mac OS X</><secondary>shared library</></>
+ </term>
+ <listitem>
+ <para>
+ Here is an example. 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>
+ <systemitem class="osname">NetBSD</>
+ <indexterm><primary>NetBSD</><secondary>shared library</></>
+ </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>
+ <systemitem class="osname">OpenBSD</>
+ <indexterm><primary>OpenBSD</><secondary>shared library</></>
+ </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>
+ <systemitem class="osname">Solaris</>
+ <indexterm><primary>Solaris</><secondary>shared library</></>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag to create <acronym>PIC</acronym> is
+ <option>-KPIC</option> with the Sun compiler and
+ <option>-fpic</option> with <application>GCC</>. To
+ link shared libraries, the compiler option is
+ <option>-G</option> with either compiler or alternatively
+ <option>-shared</option> with <application>GCC</>.
+<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>
+ <systemitem class="osname">UnixWare</>
+ <indexterm><primary>UnixWare</><secondary>shared library</></>
+ </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>
+
+ <tip>
+ <para>
+ If this is too complicated for you, you should consider using
+ <ulink url="http://www.gnu.org/software/libtool/">
+ <productname>GNU Libtool</productname></ulink>,
+ which hides the platform differences behind a uniform interface.
+ </para>
+ </tip>
+
+ <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
+ -->
+
+</sect2>