ソフテック・トップページへ
ホーム 製品 セキュリティ・サービス HPCサービス ダウンロード 企業情報

PGI compiler TIPS
PGIコンパイラを利用したリンク操作の裏技
技術情報・TIPS > リンク操作の裏技
 

PGI コンパイラを利用する際のライブラリ・リンク操作の裏技 (2005年5月6日)

PGI コンパイラに限らず、一般的なコンパイラでは、アセンブル機能とリンク機能は、GNUのユーティリティを使用します(Linux の場合)。一般に、プログラムのコンパイルから実行モジュールの生成までは、以下の内部的な手続きが行われています。PGI コンパイラは以下の手続きを自動的に行っています。以下の手続きの内容と各コマンドのオプションを知るための方法は、こちらで説明しています。

  1. コンパイル&コード生成 (pgi のコンパイラコマンド・コマンド)
  2. アセンブラによるオブジェクト生成 (GNU as コマンド)
  3. リンカによるライブラリ等のリンクを行って実行モジュールの生成 (GNU ld コマンド)


上記の手続きの中で、1,2 に関してはユーザが直接操作することができませんが、3 のリンケージの処理に関しては、ユーザ独自で GNU の ld コマンドのオプションを操作して、リンク時の問題等に対応することが可能です。
以下に説明する内容は、リンクにおける様々な裏技の例を示したものです。「リンク時における問題」の多くは、必要とするライブラリが見つからない問題、同じ関数・サブプログラムを別のライブラリ・ファイルからリンクしたい等の対処が多いため、リンケージに関する基本的な知識を要します。 ここでは、リンク時における「ライブラリ」の対処法に関してフォーカスし、その裏技を説明します。

ランタイム・ライブラリに関する基礎知識
まず始めに、実行モジュールにリンクされる、ライブラリに関する基礎的な事項について説明します。ユーザ・プログラム(オブジェクト)にリンクされるライブラリには、大きく以下の二つのライブラリ形式があります。

  • スタティック(静的)ライブラリ
  • シェアード(共有)ライブラリ

二つ目の共有ライブラリの範疇には、一般にダイナミックライブラリと言う形式のものもありますが、この共有ライブラリの中の特殊な例です。スタティックライブラリは、リンク時に実行モジュールの中に組み込まれます。モジュールサイズは大きくなりますが、別のシステム上で動作させたい場合は、全て必要なライブラリが組み込まれているため、そのままの形で動作します。一般に、ファイル名形式として、lib***.a と言う .a の名称がつけられております。スタティックライブラリを作成するためには、一般に、ar コマンドでオブジェクト(*.o)をまとめ、 ranlib コマンドでリンクを高速化する先頭子をつけ、strip コマンドでシンボルテーブルを削除します。
一方、シェアード(共有)ライブラリは、プログラムの実行時にシステム上に備えている、そのライブラリをロードして使用するためのものであり、システムライブラリのバージョンが異なったり、システム上に存在しない場合は、実行モジュールが動作しない場合があります。一般に、ファイル名形式として、lib***.so と言う .so の名称がつけられております。シェアードライブラリの一つである、ダイナミックライブラリとは、実行時に load/unload することが可能な「位置独立なライブラリ形式」のものを言います。これは、リンク時のオプションに -fPIC を指定して作成されております。

一般の実行モジュールは、ほとんどが「シェアード(共有)ライブラリ」をリンクするとの前提で生成され、実行時に必要とされるシステム共有ライブラリとPGI の場合は、PGI 用の共有ライブラリがロードされる形式になっています。このデフォルトのリンク方式を使用する場合には、「リンク時における問題」は、ほとんど発生しませんが、明示的にスタティック(静的)ライブラリをリンクする際に未解決なオブジェクト・ルーチンが存在する場合や作為的にあるライブラリを組み込みたい等の操作をした場合、リンク時の問題が発生します。


