Linuxのライブラリをコンパイルするには、奇妙な間違いを発見し解決されました

共有オブジェクトを作成するときにシンボルに対して再配置R_X86_64_PC32 `_ZTVN9xxxxxE」を使用することができません。

 

Linuxのコンパイラのダイナミックリンクライブラリ、私は、非常に奇妙な、次のエラーメッセージが表示されます。調査の後、決定問題は、コード自体はありません

/ usr / binに/ LD:./xxxxx.o:共有オブジェクトを作成するときにシンボルに対して再配置R_X86_64_PC32 `_ZTVN9xxxxxE」を使用することができません。-fPICで再コンパイル
メイク:49:失敗した'libxxxxx.so'ターゲットのためのレシピ
は/ usr / binに/ LD:最后的链结失败:错误的值
collect2は:エラー:ldは1つの終了ステータスを返しました

オンラインチェックまたは追加するには、画面の指示に従ってください-fPIC

これはおそらく、翻訳パラメータの欠如を意味-fPIC

メイクファイルの方法がある場合は、あなたが、GCCに直接増やすの.o注意することができますファイルは、以下のようにする場合、また、.soの中に包装バックに、追加する際に生成されます。

$ gccの-FPIC -c hello.cを

$ gccの-FPIC -c main.cの

$のgcc -shared -fPIC -oハローhello.o main.o 

 

しかし、私はそうも++のgccグラムで使用日食でコンパイルされたファイルだった、-fPICを追加するためのものです

ソリューション:

1.プロジェクトを選択し、右クリックして[プロパティ]を選択します

。2. C / C ++ビルド- [設定] -ツール設定

3. :(増加は下図-fpic、2、ケースへのこだわりがあり、スペース)

 

 

 

 

 

さて、あなたは、することができます再コンパイル。

 

しかし、あなたはこの問題を解決するためのオプションがあるようにEclipseが見え慎重に見つけることがあります。図:

 

 

非常に奇妙な、フックは、ここでは有用ではありません。私は何の理由を知りません。

オンライン設定は、環境変数にコマンドを直接のようなもちろん引数が見えている、次のことができるように、そうすべき変化にないすべてのプロジェクトの変更

 

さらに読書:-fPIC(以下は、インターネットからの抜粋である、非常に詳細に書かれています)

PICコードは独立した位置の作業で

、真の意味でのコードセグメントの.soファイル共有に変更を加えるPIC 

あなたは-fPICを追加しない場合は、コードセグメントの.soファイルがロードされ、スニペットで参照データオブジェクトは再配置を必要とする、

再配置が変更されますコードセグメントの内容

本の.soファイルコピー処理が、カーネル内のコード・セグメントの.soファイルを生成し使用するために、各コードセグメントをもたらした。各コピーは.soのファイルのコードとデータに応じて、異なります位置セグメントメモリマップ。

(それがコード位置独立コードの内部ではないので)、コンパイラがそのように、再び再び移転ロード装填位置に応じFPICことなく
、複数のアプリケーションが共通に使用される場合、それらは、各プログラムのコピーがそうするためのコードで維持しなければなりません。(各プログラムのようにロードされた位置は明らかに異なっているので、再配置が異なっているこれらのコードの後に、当然のことながら、共有することはできません)
私たちはいつもFPICを生成するために使用しますまた、生成するのにFPICを使用されることはありません。
FPICダイナミックリンクは同じがFPICをコンパイルすることはできませんlibc.soが、基本的には関係ないと言うことができるとき、ちょうどそうので、ユーザプログラムのアドレス空間にロードする必要があります すべてのエントリをリダイレクトします。

そのため、FPICので、コンパイルされていない、常に悪いことではありません。
あなたは、以下の4つの要件/条件満たしている場合:
1.ライブラリは、頻繁に更新する必要があるかもしれ
2.ライブラリが非常に高い効率(と特にが必要です多くは)世界的な量を使用する
ライブラリは素晴らしいではありません3。
4.基本的なライブラリは、複数のアプリケーションで共有する必要はありません。

このパラメータは、共有ライブラリのコンパイル後に追加されていない場合は、使用することができ、それは2かもしれ理由:
1:gccのオプションはデフォルトで有効になっている-fPIC 
2:ローダーあなたの位置に依存しないコードを作ります

