web-dev-qa-db-ja.com

C ++静的リンク共有ライブラリ

* .soオブジェクトを必要とする私の制御を超えた別のアプリケーションによって使用される共有ライブラリがあります。私のライブラリは、静的にリンクする必要があるsqlite3を使用しています(完全に自己完結型のバイナリが必要です)。

ライブラリをコンパイルしてリンクしようとすると:

-fpic -flto -pthread -m64
-flto -static -shared

次のエラーが発生します。

/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status

-fPICでの再コンパイルとは何ですか?私のコードまたはCRT?

同じ結果で-fPICを使用してオブジェクトをコンパイルしようとしました。

ありがとう。

編集:

問題はSQLite3に関連しているようではありません。

次のようにコンパイルしてリンクするシンプルな1行で何もしないライブラリを作成しました:

g++ -c -fPIC -o bar.o bar.cpp
g++ -shared -o bar.so bar.o

これは好きではありません:

g++ -c -fPIC -o bar.o bar.cpp
g++ -static -shared -o bar.so bar.o

問題はCRT(crtbeginT.o)に関連しているようです。GCCを--with-picなどで再コンパイルする必要がありますか?

26
Petr

共有ライブラリを作成するときは、-staticフラグを使用しないでください。静的にリンクされた実行可能ファイルを作成するためです。

ライブラリの静的バージョンしかない場合は、-lsqlite3を使用してリンクするだけです。ただし、動的バージョン(.so)と静的バージョンの両方がある場合、リンカーは動的バージョンを優先します。

リンカに静的なものを選択するように指示するには、リンカに-Bstaticフラグを指定し、-Bdynamicを使用して他の機能(libcや動的ランタイムサポートなど)の動的リンクに戻すようにします。つまり、フラグを使用します。

 -Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic 

別の方法として、.aファイルの完全パスを指定することもできます。コンパイラ/リンカーフラグの代わりに/usr/lib/libsqlite3.a

GNU ldでは、-l:libsqlite3.aの代わりに-lsqlite3を使用することもできます。これにより、リンカがデフォルトで優先するlibsqlite3.aの代わりにライブラリファイルlibsqlite3.soが強制的に使用されます。

.aファイルが-fpicフラグを使用してコンパイルされていることを確認してください。そうでない場合、通常は共有ライブラリに埋め込むことができません。

39
nos

何らかの形で動的ライブラリーに入るコードは、再配置可能にする必要があります。これは、静的または動的に関係なく、.soにリンクされているすべてのものを-fPICでコンパイルする必要があることを意味します。特に、静的sqliteライブラリも-fPICでコンパイルする必要があります。

PICの意味の詳細はこちら: http://en.wikipedia.org/wiki/Position-independent_code

8
vines

私も同じ問題を抱えていました。どうやら-staticは-Bstaticと同じではありません。 -Bstaticに切り替えたところ、すべてが機能しました。

0
Dre