リンク時におけるライブラリの組込み順序
デフォルトでは、リンカはまず、シェアード(共有)ライブラリを検索し、必要となるルーチンを組み込もうとします。次に、スタティック(静的)なライブラリの中から探し出し、実行モジュールに組み込みます。従って、一般のコンパイル(リンク)オプションでは、ある配慮を行わなければ、常に、シェアード(共有)ライブラリが組み込まれると言うことになります。この点を理解しておくが、「リンクする順序」と共に重要なポイントとなります。
ちなみに、実行モジュールの中でどのような dynamic shared library が使用されているかは、以下のコマンド (ldd) で確かめることができます。以下の例では、PGI 関連の libpgc.so だけでなく、システムに備えられたシェアード(共有)ライブラリもリンクされるべき実行モジュールであることが分かります。特に libpgc.so ファイルは、PGI をインストールしたマシン上でしか存在しません。例えば、他のシステムでこのような実行モジュールを動作させるためには、このlibpgc.so ファイルを予めコピーしておくことが必要となります。


 $ ldd a.out
   libc.so.6 => /lib/i686/libc.so.6 (0x4002d000)
   libpgc.so => /usr/pgi/linux86/5.2/lib/libpgc.so (0x4015d000)
   libm.so.6 => /lib/i686/libm.so.6 (0x40172000)
   /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

一方、スタティックなライブラリをリンクして作成された実行モジュールでは、ldd コマンドでどのように表示されるでしょうか?以下のように表示されます。

 $ ldd a.out
   not a dynamic executable

リンカが暗黙で行うシステム上のライブラリ検索順序は上記に述べたとおりですので、これを作為的に変更することによって、所望とするライブラリ・ルーチンを先に組み込むことができます。一般に、リンカ(コマンド)のオプションの指定で、ライブラリの検索順位を明示的に指定することができます。とは言っても、この操作は簡単で、単にリンクするライブラリ名をコマンド列の中で先に指定するだけの操作となります。このことを理解すれば、後は試行錯誤で、リンクエラーが起きないように所望とするライブラリを組み込むことができます。複数のライブラリ間で呼び出し/参照の順序の依存関係がある場合、ライブラリ名をコマンド列で指定する順序は、必ず以下のようにしなければなりません(順序はセンシティブです)。

 例えば、 ユーザのスタティックライブラリ libA.a の中の関数が、libB.a の中の関数を必要とする場合の例を記します。

   libA.a ---> libB.a (共有ライブラリの場合は、 libA.so ---> libB.so)

 リンカのコマンド列では、以下のような順番でリンク検索順序を指定します。ライブラリ(*.a) 内の参照の解決は、コマンド行に記されたものを順番に、1回限りの検索を行います。特に大事なことは、コマンド行上で先行するアーカイブ・ライブラリを、後続の入力ファイル(ライブラリを含む)内の新しい参照の解決に使用することはありません。このリンケージにおける暗黙の決まりごとが、コマンド行のライブラリ名指定の順序に関係します。以下の例では、最初に test.o の未解決の参照をコマンド行の次以降に記された *.a を順番に検索して解決すれば問題なく、test.o を実行モジュールにできますが、これで全てOKとは言えません。次のコマンド行に出てくる libA.a 内部の未解決参照があるかどうか、リンカはチェックします。リンカは、コマンド行のlibA.a の右側に記述されているライブラリのみしか、未解決参照シンボルを検索しません。もし、その前にアーカイブ名記述されていたとしても、例えば、この場合libB.a がコマンド行の前に記述されていても、「検索」自体を行いません。常に、コマンド行を1回限り、常に右にあるものを検索するのみです。

   pgCC test.o -Bstatic -L{directory} -lA -lB ( -lB -lA の順番では libB.a の関数が未解決になります)

 あるいは、明示的にライブラリ名を指定します。

   pgCC test.o -Bstatic libA.a libB.a
 
 共有ライブラリ(libA.so、libB.so)の場合は、
   pgCC test.o -L{directory} -lA -lB あるいは、pgCC test.o libA.so libB.so

静的にリンクする場合のコンパイル・オプション
PGI コンパイラでは、リンカに静的リンケージを行うことを指示するために、 -Bstatic と言うオプションがあります。基本的には、この指定によって、リンカは静的ライブラリを先に検索しようとします。但し、-Bstatic オプションを指定して実行モジュールを作成する際に、リンカのレベルで、「未解決な参照ルーチン」が存在して、実行モジュールが作成できないエラーが生じる場合があります。これは、PGI コンパイラ(ld リンカ)のデフォルトのライブラリの検索順序が適当でない場合に生じます。この対策については、以下に例を示しました。

(1) -Bstatic を指定すると、未解決なライブラリルーチンが存在し、モジュールが生成できない問題

pgCC (C++) を使用して、デフォルトの共有ライブラリをリンクして実行モジュールは問題なく作成できるが、静的リンク -Bstatic を指定すると、リンク時に 「未解決な参照ルーチン」 が存在すると言う形でエラーになる。

