web-dev-qa-db-ja.com

C ++実行可能ファイル(gcc)をビルドするときにリンクされているすべてのライブラリのレポートを取得できますか? (静的リンクを含む)

継承したC++アプリケーションがあり、次のもので構成されています。

  • 私のメインアプリ
  • いくつかのアプリ固有のライブラリ(libapp1、libapp2など)
  • メインアプリ、アプリ固有のlibappXライブラリ、およびその他のサードパーティライブラリの両方からリンクされたいくつかの「サードパーティ」ライブラリ(ほとんどの「サードパーティは、社内の他のチーム」です)。 libext1、libext2など...

つまり、私のコードは次のようになります。

// main.C
#include <app1/a1l1.H>
#include <app2/a2l1.H>
#include <ext1/e1l1.H>

// app1/a1l1.H
#include <app1/a1l2.H>
#include <ext2/e2l1.H>

// app2/a2l1.H
#include <ext2/e2l2.H>

// ext1/e1l1.H
#include <ext3/e3l1.H>

// ext3/e3l1.H
#include <ext4/e4l1.H>

質問:

1)最終的な実行可能ファイルにリンクされているライブラリを確認するにはどうすればよいですか? これには静的にリンクされたものを含める必要があります

つまり、「app1、app2、ext1、ext2、ext3、ext4」という答えが欲しい

理想的には、答えは実行可能ファイル自体から入手できます(より可能にするために、デバッグバージョンが組み込まれています)。それが不可能な場合は、その分析を提供するための簡単なコード分析ツール(つまり、gcc自体の中にある何か)があるかどうかを知りたいのですが。

外部ライブラリのオブジェクトファイルは既にビルドされているので、ビルドログを見て何がリンクされているかを確認してください。「ext3」をビルドしないため、「ext4」がログに表示されないのではないかと心配しています。 "既にビルドされているライブラリ。

注:すべてを再構築するためにDEPSをyesに設定して「nmake」を実行することはオプションではありません。しかし、私は外部ライブラリの完全なソースコードにアクセスできます。

2)少し離れて重要性の低い質問ですが、作成しているソースツリー全体で使用されているすべてのinclude filesのリストをどのように確認できますか?繰り返しますが、理想的には、frmで既にビルドされている実行可能ファイルで、デバッグバージョンがあります。

=================

更新:明確にするために、ライブラリは静的にリンクされているため、ldd(List Synamic Dependencies)は機能しません。

また、答えはSolarisまたはLinuxのどちらでもかまいません。問題はありません。

私はnmを使ってみましたが、ライブラリがリストされていません

22
DVK

私は同様の問題を抱えており、解決策を見つけました:リンク時に-Wl、-verboseオプションを追加します。リンカを冗長モードに切り替えます。

gcc -o test main.o -ltest -L. -Wl,--verbose

次に出力例を示します。

GNU ld (GNU Binutils) 2.23.52.20130604
  Supported emulations:
   i386pep
   i386pe
using internal linker script:
==================================================
/* Default linker script, for normal executables */
[many lines here]
==================================================
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o
attempt to open main.o succeeded
main.o
attempt to open ./libtest.dll.a failed
attempt to open ./test.dll.a failed
attempt to open ./libtest.a succeeded
(./libtest.a)test.o
[more lines here]
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o

pdate: -Wl、-verboseの代わりに-Wl、-traceオプションを使用することもできます。ライブラリのリストも表示されますが、それほど冗長ではありません。

pdate 2: -Wl、-traceは、間接的に含まれるライブラリを表示しません。例:libAとリンクし、libAはlibBとリンクしました。 libBも必要であることを確認するには、-Wl、-verboseを使用する必要があります。

31

直接依存関係の場合。

ldd <app>

間接/すべての依存関係。

ldd -r <app>
10
ismail

私が知る限り、リンク時に静的ライブラリに関する情報はほとんど保持されません(とにかく、リンカーはそのライブラリを* .oオブジェクトのコレクションと見なすだけなので)。

最終的な実行可能ファイルをリンクし、-vフラグを追加するmakeコマンドを見つけた場合、g++は、それがldコマンドを呼び出す方法を正確に示します。これには、他のライブラリによって使用されるライブラリを含む、必要なすべての静的ライブラリが含まれている必要があります。そうでない場合、リンク手順は失敗します。ただし、実際には使用されない追加のライブラリが含まれる場合もあります。

別のおそらく有用なことは、少なくともLinuxでは、オブジェクトと実行可能ファイルは通常、作成元のソースコードファイルの名前を格納することです。 (ファイル名のみ、パスなし。)

objdump -t executable | grep '*ABS*'
4
aschepler

ldd +ファイル名を使用してみてください。これにより、ライブラリがリストされます。

1
kohlehydrat

最初に2つ目の質問にお答えします。 -Hまたは-Mフラグは、コンパイルで処理されたすべての(システムを含む)ヘッダーを表示します。 gcc -H main.cトリックを行う必要があります。含まれているヘッダーを確認することで、実際にリンクされている静的ライブラリを見つけるための正しい道をたどることができます。

最終オブジェクトでobjdump(または最終バイナリでreadelf)を使用して、そこにあるすべての関数の名前を取得できます。次に、関数がプルされたライブラリを探す必要がありますが、それは少し面倒です。間違いなく、最小限のスクリプトでスクリプトを作成する必要があります。

他の誰かがgcc <stuff> -Wl,-verboseは単に-verboseリンカーへのフラグ。これは共有ライブラリ(.soファイル)のリストを取得するのに最適な方法ですが、静的ライブラリであると述べたので、この場合はそうすることはできません。

幸運を!

0
s g