<!--
$Header: /usr/prj/pg/cvsroot/doc/doc/src/sgml/dfunc.sgml,v 1.8 2001/07/10 01:07:17 natsuyo Exp $
-->

<sect2 id="dfunc">
<!-- <title id="dfunc-title">Compiling and Linking Dynamically-Loaded Functions</title> -->
 <title id="dfunc-title">動的にロードされる関数のコンパイルとリンク</title>
<indexterm><primary sortas="どうてきろーどかんすう">動的ロード関数</primary></indexterm><indexterm><primary sortas="かんすう">関数</primary><secondary sortas="どうてきろーど">動的ロード</secondary></indexterm>
 <para>
  <!-- Before you are able to use your
  <productname>PostgreSQL</productname> extension function written in
  C they need to be compiled and linked in a special way in order to
  allow it to be dynamically loaded as needed by the server.  To be
  precise, a <firstterm>shared library</firstterm> needs to be created. -->

  Cで書かれた<productname>PostgreSQL</productname>の拡張関数を使うためには、サーバーの要求があったときに動的にロードできるように特別な方法でコンパイルとリンクを行う必要があります。正確にいうと、<firstterm>共有ライブラリ</firstterm>を作る必要があるのです。

 </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. -->

  詳しい情報は、オペレーティングシステムのドキュメント、特にCコンパイラ<command>cc</command>と、リンクエディタ<command>ld</command>のマニュアルページを参照してください。さらに、<productname>PostgreSQL</productname>のソースコードの<filename>contrib</filename>ディレクトリにいくつか実例があります。しかし、もしこれらの例に頼ると<productname>PostgreSQL</productname>ソースコードの有効性に依存したモジュールが作られてしまいます。
 </para>

 <para>
  <!-- Creating shared libraries is generally analoguous 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 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. 
  -->

  共有ライブラリの作成は実行プログラムのリンクと似ています。まずソースファイルがオブジェクトファイルにコンパイルされ、そのオブジェクトファイル同士がリンクされるのです。これらのオブジェクトファイルは<firstterm>ポジションインディペンダントコード</firstterm>（<acronym>PIC</acronym>）として作られる必要があります。それは概念的には、実行プログラムから呼び出されるときにメモリの適当な場所に置くことができるということです（実行プログラムとして作られたオブジェクトファイルはそのようにはコンパイルされません）。共有ライブラリをリンクするコマンドは実行プログラムのリンクと区別するための特別なフラグを持っています。少なくとも理論上ではそのようになっています。他のシステムではもっとわかりにくい物もあります。<indexterm><primary sortas="ぽじしょんいんでぃぺんだんとこーど">ポジションインディペンダントコード</primary></indexterm><indexterm><primary>PIC</primary></indexterm><indexterm><primary sortas="きょうゆうらいぶらり">共有ライブラリ</primary></indexterm><indexterm><primary sortas="かんすう">関数</primary><secondary sortas="きょうゆうらいぶらり">共有ライブラリ</secondary></indexterm><indexterm><primary sortas="かんすう">関数</primary><secondary>PIC</secondary></indexterm>

 </para>

 <para>
<!--  In the following examples we assume that your source code is in a
  file <filename>foo.c</filename> and we will create an 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. -->

  次の例ではソースコードはファイル<filename>foo.c</filename>にあるものと仮定し、<filename>foo.so</filename>という共有ライブラリを作ります。中間のオブジェクトファイルは特別な記述がない限り<filename>foo.o</filename>とと呼ばれます。共有ライブラリは1つ以上のオブジェクトファイルを持つことができますが、ここでは1つしか使われていません。

 </para>


<!--
<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.
</para>
-->

  <variablelist>
   <varlistentry>
    <term><productname>BSD/OS</productname></term>
    <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>. -->

      <acronym>PIC</acronym>を作るコンパイラフラグは<option>-fpic</option>です。共有ライブラリを作るリンカフラグは<option>-shared</option>です。
</para>

