1<!-- doc/src/sgml/dfunc.sgml --> 2 3<sect2 id="dfunc"> 4 <title>Compiling and Linking Dynamically-Loaded Functions</title> 5 6 <para> 7 Before you are able to use your 8 <productname>PostgreSQL</productname> extension functions written in 9 C, they must be compiled and linked in a special way to produce a 10 file that can be dynamically loaded by the server. To be precise, a 11 <firstterm>shared library</firstterm> needs to be 12 created.<indexterm><primary>shared library</primary></indexterm> 13 14 </para> 15 16 <para> 17 For information beyond what is contained in this section 18 you should read the documentation of your 19 operating system, in particular the manual pages for the C compiler, 20 <command>cc</command>, and the link editor, <command>ld</command>. 21 In addition, the <productname>PostgreSQL</productname> source code 22 contains several working examples in the 23 <filename>contrib</filename> directory. If you rely on these 24 examples you will make your modules dependent on the availability 25 of the <productname>PostgreSQL</productname> source code, however. 26 </para> 27 28 <para> 29 Creating shared libraries is generally analogous to linking 30 executables: first the source files are compiled into object files, 31 then the object files are linked together. The object files need to 32 be created as <firstterm>position-independent code</firstterm> 33 (<acronym>PIC</acronym>),<indexterm><primary>PIC</primary></indexterm> which 34 conceptually means that they can be placed at an arbitrary location 35 in memory when they are loaded by the executable. (Object files 36 intended for executables are usually not compiled that way.) The 37 command to link a shared library contains special flags to 38 distinguish it from linking an executable (at least in theory 39 — on some systems the practice is much uglier). 40 </para> 41 42 <para> 43 In the following examples we assume that your source code is in a 44 file <filename>foo.c</filename> and we will create a shared library 45 <filename>foo.so</filename>. The intermediate object file will be 46 called <filename>foo.o</filename> unless otherwise noted. A shared 47 library can contain more than one object file, but we only use one 48 here. 49 </para> 50 51<!-- 52 Note: Reading GNU Libtool sources is generally a good way of 53 figuring out this information. The methods used within PostgreSQL 54 source code are not necessarily ideal. 55--> 56 57 <variablelist> 58 <varlistentry> 59 <term> 60 <systemitem class="osname">FreeBSD</systemitem> 61 <indexterm><primary>FreeBSD</primary><secondary>shared library</secondary></indexterm> 62 </term> 63 <listitem> 64 <para> 65 The compiler flag to create <acronym>PIC</acronym> is 66 <option>-fPIC</option>. To create shared libraries the compiler 67 flag is <option>-shared</option>. 68<programlisting> 69gcc -fPIC -c foo.c 70gcc -shared -o foo.so foo.o 71</programlisting> 72 This is applicable as of version 3.0 of 73 <systemitem class="osname">FreeBSD</systemitem>. 74 </para> 75 </listitem> 76 </varlistentry> 77 78 <varlistentry> 79 <term> 80 <systemitem class="osname">HP-UX</systemitem> 81 <indexterm><primary>HP-UX</primary><secondary>shared library</secondary></indexterm> 82 </term> 83 <listitem> 84 <para> 85 The compiler flag of the system compiler to create 86 <acronym>PIC</acronym> is <option>+z</option>. When using 87 <application>GCC</application> it's <option>-fPIC</option>. The 88 linker flag for shared libraries is <option>-b</option>. So: 89<programlisting> 90cc +z -c foo.c 91</programlisting> 92 or: 93<programlisting> 94gcc -fPIC -c foo.c 95</programlisting> 96 and then: 97<programlisting> 98ld -b -o foo.sl foo.o 99</programlisting> 100 <systemitem class="osname">HP-UX</systemitem> uses the extension 101 <filename>.sl</filename> for shared libraries, unlike most other 102 systems. 103 </para> 104 </listitem> 105 </varlistentry> 106 107 <varlistentry> 108 <term> 109 <systemitem class="osname">Linux</systemitem> 110 <indexterm><primary>Linux</primary><secondary>shared library</secondary></indexterm> 111 </term> 112 <listitem> 113 <para> 114 The compiler flag to create <acronym>PIC</acronym> is 115 <option>-fPIC</option>. 116 The compiler flag to create a shared library is 117 <option>-shared</option>. A complete example looks like this: 118<programlisting> 119cc -fPIC -c foo.c 120cc -shared -o foo.so foo.o 121</programlisting> 122 </para> 123 </listitem> 124 </varlistentry> 125 126 <varlistentry> 127 <term> 128 <systemitem class="osname">macOS</systemitem> 129 <indexterm><primary>macOS</primary><secondary>shared library</secondary></indexterm> 130 </term> 131 <listitem> 132 <para> 133 Here is an example. It assumes the developer tools are installed. 134<programlisting> 135cc -c foo.c 136cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o 137</programlisting> 138 </para> 139 </listitem> 140 </varlistentry> 141 142 <varlistentry> 143 <term> 144 <systemitem class="osname">NetBSD</systemitem> 145 <indexterm><primary>NetBSD</primary><secondary>shared library</secondary></indexterm> 146 </term> 147 <listitem> 148 <para> 149 The compiler flag to create <acronym>PIC</acronym> is 150 <option>-fPIC</option>. For <acronym>ELF</acronym> systems, the 151 compiler with the flag <option>-shared</option> is used to link 152 shared libraries. On the older non-ELF systems, <literal>ld 153 -Bshareable</literal> is used. 154<programlisting> 155gcc -fPIC -c foo.c 156gcc -shared -o foo.so foo.o 157</programlisting> 158 </para> 159 </listitem> 160 </varlistentry> 161 162 <varlistentry> 163 <term> 164 <systemitem class="osname">OpenBSD</systemitem> 165 <indexterm><primary>OpenBSD</primary><secondary>shared library</secondary></indexterm> 166 </term> 167 <listitem> 168 <para> 169 The compiler flag to create <acronym>PIC</acronym> is 170 <option>-fPIC</option>. <literal>ld -Bshareable</literal> is 171 used to link shared libraries. 172<programlisting> 173gcc -fPIC -c foo.c 174ld -Bshareable -o foo.so foo.o 175</programlisting> 176 </para> 177 </listitem> 178 </varlistentry> 179 180 <varlistentry> 181 <term> 182 <systemitem class="osname">Solaris</systemitem> 183 <indexterm><primary>Solaris</primary><secondary>shared library</secondary></indexterm> 184 </term> 185 <listitem> 186 <para> 187 The compiler flag to create <acronym>PIC</acronym> is 188 <option>-KPIC</option> with the Sun compiler and 189 <option>-fPIC</option> with <application>GCC</application>. To 190 link shared libraries, the compiler option is 191 <option>-G</option> with either compiler or alternatively 192 <option>-shared</option> with <application>GCC</application>. 193<programlisting> 194cc -KPIC -c foo.c 195cc -G -o foo.so foo.o 196</programlisting> 197 or 198<programlisting> 199gcc -fPIC -c foo.c 200gcc -G -o foo.so foo.o 201</programlisting> 202 </para> 203 </listitem> 204 </varlistentry> 205 206 </variablelist> 207 208 <tip> 209 <para> 210 If this is too complicated for you, you should consider using 211 <ulink url="https://www.gnu.org/software/libtool/"> 212 <productname>GNU Libtool</productname></ulink>, 213 which hides the platform differences behind a uniform interface. 214 </para> 215 </tip> 216 217 <para> 218 The resulting shared library file can then be loaded into 219 <productname>PostgreSQL</productname>. When specifying the file name 220 to the <command>CREATE FUNCTION</command> command, one must give it 221 the name of the shared library file, not the intermediate object file. 222 Note that the system's standard shared-library extension (usually 223 <literal>.so</literal> or <literal>.sl</literal>) can be omitted from 224 the <command>CREATE FUNCTION</command> command, and normally should 225 be omitted for best portability. 226 </para> 227 228 <para> 229 Refer back to <xref linkend="xfunc-c-dynload"/> about where the 230 server expects to find the shared library files. 231 </para> 232 233<!-- 234Under AIX, object files are compiled normally but building the shared 235library requires a couple of steps. First, create the object file: 236.nf 237cc <other flags> -c foo.c 238.fi 239You must then create a symbol \*(lqexports\*(rq file for the object 240file: 241.nf 242mkldexport foo.o `pwd` > foo.exp 243.fi 244Finally, you can create the shared library: 245.nf 246ld <other flags> -H512 -T512 -o foo.so -e _nostart \e 247 -bI:.../lib/postgres.exp -bE:foo.exp foo.o \e 248 -lm -lc 2>/dev/null 249.fi 250 --> 251 252</sect2> 253