diff options
Diffstat (limited to 'doc/src/sgml/dfunc.sgml')
-rw-r--r-- | doc/src/sgml/dfunc.sgml | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/doc/src/sgml/dfunc.sgml b/doc/src/sgml/dfunc.sgml new file mode 100644 index 0000000..a635767 --- /dev/null +++ b/doc/src/sgml/dfunc.sgml @@ -0,0 +1,252 @@ +<!-- 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</primary></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</primary></indexterm> 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</systemitem> + <indexterm><primary>FreeBSD</primary><secondary>shared library</secondary></indexterm> + </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</systemitem>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + <systemitem class="osname">HP-UX</systemitem> + <indexterm><primary>HP-UX</primary><secondary>shared library</secondary></indexterm> + </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</systemitem> uses the extension + <filename>.sl</filename> for shared libraries, unlike most other + systems. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + <systemitem class="osname">Linux</systemitem> + <indexterm><primary>Linux</primary><secondary>shared library</secondary></indexterm> + </term> + <listitem> + <para> + The compiler flag to create <acronym>PIC</acronym> is + <option>-fPIC</option>. + 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">macOS</systemitem> + <indexterm><primary>macOS</primary><secondary>shared library</secondary></indexterm> + </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</systemitem> + <indexterm><primary>NetBSD</primary><secondary>shared library</secondary></indexterm> + </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</systemitem> + <indexterm><primary>OpenBSD</primary><secondary>shared library</secondary></indexterm> + </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</systemitem> + <indexterm><primary>Solaris</primary><secondary>shared library</secondary></indexterm> + </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</application>. To + link shared libraries, the compiler option is + <option>-G</option> with either compiler or alternatively + <option>-shared</option> with <application>GCC</application>. +<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> + + </variablelist> + + <tip> + <para> + If this is too complicated for you, you should consider using + <ulink url="https://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> |