ranlibとは


13

私はしばらくの間MacOSXシステムを使用していますが、つい最近になって根性を突破し始めました。「sudo ranlib/usr/local/lib/libjpeg.a」(libjpegのインストール)を実行するように指示するガイドを見つけました。ranlibのマニュアルを読み、オンラインで見てみました。私は単に理解していません。詳細を調べるには、どのリソースを調べる必要がありますか、またはその使用について簡潔に説明できますか?前もって感謝します!

回答:


7

ranlib追加または更新されたオブジェクトファイルを静的ライブラリ。リンカは、コードが動作するために必要なシンボルを提供するために、リンク時に静的ライブラリを使用できます(ローダーが実行可能ファイルの実行時に動的ライブラリでそれらを探すのとは対照的です)。


こんにちは、イグナシオ、回答ありがとうございます。これは、ライブラリでranlibを実行すると、リンカーが「参照」しようとするたびに使用できることを意味しますか?どうやって取り除くの?
Ying

ranlibライブラリの作成と変更に使用されます。それらを使用するかどうかは、通常、コマンドラインでライブラリの場所や名前を渡すことにより、リンカに委ねられます。詳細については、-Lおよび-lgccの引数を参照してください。
Ignacio Vazquez-Abrams

5
しかし、それarもしませんか?違いは何ですか?
greatwolf 16

18

この説明はかなり明確に見えます:http : //sourceware.org/binutils/docs/binutils/ranlib.html

したがって、オブジェクトファイルのコレクションをアーカイブする場合は、次のようにします。

$ ar r fruits.a apple.o orange.o pineapple.o

その後、実行

$ ranlib fruits.a

fruit.aのコンテンツのインデックスを作成し、fruits.aにインデックスを格納します。これは、リンクやオブジェクトが相互に呼び出す場合に役立ちます。


「ranlibはアーカイブのコンテンツへのインデックスを生成し、それをアーカイブに保存します」。これは組み合わせるもののように聞こえますが、tarあまり明確ではありません。
2018

9

ranlibはアーカイブのコンテンツへのインデックスを生成し、アーカイブに保存します。インデックスには、再配置可能なオブジェクトファイルであるアーカイブのメンバーによって定義された各シンボルがリストされます。このようなインデックスを持つアーカイブは、ライブラリへのリンクを高速化し、ライブラリ内のルーチンがアーカイブ内の配置に関係なく相互に呼び出すことができるようにします。

ソース:ranlib manページ


2

ar

Linuxではar、GNU汎用アーカイバーです。(ar他のUnixライクなOSには、GNU以外のバリアントがあります)。オプション付きc

ar c... archive-name file...

のコピーを含むアーカイブを作成しますfile...archive-name従来は必ずしも必要ではない拡張子がある.a(のためのアーカイブを)。それぞれfile...がオブジェクトファイルである必要はなく、どのような種類のファイルでもかまいません。

アーカイブされたファイルがすべてオブジェクトファイルである場合、通常はアーカイブを使用して、選択したオブジェクトファイルをプログラムまたはDSO(動的共有オブジェクト)のリンケージに配信します。この場合archive-name、従来どおりlib、たとえば libfoo.a、接頭辞が付けられるため、リンカーオプションを介して候補リンカー入力ファイルとして検出できます-lfoo

リンカー入力ファイルとして使用され、libfoo.a通常はスタティックライブラリと呼ばれます。この使用法は、アーカイブlibfoo.aがDSOとほぼ同じ種類のものでありlibfoo.so、通常はダイナミック/共有ライブラリーと呼ばれ、これに基づいて誤った期待を構築するため、熟練していないプログラマーにとっては、絶え間ない混乱の源です。実際、「静的ライブラリ」と「動的ライブラリ」はまったく同じものではなく、まったく異なる方法で連携して使用されます。

顕著な違いは、静的ライブラリはリンカーではなくによって生成されることarです。したがって、リンケージは発生せず、シンボル解決も発生しません。アーカイブされたオブジェクトファイルは変更されていません。バッグに入れられているだけです。

アーカイブは、何かの連携で入力されるとされた未収いる未解決のシンボル参照の定義を提供し、その中に任意のオブジェクトファイルがあるかどうかを確認するために袋の中のリンカーのルックス-このようなプログラムやDSOなど-リンカによって生成しますリンケージの早い段階で。見つかった場合は、それらのオブジェクトファイルをバッグから抽出し、リンカーのコマンドラインで個別に指定した場合とまったく同じようにアーカイブに名前を付けたかのように、それらを出力ファイルにリンクます。したがって、リンケージにおけるアーカイブの全体的な役割は、リンカがリンケージを実行するために必要なファイルを選択できるオブジェクトファイルのバッグとしての役割です。

デフォルトでは、GNU arはその出力アーカイブをリンカー入力として使用できるようにします。偽の「ファイル」を魔法の偽のファイル名でアーカイブに追加します。この偽のファイルには、アーカイブ内のオブジェクトファイルによって定義されているグローバルシンボルからリンカがルックアップテーブルとして読み取ることができるコンテンツが書き込まれます。アーカイブ内のそれらのオブジェクトファイルの名前と位置に。このルックアップテーブルにより、リンカーはアーカイブを調べて、手元にある未解決のシンボル参照を定義するオブジェクトファイルを識別できます。