GCCの観点から、共有FPICオプションが含まれなければならないが、それはそうシステムがサポートされていないようですので、明示的にFPICオプションを追加することをお勧めします。下記参照


-shared ` ' 
     、他とリンク可能な共有オブジェクトプロデュース
     実行可能ファイルを形成するためにオブジェクトを。ないこのすべてのシステムがサポート
     オプションをザを予測可能な結果のために、あなたはまた、同じでMUSTを指定して
     コードを生成するために使用されたオプションのセットを( -fpic `「` -fPIC」、
     またはモデルのサブオプション)あなたは、このオプションを指定した場合。(1)


-fPIC使用し、それ以外の場合は、達成することができない、動的にリンクされたの目的を達成するために、PIC用の.so要件をPICコードを生成します。ダイナミックリンク。

非PIC PICコードは、主に、異なるアクセスグローバルデータ、のジャンプラベルが異なります。
このようなコマンドとしてアクセスグローバルデータは、
状況は非PIC:LDのR3、VAR1の 
PICはの形である:VAR1オフセット@、LD r3の GOT、 ローカルテーブルインデックスがでVAR1オフセット得たことを意味
負荷を示すアドレス値、即ち4バイトVAR1オフセット@はVAR1アドレスに実際に得ました。このアドレスは、実行時にのみ知られている、ダイナミック・ローダー(ld-linux.so)に行くことで満たされています。

別の例ジャンプラベルの指示
非PICの状況は次のとおりです。printf関数を呼び出すことを意味し、ジャンプのprintf、。
PICは、の形式である:ジャンプ、GOT @ printfのオフセット
で示すGOTジャンプアドレステーブルインデックス意味実行するローカルのprintfをオフセット
.PLT部に配置されたアドレスのコードの、
外部関数の各printfのオフセットGOTローカルテーブルインデックスのアドレスに書き込まれ、その関数の関数(この場合のprintf)のアドレスを見つけるために、ダイナミック・ローダ(ld-linux.so)を呼び出すことで、このコードセクション、に対応する、及び
この機能を実行している間。このように、第二コールのprintfと彼らがルックアップすることなく、printf関数のアドレスに直接ジャンプします。

GOTは、テーブル、データ部であるエントリは、各エントリの内容を再度実行することができる場合を除き、いくつかの特別な修正、
PLTは、テキストセクションであり、コードのセクション、実行を修正する必要があります。
PICを達成するために、各ターゲットの異なるメカニズムが、非常に多くのと同じ。例えば、MIPSなしの.pltが、呼び出され.stub、機能および.PLT同じ。

目に見える、ダイナミックリンクは非常に複雑な静的にリンクされた実行時間より長く実行しますが、サイズが大幅に節約、PICと動的リンク技術は、コンピュータにおけるマイルストーンの歴史の中で非常に重要な進展です。

GCC manulは、上記述べている
連結用GOTサイズ場合-fpic (その場合-fPIC ;.動作せず、代わりに-fPICと再コンパイルすることを示す実行可能ファイルがマシン特有の最大サイズを超えて、あなたは、リンカーからエラーメッセージを取得します8Kはm68kの上のこれらのSPARCザ及び32K ONの上限であり、386のRS / 6000はそのような制限があります。)

の場合のために-fPICターゲットは、マシンをサポートダイナミックリンクザONに適した独立EMIT位置コード、および任意の回避を制限しますグローバルオフセットテーブルのサイズは。このオプションは、m68kの、PowerPCとSPARC上の違いになります。位置独立コードは、特別な支援を必要とするためにのみ、特定のマシン上で動作します。 

キーは、GOT内部グローバルオフセットテーブルエントリのサイズをスキップです。
Intelプロセッサは4バイトには問題はない、均一でなければなりません。
原因のPowerPCアセンブリコードまたはマシンコードの特殊な要件のために、それは、短期および長期2種類に分岐されます。

メモリを節約するために-fpicは、ここで「短い」長さを予約しました。
-fPICは大きなジャンプのアイテムを使用しています。

  

 

 

おすすめ

転載: www.cnblogs.com/winafa/p/11654789.html