<programlisting>
gcc -fpic -c foo.c
ld -shared -o foo.so foo.o
</programlisting>

<para>
      <!-- This is applicable as of version 4.0 of
      <productname>BSD/OS</productname>. -->

      これは<productname>BSD/OS</productname>のバージョン4.0に適用されます。

     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>FreeBSD</productname></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>. -->

      <acronym>PIC</acronym>を作るコンパイラフラグは<option>-fpic</option>です。共有ライブラリを作るリンカフラグは<option>-shared</option>です。
</para>

<programlisting>
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>

<para>
      <!-- This is applicable as of version 3.0 of
      <productname>FreeBSD</productname>. -->

      これは<productname>FreeBSD</productname>のバージョン3.0に適用されます。

     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>HP-UX</productname></term>
    <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
      -->
     <acronym>PIC</acronym>を作るためのシステムコンパイラのコンパイラフラグは<option>+z</option>です。<productname>GCC</productname>を使う場合は<option>-fpic</option>です。共有ライブラリのためのリンカフラグは<option>-b</option>です。以下の3つの方法が考えられます。
</para>

<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>

<para>
      <!-- <productname>HP-UX</productname> uses the extension
      <filename>.sl</filename> for shared libraries, unlike most other
      systems. -->

      <productname>HP-UX</productname>は、他のほとんどのシステムと違い共有ライブラリに<filename>.sl</filename>という拡張子を使います。

     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Irix</productname></term>
    <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>. -->

      <acronym>PIC</acronym>がデフォルトで、特別なコンパイラオプションは何も必要ありません。共有ライブラリを作るためのリンカオプションは<option>-shared</option>です。
</para>

<programlisting>
cc -c foo.c
ld -shared -o foo.so foo.o
</programlisting>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Linux</productname></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:
      -->

      <acronym>PIC</acronym>を作るためのコンパイラフラグは<option>-fpic</option>です。いくつかのプラットフォームでは状況によって<option>-fpic</option>が動作しない場合は<option>-fPIC</option>を使わなければいけません。さらに詳しい情報についてはGCCのマニュアルを参照してください。共有ライブラリを作るコンパイラフラグは<option>-shared</option>です。完全な例は下記のようになります。
</para>

<programlisting>
cc -fpic -c foo.c
cc -shared -o foo.so foo.o
</programlisting>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>NetBSD</productname></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. -->

       <acronym>PIC</acronym>を作るためのコンパイラフラグは<option>-fpic</option>です。<acronym>ELF</acronym>システムではフラグ<option>-shared</option>がついたコンパイラが共有ライブラリをリンクするために使われます。より古い非ELFシステムでは<literal>ld -Bshareable</literal>が使われます。
</para>

<programlisting>
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>OpenBSD</productname></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. -->

      <acronym>PIC</acronym>を作るためのコンパイラフラグは<option>-fpic</option>です。共有ライブラリをリンクするためには<literal>ld -Bshareable</literal>が使われます。
</para>

<programlisting>
gcc -fpic -c foo.c
ld -Bshareable -o foo.so foo.o
</programlisting>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term>Digital Unix/Tru64 UNIX</term>

    <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: -->

     <acronym>PIC</acronym>がデフォルトなので、コンパイルのコマンドは通常のままで問題ありません。リンクするためには特別なオプションを付けた<command>ld</command>が使われます。
</para>

<programlisting>
cc -c foo.c
ld -shared -expect_unresolved '*' -o foo.so foo.o
</programlisting>


<para>
      <!-- The same procedure is used with GCC instead of the system
      compiler; no special options are required. -->

      システムコンパイラの代わりに、GCCを使うときも同じ手順になります。特別なオプションは要求されません。

     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Solaris</productname></term>
    <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>.
      -->

      <acronym>PIC</acronym>を作るためのコンパイラフラグはSunコンパイラでは<option>-KPIC</option>で、<productname>GCC</productname>では<option>-fpic</option>です。共有ライブラリをリンクするためには、どちらのコンパイラでも<option>-G</option>で、<productname>GCC</productname>では代わりに<option>-shared</option>オプションも使うことができます。