このルックアップテーブルの作成または更新を抑制するには、q(= クイック)オプション( 実際には独自のar例で使用しています)および(大文字)S(= シンボルテーブルなし)オプションを使用します。またar、何らかの理由で(最新の)シンボルテーブルを持たないアーカイブを作成または更新するために呼び出す場合は、オプションでアーカイブを指定できsます。

ランリブ

ranlibライブラリをまったく作成しません。Linuxにranlibは、(最新の)シンボルテーブルarがない場合にアーカイブに追加するレガシープログラムがあります。その効果はar s、GNU の場合とまったく同じarです。歴史的にarは、シンボルテーブル自体を生成する機能が装備される前はranlib、マジックフォニーファイルをアーカイブに挿入して、リンカーがオブジェクトファイルを選択できるようにするクラッジがありました。非GNU UnixライクなOSでは、ranlibこの目的のためにまだ必要になるかもしれません。あなたの例:

ar qc libgraphics.a *.o
ranlib libgraphics.a

言う:

  • シンボルテーブルを使用せずに、現在のディレクトリ内のlibgraphics.aすべての*.oファイルをアーカイブに追加して作成します。
  • 次に、シンボルテーブルを追加します libgraphics.a

Linuxでは、これは次と同じ正味の効果があります。

ar cr libgraphics.a *.o

それ自体はar qc libgraphics.a *.o、シンボルテーブルがないため、リンカが使用できないアーカイブを作成します。

ld

あなたの例:

ld -r -o libgraphics.a *.o

実際にはまったく正統ではありません。これはかなり稀使用示すリンカーld製造する、マージされたシンボル解決が実行された単一の出力オブジェクトファイルに複数の入力ファイルをリンクすることによってオブジェクトファイルをはるかに可能な限り入力ファイル所与を、。-r(= 再配置可能オプションは、未定義のシンボル参照は出力ファイルに残っている場合linkaqeを失敗する可能な限りとしないように入力をリンクすることによって、オブジェクトファイル(むしろプログラムより、またはDSO)ターゲットを生成するために、リンカーを指示します。この使用法は、部分リンクと呼ばれます。

の出力ファイルはアーカイブld -r ... はなくオブジェクトファイルであり、 ar アーカイブのように見える出力ファイル名を指定しても、ファイル名にarはなりません。したがって、あなたの例は欺瞞を示しています。この:

ld -r -o graphics.o *.o

正直になります。ELFオブジェクトファイルが呼び出されlibgraphics.a、その名前またはによってリンケージに入力された場合でも-lgraphics、リンカーがELFオブジェクトファイルとして正しく識別するため、このような詐欺の目的が何であるかは不明です。arアーカイブではなく、コマンドラインでオブジェクトファイルを使用するのと同じように使用します。無条件にアーカイブを出力ファイルにリンクしますが、本物のアーカイブを入力する目的は、参照されている場合にのみアーカイブメンバーをリンクすることです。たぶん、あなたはここで悪質なリンクの例を持っているだけでしょう。

まとめ...

実際には、ライブラリと呼ばれるものを生成する方法は1つしかありません。これは、いくつかのオブジェクトファイルをアーカイブし、シンボルテーブルをアーカイブに保存する、いわゆるスタティックライブラリの生成です。

また、従来ライブラリと呼ばれていた他の最も重要な種類のオブジェクト、つまり動的共有オブジェクト/共有ライブラリ/動的ライブラリを作成する方法はまったく見ていません。

プログラムと同様に、DSOはリンカーによって生成されます。プログラムとDSOは、OSローダーが理解し、実行中のプロセスをアセンブルするために使用できるELFバイナリのバリアントです。通常、我々は(GCCフロントエンドの1つを介してリンカーを起動しgccg++gfortran、など):

プログラムのリンク:

gcc -o prog file.o ... -Ldir ... -lfoo ...

DSOのリンク:

gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...

-lfoo他のプログラムまたはDSOをリンクする場合、共有ライブラリと静的ライブラリの両方を、統一されたプロトコルによってリンカーに提供できます。そのオプションのいずれかを見つけるために、その指定するか、デフォルトの検索directroriesをスキャンするためにリンカに指示し libfoo.soたりlibfoo.a。デフォルトでは、どちらかが見つかると、そのファイルをリンケージに入力しますlibfoo.so。同じ検索ディレクトリで両方が見つかった場合は、を優先します。場合はlibfoo.so、選択された後、リンカはDSOは、どんなプログラムやDSOの実行時の依存関係リストにあなたが作っていることを追加します。場合はlibfoo.a、選択された右が、その後、必要に応じてリンカは、出力ファイルに結合のためのオブジェクトファイルの選択などのアーカイブを使用しています。ランタイムに依存しない libfoo.aそれ自体は可能です。プロセスにマッピングすることはできません。OSローダーには何の意味もありません。

https://stackoverflow.com/a/47924864/195787からコピー。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.