$ pgCC test.C  (動的リンクは問題なく実行モジュールは生成される)

$ pgCC -Bstatic test.C (静的リンクで未解決な参照がありエラー)
 /usr/pgi/linux86-64/6.0/lib/libstd.a(locale_impl.o)(.text+0x25): In function  
 `std::_STLP_mutex_base::_M_acquire_lock( (void))':: undefined reference to `pthread_mutex_lock'
 /usr/pgi/linux86-64/6.0/lib/libstd.a(locale_impl.o)(.text+0x35): In function  
 `std::_STLP_mutex_base::_M_release_lock( (void))':: undefined reference to `pthread_mutex_unlock'


 【解決方法】

問題の状況の把握:
動的リンクの場合は、正常なライブラリのリンクがなされているため、ライブラリ間の参照依存性は解決されてリンクされている。一方、静的ライブラリを使用してリンクする場合は、ライブラリ間の参照の依存性が存在している。libstd.a ライブラリが、pthread 関係の静的システムライブラリを参照するが、これらのライブラリのリンクの順序の不整合か、あるいは、pthread のライブラリがリンクされていないと言う予想がつく。動的ライブラリと静的ライブラリでは、個々のライブラリのその参照構成が異なる場合がある。少なくとも、静的リンク法では、libstd.a が明示的にリンクされなければいけない形式となっているようだ(動的リンクとは異なる)。その中で、pthread ライブラリが参照されているため、リンク時にこの pthread ライブラリが何らかの形で参照できないという状況のようである。

【リンク時 (ld) のオプションの設定を調べる】
$ pgCC -Bstatic test.C -#  (コンパイル手続きの詳細を調べる
 /usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.3/crtbegin.o
-m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /tmp/pgCCcaaaareeat.o
-L/usr/pgi/linux86-64/6.0/lib -L/usr/lib64 -L/usr/lib64/gcc-lib/x86_64-suse-linux/3.3.3
-rpath /usr/pgi/linux86-64/6.0/lib -Bstatic -lstd -lC -lc -lnspgc -lpgc -lm -lgcc -lc -lgcc
/usr/lib64/gcc-lib/x86_64-suse-linux/3.3.3/crtend.o /usr/lib64/crtn.o

上記の ld コマンドのライブラリ指定の中で、-lstd (libstd.a) は存在するが、 -lpthread (libpthread.a) の指定はないため、未解決な参照としてエラーとなっている。

【libstd.a と libpthread.a の存在場所を調べる】
上記のコマンド列の中で、ライブラリ参照パス -L/usr/pgi/linux86-64/6.0/lib -L/usr/lib64 の中に存在するかを調べる。特に libpthread.a の存在を調べると、確かに /usr/lib64 配下に存在する。従って、コンパイル(リンク)オプションに、明示的に -lpthread を指定することで、リンクが可能であると予想がつく。

【コンパイル(リンク)オプションに、必要なライブラリ名を付け加える】
コンパイル・オプションにおいて、この問題を回避するための方法を以下に示す。ライブラリの指定は、必ず、ユーザプログラム test.C(test.o) の後に指定した方が安全である。(参照の上位の順番から指定する)

  pgCC -Bstatic test.C  -lstd -lpthread  (std と pthread の順番を間違わないように!)

あるいは、

 pgCC -Bstatic test.C  -Wl,'-lstd','-lpthread'

あるいは、

 pgcc -Bstatic test.C /usr/pgi/linux86-64/6.0/lib/libstd.a /usr/lib64/libpthread.a


(2) FORTRN77 3F関数 に関して PGI 提供関数ではなく、ネイティブな G77 3F 関数のライブラリをリンクする

3F ルーチンとして知られている Fortan run-time ライブラリである、Linux システムとのインタフェースを取り持つ関数、サブプログラムは、多くのシステム上で提供されています。これは、 FORTRAN77 3F ルーチンと称され、Cプログラムが C ライブラリで Linux システムのシェル「等の機能を制御できるように、これらと同様な機能を提供します。PGI コンパイラは、これら3F 関数がプログラムで使用されている場合、自動的にリンク(ロード)し利用できます。デフォルトは、PGI が提供する3F互換のライブラリが、リンクされますが、関数の出力するフォーマットが異なる場合があります。この場合、GNU の 3F 関数形式の出力を利用したい場合、ネイティブな3F 関数をリンクしなければならない状況が生じます。
ここでの例は、PGI のデフォルトの 3F 関数を使用せずに、Linux システムが提供している g77 の 3F 関数をリンクしたいと言う要求に対する対処例を示したものです。具体的には、idate 関数の出力フォーマットが g77 とは異なる場合、PGI のライブラリではなく、GNU g77 のライブラリを直接リンクしたい場合のリンクの方法を述べたものです。

