共有ライブラリをビルドするときの-fPICの意味は?


109

' -fPIC'オプションがアドレスの解決と個々のモジュール間の独立性に関係していることは知っていますが、それが本当に何を意味するのかわかりません。説明できますか?


1
さらに詳しく知りたい場合は、こちらの素晴らしい記事(akkadia.org/drepper/dsohowto.pdf)をご覧ください
MJ

回答:


61

PICは位置独立コードの略

そして引用するman gcc

ターゲットマシンでサポートされている場合は、動的リンクに適し、グローバルオフセットテーブルのサイズの制限を回避する、位置に依存しないコードを発行します。このオプションは、m68k、PowerPC、およびSPARCで違いをもたらします。位置に依存しないコードは特別なサポートを必要とするため、特定のマシンでのみ機能します。

これらのアーキテクチャーで共有オブジェクト(* .so)を構築するときにこれを使用します。


1
fは何も意味せず、オプション名の一部にすぎません。
Zifre 2009年

17
fpicとfPICには違いがあります。どちらも同じことを行いますが、fpicは、可能な場合はより短い相対オフセットを使用します。したがって、fpicを使用してコンパイルすると、ファイルが小さくなる可能性があります。残念ながら、期待どおりに動作しない場合があるため、fPICを使用してください。また、すべてのプロセッサが短いオフセットをサポートしているわけではないため、違いが生じない場合があることに注意してください。
マーティンヨーク

2
'f'は、gccがコマンドライン引数を引き継いだ方法からの二日酔いです(これは数年前で、最近見たことがないコードのこの部分が変更されました)。しかし、当時はさまざまな条件下で特定の文字または組み合わせのみが許可されていました(コマンドライン引数を定義するための非常に複雑な言語がありました)。その結果、 'f'を使用してコマンドライン引数として簡単に定義できました。
マーティンヨーク

2
fPICなしで* .soをビルドするとどうなりますか?
Isa A

2
@IsaA今日、ソースからc-api mysql関数をコンパイルしていましたが、ビルドできませんでした。そのため、/usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPICfPICを追加してビルドしました。
chiliNUT

32

これfは、「コード生成で使用されるインターフェース規則を制御する」オプションのgccプレフィックスです。

PIC「Position Independent Code」の略で、fpicm68KとSPARCを専門にしたものです。

編集:0x6adb015によって参照されるドキュメントの 11ページ、およびcoryanによるコメントを読んだ後、いくつかの変更を加えました。

このオプションは共有ライブラリにのみ意味があり、OSにグローバルオフセットテーブルGOTを使用していることを伝えています。つまり、すべてのアドレス参照はGOTに関連しており、コードは複数のプロセス間で共有できます。

それ以外の場合、このオプションがないと、ローダーはすべてのオフセット自体を変更する必要があります。

言うまでもなく、ほとんど常に-fpic / PICを使用します。


1
OSは任意の仮想アドレスにライブラリを自由にロードできると思いましたが、pic / PICがないと、ローダーはコードを変更し、すべての絶対ジャンプ+ルーチン/ライブラリの実際の場所への間接参照を調整する必要があります。pic / PICではコードは変更されないため、実際には複数のプロセス間で共有されます。
コリアン09年

複数のプロセスはほぼ偶然です。重要な点は、コードを絶対最小のアドレス修正で任意の仮想アドレスにロードできることです。
ジョナサンレフラー

16

man gcc 言う:

-fpic
  共有での使用に適した位置独立コード(PIC)を生成する
  ライブラリ(ターゲットマシンでサポートされている場合)。そのようなコードはすべてにアクセスします
  グローバルオフセットテーブル(GOT)による定数アドレス。ダイナミック
  ローダーは、プログラムの起動時にGOTエントリを解決します(動的
  ローダーはGCCの一部ではありません。オペレーティングシステムの一部です)。もし
  リンクされた実行可能ファイルのGOTサイズがマシン固有のサイズを超えています
  最大サイズ、リンカからエラーメッセージが表示されます
  -fpicは機能しません。その場合は、代わりに-fPICを使用して再コンパイルしてください。
  (これらの最大値は、SPARCでは8k、m68kおよびRS / 6000では32kです。
  386にはそのような制限はありません。

  位置に依存しないコードには特別なサポートが必要なので、
  特定のマシンでのみ機能します。386の場合、GCCはPICをサポートします
  System Vですが、Sun 386i用ではありません。生成されるコード
  IBM RS / 6000は常に位置に依存しません。

-fPIC
  ターゲットマシンでサポートされている場合は、位置に依存しないコードを発行します。
  動的リンクに適しており、サイズの制限を回避します
  グローバルオフセットテーブル。このオプションは、m68kに違いをもたらします
  そしてSPARC。

  位置に依存しないコードには特別なサポートが必要なので、
  特定のマシンでのみ機能します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.