</para>

<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>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><productname>Unixware</productname></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>. -->

      <acronym>PIC</acronym>を作るためのコンパイラフラグはSCOコンパイラでは<option>-KPIC</option>で、<productname>GCC</productname>では<option>-fpic</option>です。共有ライブラリのリンクには、SCOコンパイラでは<option>-G</option>で、<productname>GCC</productname>では<option>-shared</option>です。
</para>

<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>
    </listitem>
   </varlistentry>

  </variablelist>

 <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.
   -->

   もし作った拡張モジュールをより広く配布するためのパッケージにしたい場合、<ulink url="http://www.gnu.org/software/libtool/"><productname>GNU Libtool</productname></ulink><![%book-publish;[（"http://www.gnu.org/software/libtool/"）]]>を共有ライブラリの構築に使うことを検討するべきです。これはプラットフォームの違いを、一般的で強力なインターフェイスにカプセル化します。真剣なパッケージ作成はさらにライブラリバージョン管理、シンボル解決メソッドなどの検討も必要になります。<indexterm><primary>GNU Libtool</primary></indexterm>

  </para>
 </tip>

 <para>
  <!--  
  The resulting shared library file can then be loaded into
  <productname>Postgres</productname>.  When specifying the file name
  to the <command>CREATE FUNCTION</command> command, one must give it
  the name of the shared library file (ending in
  <filename>.so</filename>) rather than the simple object file.
  -->

  これで完成した共有ライブラリファイルは<productname>Postgres</productname>にロードすることができます。<command>CREATE FUNCTION</command>コマンドにファイル名を指定するときには、単純なオブジェクトファイルではなく共有ライブラリ名の名前（<filename>.so</filename>で終わるもの）を渡してください。
 </para>

  <note>
   <para>
    <!-- 
    Actually, <productname>Postgres</productname> does not care what
    you name the file as long as it is a shared library file. -->

    実際は、<productname>Postgres</productname>はそのファイルが共有ライブラリファイルである限り名前が何であっても構いません。

   </para>
  </note>

<para>
  <!-- 
  Paths given to the <command>CREATE FUNCTION</command> command must
  be absolute paths (i.e., start with <literal>/</literal>) that refer
  to directories visible on the machine on which the
  <productname>Postgres</productname> server is running.  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!  The user id the
  <productname>Postgres</productname> server runs as must be able to
  traverse the path given to the <command>CREATE FUNCTION</command>
  command and be able to read the shared library file.  (Making the
  file or a higher-level directory not readable and/or not executable
  by the <quote>postgres</quote> user is a common mistake.)
  -->

  <command>CREATE FUNCTION</command>コマンドに与えられるパスは<productname>Postgres</productname>サーバーが動いているマシン上で見えるディレクトリを参照する絶対パス（つまり<literal>/</literal>で始まるもの）でなければいけません。相対パスでも実は動作しますが、これはデータベースがあるディレクトリに対して相対なのです（それは一般的にはフロントエンドアプリケーションからは見えません）。明らかに、ユーザーがフロントエンドアプリケーションを始めたディレクトリからの相対パスにしても意味がありません。なぜならサーバーはまったく別のマシンで動いているかもしれないのです!　<productname>Postgres</productname>サーバーの動作するユーザーIDで<command>CREATE FUNCTION</command>コマンドで指定されるパスを使って共有ライブラリファイルを読めなくてはいけません（<quote>postgres</quote>ユーザーが読めない、あるいは実行できないファイルもしくはより上のレベルのディレクトリを作ることはよくある間違いです）。

 </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 &bsol;*(lqexports&bsol;*(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 &bsol;e
   -bI:.../lib/postgres.exp -bE:foo.exp foo.o &bsol;e
   -lm -lc 2>/dev/null
.fi
You should look at the Postgres 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-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:
-->