プログラム例: 3F 関数 idate の使用例 test.f

      INTEGER*4 ia(3)
      call idate( ia )
      write(*, "(' The date is: ',3i5)" ) ia
      stop
      end

実行例: idate は 年月日を出力する関数です

$ pgf95 -g77libs -o a.out test.f
$ ./a.out
 The date is:     4   19    5  (下記の g77 の場合と出力形式が異なる)

$ g77 -o a.out test.f
$ ./a.out
 The date is:    19    4 2005

  • PGI コンパイラでは 組み込み関数は基本的に、PGI が提供する関数群、G77互換の関数を使用することが前提となっています。例えば、G77 の互換組込み関数は /usr/pgi/linux86/6.0/lib/libpgftnrtl.a と言うライブラリに含まれております。
  • 一方、Linux が提供する g77 の 組込み関数に関しては、一般には、/usr/lib/libg2c.a or libg2c.so に含まれております。場所は Linux OS によって異なる場合がありますが、g77のパッケージをインストールしてあれば、libg2c と言うライブラリはいずれかの場所に存在します。


今回の問題に関して対処する方法は、リンク時においてデフォルトの PGI 提供の g77 intrinsic ではなく、GNU の libg2c.so の g77 intrinsic を使用するように PGI 及びシステム・ライブラリのリンケージの順番を明示的に変更することです。pgf95(pgf77) コマンドライン上では、これを以下の方法で行います。

 pgf95  -Wl,'/usr/lib/libg2c.so' test.f   (32bit Linux)
 pgf95  -Wl,'/usr/lib64/libg2c.so' test.f (64bit Linux)

あるいは安全のために -g77libs を入れておいても構いません。

 pgf95  -g77libs  -Wl,'/usr/lib/libg2c.so' test.f   (32bit Linux)
 pgf95  -g77libs  -Wl,'/usr/lib64/libg2c.so' test.f (64bit Linux)

 $ ./a.out
  The date is:    19    4 2005

ここで、 -Wl,'/usr/lib/libg2c.so' の指定方法は、PGI に限らずコンパイラ上での他のモジュール(リンカー等)へのオプションを引き渡すための共通フォームです。-Wl,"引き渡すオプション" と言うフォーマットですが、-Wl のエル (l) は "l"="linker" と言う意味で、リンカーに対し /usr/lib/libg2c.so と言うライブラリを一番最初の検索ライブラリ(オブジェクト)にせよと言う指示の意味となります。

すなわち、PGIが実行モジュールを作成するためにリンカーld に引き渡すリンケージのオプションに、上記の '/usr/lib/libg2c.so' を加えることになります。デフォルトは、必ず PGI の提供する g77 intrinsic ライブラリである libpgftnrtl.a が先にリンクされるようになっています。従って、PGIが提供する一般的なコンパイラのオプションでは、PGI の関数を先に使用するため、 g77 の結果のようにはなりません。

PGIコンパイラのコマンド (pgf77) がそのコンパイルフェーズ(リンクフェーズ)でどのようなオプション順位でリンクしているかを確認してみます。-# オプションを付けてみてください。以下は、SuSE 9.1(32bit) の OS 下で PGI5.2 の場合において出力されるものです。ここでは安全の意味で、-g77libs を指定してGNU のライブラリもリンケージライブラリ候補に指定しています。

$ pgf77 -g77libs -# test.f

(リンカー ld でリンケージするフェーズとそのオプション)
/usr/bin/ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i586-suse-linux/3.3.3/crtbegin.o
/usr/pgi/linux86/5.2/lib/pgfmain.o -m elf_i386 -dynamic-linker /lib/ld-linux.so.2
/tmp/pgf77baaaaBwtab.o -L/usr/pgi/linux86/5.2/lib -L/usr/lib
-L/usr/lib/gcc-lib/i586-suse-linux/3.3.3 -L/usr/lib/gcc-lib/i586-suse-linux/3.3.3 -rpath
/usr/pgi/linux86/5.2/lib -lpgftnrtl -lg2c -lc -lnspgc -lpgc -lm -lgcc
-lc -lgcc /usr/lib/gcc-lib/i586-suse-linux/3.3.3/crtend.o /usr/lib/crtn.o

