* .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などで再コンパイルする必要がありますか?
共有ライブラリを作成するときは、-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
フラグを使用してコンパイルされていることを確認してください。そうでない場合、通常は共有ライブラリに埋め込むことができません。
何らかの形で動的ライブラリーに入るコードは、再配置可能にする必要があります。これは、静的または動的に関係なく、.soにリンクされているすべてのものを-fPIC
でコンパイルする必要があることを意味します。特に、静的sqlite
ライブラリも-fPIC
でコンパイルする必要があります。
PICの意味の詳細はこちら: http://en.wikipedia.org/wiki/Position-independent_code
私も同じ問題を抱えていました。どうやら-staticは-Bstaticと同じではありません。 -Bstaticに切り替えたところ、すべてが機能しました。