選択的静的リンクで図書館の機能は共有ライブラリ
-
13-09-2019 - |
質問
をしたいと思っている共有ライブラリを使用する機能から第3者による静的ライブラリ。例えば、 foo
や bar
から libfoobar.a
.もしかすると主な用途でも使用してい foo
ま輸出するシンボルです。いるだけであるリンク bar
保存コードのサイズや休'foo'未解決のとして提供する主なものとします。場合を含みます libfoobar.a
, のリンカー ld するとともに、私共図書館があります。ばんなど libfoobar.a
, 私の図書館にないアクセス機能 bar
ので、アプリケーション自体はリンク bar
.ご質問:
- はしてもらえると助かりますか ld みを解決する記号をビルドする際には、共有ライブラリが含?
- 番
libfoobar.a
共有のですか? - エキスを含むファイル機能
bar
からlibfoobar.a
指定したリンカーがかかってしまいます。 - 気にしないことで、実行時のローダを使用
bar
アプリケーションのコピーbar
には、共有ライブラリが含まれないロード?
解決
以下の点につめの質問に答えたリ:
- ld いないであろうということができますを省略するリンクの特徴から静的ライブラリ。の利用
--just-symbols
または--undefined
またはEXTERN
リンカスクリプトコマンド)を妨げない限りにおいて ld からのリンクのシンボルといえる。 に変換するには静的ライブラリ, libfoobar.a, は、共有、 libfoobar.います。1.0, で、輸出全に可視にならない。も利用できます
--version-script
その他の方法で輸出のみサブセットの記号です。ld -shared -soname libfoobar.so.1 -o libfoobar.so.1.0 --whole-archive libfoobar.a --no-whole-archive
その 削除 アーカイブの会員からの コピー の静的ライブラリで抽出してはいられない内部の依存関係を置くことができます.例えば、仮において輸出の全ての号を生成することができ、マップファイルからの主な実行形式にまとめたものです。そのgrepすべてのアーカイブのメンバーの実行可能な引からのコピーを静的ライブラリを削除してからコピーします。なおバリアフリー支援室は、リンクの静的ライブラリで、同じ記号解決されていない。
を指定することが可能でメインの実行ファイルとして共有ライブラリのためのご支援室の場合はコンパイル、実行ファイルの
--pie
オプションです。おバリアフリー支援室のリンク先をご実行可能な場合の前には静的ライブラリのリンクのコマンドです。の点に注意することを主な実行可能なアクセス可能LD_LIBRARY_PATH
または-rpath
.さらに、 strace それは、実行可能で依存関係の図書館で読み込み時に改めておバリアフリー支援室ます。ld -shared -rpath '$ORIGIN' -L. -lc -ldl -o DSO.so DSO.o app libfoobar.a
動的リンカーの利用実行ファイルのバージョンの foo 第場合を除き電話 dlopen() の
RTLD_DEEPBIND
フラグ。を使用 strace その全体をバリアフリー支援室でマップされたどのファイル mmap2() に示しますしかし、Wikipediaの請求が受け"の読み込みディスクから行"lazy"にした後、特定の場所でご利用いただけます。" このような場合は、その複製 foo はロードされます。なお、オーバーライドのみが起こる場合はバリアフリー支援室 輸出 の機能 foo.その他の機能 foo した静的にリンクへのバリアフリー支援室まで使用する場合は必ずごバリアフリー支援室電話 foo.
その結果、場合に 受() 使用流を読み、その値段が高くなりますが、リンク先はバリアフリー支援室は、通常のように動的にリンカーおよびlinuxのついてご覧いただけます。
他のヒント
私は共有ライブラリ上で最大の専門家ではないので、私がここで間違っている可能性があります!
私はあなたが何をしようとして権利について推測している場合は、、ちょうどlibc.so.に対するあなたの共有ライブラリをリンクしますあなたはあなたのライブラリーに組み込まれたsscanf関数の余分なコピーを望んでいない。
私は非常にあなたが答えに興味を持っている場合には、になっていたものを考え出した前に私はあなたの質問に答えます。
共有ライブラリを構築するときにのみ、特定のシンボルを解決するために、LDを伝える方法はありますか?
のみにextern、静的ではなく、関数や変数は、共有ライブラリのシンボルテーブルに行きます。
あなたの共有ライブラリを構築する場合、、リンカコマンドラインでオブジェクトにないシンボルが未解決のままになります。リンカはそのことについて文句を言うならば、あなたはおそらく、の共有のlibcのに対してあなたの共有ライブラリをリンクする必要があります。あなたは、他の共有ライブラリに依存して共有ライブラリを持つことができ、ld.soは、依存関係のチェーンを扱うことができます。
私はより多くの担当者がいた場合は、、私はコメントとしてこれをお願いしたいです: あなたはsprintfの/ sscanf関数のカスタマイズバージョンを持っていますか、またはあなたの共有ライブラリが-lcで実装を使用することは大丈夫でしょうか? -lcに問題がない場合は、その後、私の答えは、おそらくあなたの問題を解決します。いない場合、あなたはあなたが必要とする機能を持っているオブジェクトのうち、あなたの共有ライブラリを構築する必要があります。すなわち/usr/lib/libc.aに対してそれをリンクしません。
たぶん私はあなたの
で混乱していますlibc.aは(ない実際には "本物" のlibc) ライン。 /usr/lib/libc.aは本当に(Linuxの場合)のglibcです。それはlibc.so.に同じコードの静的にリンクされたコピーですあなたは(私が最初に考えていたものです)あなた自身のlibc.aの話をしている場合を除き...
共有ライブラリにlibc.aはターン? あなたはおそらくすることができますが、それはおそらく、位置独立コードとしてコンパイルされていないので、いないので、それは実行時にld.soによって再配置の多くを必要となります。
のlibc.aからのsscanfを抽出し、リンカライン上でそれを指定する?
ことも可能です。内容を一覧表示するARのトンの/usr/lib/libc.a。 (ARの引数は、ここではテープ....オールドスクールUnix用のARタール。タールに似たです。)おそらくそれは容易ではない、sscanf関数は、おそらく.A内の他の.oファイル内のシンボルに依存するためます。
あなたの改訂よりクリアな質問に答えるます。
通常、共有ライブラリのポイントは、複数のプログラムがそれに対してリンクできるということであることに留意してください。メインプログラムは常にそのシンボル(静的libにまたは別の方法)を提供する場合あなたが必要とする機能のために、メインプログラムのシンボルを使用してのあなたの最適化はのみ動作します。これは、人々が何をしたいのか、通常ではありません。
それはほんの小さな関数だ場合は、おそらくあなたはそれがあるようにする必要があります。おそらく、関数のコードの2つのコピー、あなたのshlibの内の1つの、メインプログラムの1になってしまいます。彼らは頻繁にではなく、パフォーマンス・クリティカルと呼ばれる小さい(あるいは、少なくともではない巨大な)、またはしていない場合は、その後、2つのコピーを持っていることから、コードサイズ/ I-キャッシュヒットは心配するものではありません。 (翻訳:私は私の頭の上をそれそれを回避する方法がわからないので、私はそれを見て、それを避けるために、より複雑なMakefileを作るには時間がかかるしない場合があります)。
静的ライブラリからのものを抽出するために、ARをいじりにいくつかのコメントのために私の他の回答を参照してください。要約:おそらく非自明な、あなたは.A内のさまざまな.oファイル間の依存関係を知らないので、
。共有ライブラリが、それは静的ライブラリからプルのシンボルをエクスポートすることによって、あなたが望んでいるものを行うことも可能です。あなたがメインのアプリをリンクする際に続いて、リンカコマンドラインで静的libにする前に、共有ライブラリを置きます。 ldはあなたのshlibの中で「foo」を見つけ、(この再輸出トリックが可能な場合)、そのコピーを使用していますが、「バー」のためには、静的libにからのコピーを含める必要がありますされます。
LD --export-ダイナミックを使用すると、動的シンボルテーブル内のすべてのシンボルをエクスポートするために必要なものかもしれません。それを試してみてください。そして、ドキュメント/ manページで「エクスポート」を検索してください。 「輸出は、」ライブラリ内のシンボルを可視化のための専門用語です。 --export-すべてのシンボル、それ以外の場合は、おそらくトリックを行うだろう、i386のPE(WindowsのDLL)セクションにあります。