リンカ ld のオプションで、最後の方に -lpgftnrtl -lg2c と言う順番で並んでいることが分かります。ld のオプションでは、指定されたライブラリの順番で未解決なオブジェクトを探して最初に見つかればそれを採用します。この場合は、PGI の g77 Intrinsic (libpgftnrtl) が -lg2c より最初に来ています。従って、 PGI のライブラリの方が優先されます。

それでは、以下の解決策の場合はどうでしょう。

$ pgf77 -g77libs -Wl,'/usr/lib/libg2c.so' -# test.f
$ a.out
The date is: 19 4 2005
FORTRAN STOP

(リンカの部分のみ示します)
/usr/bin/ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i586-suse-linux/3.3.3/crtbegin.o
/usr/pgi/linux86/5.2/lib/pgfmain.o -m elf_i386 -dynamic-linker /lib/ld-linux.so.2
/tmp/pgf77baaaatxtap.o -L/usr/pgi/linux86/5.2/lib -L/usr/lib
-L/usr/lib/gcc-lib/i586-suse-linux/3.3.3 -L/usr/lib/gcc-lib/i586-suse-linux/3.3.3 -rpath
/usr/pgi/linux86/5.2/lib /usr/lib/libg2c.so -lpgftnrtl -lg2c -lc -lnspgc -lpgc -lm -lgcc -lc -lgcc
/usr/lib/gcc-lib/i586-suse-linux/3.3.3/crtend.o /usr/lib/crtn.o

オプションの最後の方に、/usr/lib/libg2c.so -lpgftnrtl と言う順番でリンクされるようになっているはずです。検索順位の最初の /libg2c.so の g77Intrinsic がリンクされて、意図する出力が得られます。

(3) 高度なテクニック : リンカ (ld) を直接操る方法

全てのライブラリをスタティックにリンクしないで、PGI コンパイラの共有ランタイムライブラリである、libpgc.so 等(libpgc.a) をスタティックにリンクし、GNU glibc 系のライブラリをダイナミック形式のままで実行モジュールを作ると言った、特殊なリンケージの例を以下に示します。この操作を行うためには、GNU ld (リンカ)コマンドを直接、操作しなければなりません。このようなリンクを必要とする一例としては、実行モジュールをバイナリで他者に提供する際に、自コードのソースを公開せずに、 GNU ライセンスに即した形で GNU のランタイムライブラリのみ、共有ライブラリを使用するバイナリ形式で提供するような場合が想定できます。

全てのライブラリが動的リンクの場合のリンク状況を調べる

 $ pgf77 -# test.f

(リンカの部分のみ示します)
/usr/bin/ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/crtbegin.o /export/pgi524/linux86/5.2/lib/pgfmain.o -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /tmp/pgf77baaaayxeai.o -L/export/pgi524/linux86/5.2/lib -L/usr/lib -L/usr/lib/gcc -lib/i386-redhat-linux/2.96 -rpath /export/pgi524/linux86/5.2/lib -lpgftnrtl -lc -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib/gcc-lib/ i386-redhat-linux/2.96/crtend.o /usr/lib/crtn.o

 $ ldd a.out (使用されているダイナミック共有ライブラリを調べる)
libc.so.6 => /lib/i686/libc.so.6 (0x40033000)  (GNU ライブラリ)
libpgc.so => /export/pgi524/linux86/5.2/lib/libpgc.so (0x4016e000)  これを静的ライブラリ・リンクにする
libm.so.6 => /lib/i686/libm.so.6 (0x40183000) (GNU ライブラリ)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) (GNU ライブラリ)

上記のうち、PGI 用のダイナミックライブラリ libpgc.so のみをスタティックにリンクする方法を考えます。

 $ ls -lt a.out (バイナリのサイズ)
 -rwxr-xr-x 1 kato softek 64439 Dec 15 21:16 a.out*

全てのライブラリを静的にリンクした場合の状況も調べてみる

 $ pgf77 -# -Bstatic test.f

(リンカの部分のみ示します)
/usr/bin/ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/crtbegin.o /export/pgi524/linux86/5.2/lib/pgfmain.o -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /tmp/pgf77baaaaoyeao.o -L/export/pgi524/linux86/5.2/lib -L/usr/lib -L/usr/lib/gcc -lib/i386-redhat-linux/2.96 -rpath /export/pgi524/linux86/5.2/lib -Bstatic -lpgftnrtl -lc -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib /gcc-lib/i386-redhat-linux/2.96/crtend.o /usr/lib/crtn.o

 $ ldd a.out
  not a dynamic executable

 $ ls -lt a.out (バイナリのサイズ)
  -rwxr-xr-x 1 kato softek 1837840 Dec 15 21:20 a.out*

