6

私のプロジェクトは、いくつかの静的ライブラリで構成されており、最終ステップでリンクされています。ライブラリのリンク順序が重要であるという問題があります(そうしないと、未定義のシンボルリンカエラーが発生します)。リンクされたライブラリ (-lcommon -lsetup -lcontrol など) を再ソートする必要があるという問題が発生することがあります。現時点では、再ソート、コンパイル、エラーのチェック、再ソート、コンパイルなどの愚かな試行錯誤です。

そこで、ライブラリ間の依存関係を示し、リンクするライブラリの順序を生成する小さなプログラムを作成しました。nmから定義済み ('T'、'B' など) および未定義のシンボル ('U') を読み込み、弱いシンボル('w'、'W'、'v'、'V')をnmから削除します。 「未定義のシンボル リスト」。現在、未定義のシンボルごとに、それを解決するライブラリを決定します。

しかし、私のプログラムは循環依存関係を示しています...私の間違いは何ですか?

それらが本当に存在する場合、私はまったくリンクできませんでした...それで、nm出力を分析するときに何が欠けていましたか? または、これらの依存関係を取得するために nm 出力を分析する方法はありませんか?

libcommon.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
libhardware.a:
00000484 T _ZN15HardwareUnit23GetHardwareSerialNumberEv
libsecurityaccess.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
---
libhardware.a:
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
libsecurityaccess.a:
00004020 T _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
4

2 に答える 2

6

循環依存関係を持つライブラリをリンクする別のオプションは、そのための特別なリンカー オプションを使用することです。男 ld:

   -( archives -)
   --start-group archives --end-group
       The archives should be a list of archive files.  They may be either
       explicit file names, or -l options.

       The specified archives are searched repeatedly until no new
       undefined references are created.  Normally, an archive is searched
       only once in the order that it is specified on the command line.
       If a symbol in that archive is needed to resolve an undefined
       symbol referred to by an object in an archive that appears later on
       the command line, the linker would not be able to resolve that
       reference.  By grouping the archives, they all be searched
       repeatedly until all possible references are resolved.

       Using this option has a significant performance cost.  It is best
       to use it only when there are unavoidable circular references
       between two or more archives.

ただし、循環依存関係を排除する方が常にクリーンです。

于 2011-01-24T12:29:17.270 に答える
2

静的ライブラリの循環依存チェーンが本当にある場合(これは貼り付けからは明らかではありません。非循環依存のみを表示します)、2つのオプションがあります。

  1. どういうわけか循環依存を削除します。たとえば、libcommonがlibpthardwareのシンボルを参照しないようにすることができます。
  2. .aライブラリから個々の.oファイルを抽出し、それらを直接リンクします。そうすれば、リンクの順序は重要ではなくなります。

2.の場合、静的ライブラリを作成するのではなく、部分的なリンクを使用すると便利な場合があります。GNU bintoolsを使用するシステムでは、これは次のようなものを呼び出すことによって実行できます。

ld -r -o libfoo.o foo.o bar.o

これにより、foo.oとbar.oが1つの.oファイルに結合されます。順序は関係ありません。その後、最後のリンク手順でlibfoo.oを通常のオブジェクトファイルとして参照するだけです。

これを行うと、静的ライブラリの参照されていない部分を破棄するリンカーの機能が妨げられる可能性があることに注意してください(通常、これは.a内の.oファイルのレベルで行われます)。これらのライブラリのすべてまたはほとんどを使用している場合、これはおそらく問題ではありません。ただし、コードメモリが問題になる場合は、関数レベルで未使用のコードを自動的に破棄することを検討することをお勧めします。これを行う場合は、リンクの最終段階でのみ合格--gc-sectionsします(デバッグが必要な場合は、これを避けてください)。また、システムライブラリとの静的リンクは、最新のgccでは必要ないようです。-s

于 2011-01-24T08:27:00.560 に答える