PGI の共有ライブラリ libpgc のみを静的にリンクし、gnu ライブラリを動的にリンクする方法

まず、最初に pgi のコンパイラ・コマンドのオプションに -# をつけて、各コンパイルフェーズの手続きの詳細オプションを調べます。特に、PGI によって出力された ld リンカのオプションを含むコマンド列をコピーする。このコマンド列を修正して、直接リンクの実行を後で行います。次に、コンパイルコマンドで、リンクを行わず、プログラムのオブジェクト(上記の例では、test.o)を作成します。作成された test.o を使用し、静的、動的ライブラリを適宜オプションとして指定し、ld コマンドで実行モジュールを作成します。この具体的な例を以下に示します。

 $ pgf77 -c test.f (test.o のオブジェクトファイルを作成)

次に、 ld コマンドを直接操作します。リンカのオプションの中で、ライブラリの指定を動的なものと、静的リンクが必要なライブラリとを区別して指定します。

 $ /usr/bin/ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/crtbegin.o /export/pgi524/linux86/5.2/lib/pgfmain.o -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 test2.o -L/export/pgi524/linux86/5.2/lib -L/usr/lib -L/usr/lib/gcc-lib/i386-redhat-linux/2.96 -rpath /export/pgi524/linux86/5.2/lib -lc -lm -lgcc -lc -lgcc /usr/lib/gcc-lib/i386-redhat-linux/2.96/crtend.o -Bstatic -lpgftnrtl -lnspgc -lpgc -lc /usr/lib/crtn.o

上記の例で言えば、動的なライブラリとして構成する gnu のライブラリ系を -lc -lm -lgcc -lc -lgcc として指定し、PGI のランタイムライブラリを -Bstatic -lpgftnrtl -lnspgc -lpgc として静的リンクオプション -Bstatic の後に指定することによって、期待する結果が得られます。

 $ ldd a.out (PGI の共有ライブラリ libpgc.so はリンクされていないことを確認)
  libc.so.6 => /lib/i686/libc.so.6 (0x40033000)
  libm.so.6 => /lib/i686/libm.so.6 (0x4016e000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

 $ ls -lt a.out (ファイルのサイズ)
  -rwxr-xr-x 1 kato softek 74630 Dec 15 21:21 a.out*
 $ strip a.out (シンボルテーブルの削除)
 $ ls -l a.out 
  -rwxr-xr-x 1 kato softek 48960 Dec 15 21:21 a.out

pgf77(pgf95/pgcc) のコマンドオプションで、を実現する方法

PGI コンパイラでは、リンカに対して渡す引数オプションとして、-Bdynamic と -Bstatic があります。それぞれ、それ以降指定されるライブラリを動的ライブラリとしてリンク、あるいは静的ライブラリとしてリンクするように指示するものです。このオプションを指定して、上記のことを実現するには、以下のようなコマンド列を作成することで実現します。リンクすべきライブラリの種類は、 -# オプションで確かめてから、以下のような形態で使用することが必要です。

 $ pgf90 test.f -Bdynamic -lc -lm -lgcc -lc -lgcc -Bstatic -lpgftnrtl -lnspgc -lpgc

 $ldd a.out
  libc.so.6 => /lib/i686/libc.so.6 (0x40033000)
  libm.so.6 => /lib/i686/libm.so.6 (0x4016e000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

ァ‐紊竜’修鬟灰鵐僖ぅ襯プションで実現する方法(PGI 6.2以降)

PGI が提供する専用ライブラリは静的リンクで行い、Linux のシステム依存ライブラリは、ダイナミックにリンクさせるためのオプション(-Bstatic_pgi)が PGI 6.2 から提供されました。このオプションで生成された実行モジュールは、他の Linuxシステム(OS の glibcバージョン等が同じもの)においても、PGIが提供する専用シェアードライブラリをコピーすることなく実行できる利点があります。

 $ pgf95 -fastsse -Bstatic_pgi test.f


<< 戻る


 ソフテックは、PGI 製品の公認正規代理店です

サイトマップ お問合せ
Copyright 2004 SofTek Systems Inc. All Rights Reserves.