静的/動的ライブラリーの名前を決定します。

静的/動的ライブラリーの名前を決定します。

私は多くの場合、Unix / Linux Cライブラリ(たとえば)を使用するサードパーティのCコードスニペットで作業することがよくあります#include <glib.h>。たとえば#include <net/if.h>、特定のライブラリファイル名またはpkg-config名を知る必要があります。 「2.0」、「1」のヘッダファイルが異なるため、推測できません。-lglib-2.0-lbluetoothpkg-config --libs dbus-1

API /ライブラリが所有するライブラリファイルの正確な名前をどのように見つけることができますか?上記の例では、#include <glib.h>ライブラリファイルの名前をどのように見つけることができますか-lglib-2.0?残念なことに、Glib / dbus / allへのオンライン参照には、「ライブラリファイル名はglib-2.0です」としか記載されていません。

これを把握するために使用できる端末コマンドはありますか?これを見つけるために使用できるユーティリティはありますか?オンラインAPI /ライブラリ参照はこれを見つけるのに本当に悪いです。

場所を見つけたい場合は、hci.h簡単に見つけることができますlocate hci.h。ライブラリ名を探す端末コマンドのようなものはありますか?

答え1

特定の機能を使用するためにどのライブラリが必要かを知るための一般的な方法はありません。このライブラリのドキュメントを確認する必要があります。よく書かれたチュートリアルやAPIリファレンスは、これが何であるかを教えてくれます。

少なくとも図書館が何であるかは理解できます。パック必須:ヘッダーファイルを含むライブラリパッケージと同じです。ヘッダーファイルを含むパッケージを確認する方法は、ディストリビューション(dpkg -S /usr/include/glib-2.0/glib.hDebian/Ubuntu/Mint/...、rpm -qf /usr/include/glib-2.0/glib.hRHEL/CentOS/Fedora/...など)によって異なります。ライブラリパッケージがわかったら、その内容を一覧表示して埋め込み.soファイルを見つけます。

dpkg -L libglib2.0-dev | grep '\.so$'
rpm -qlf /usr/include/glib-2.0/glib.h | grep '\.so$'

Glibには複数の.soファイルがあり、特定の機能にどのファイルが必要かを自動的に知る方法はありません(複数のファイルがある可能性があります)。

ライブラリでそれを使用する場合は、pkg-configヘッダーとライブラリパスをハードコードする代わりにそれを使用する必要があります。しかし、すべての図書館がそれを使用するわけではありません。ディストリビューションのライブラリパッケージは、そのpkg-configパッケージ(たとえばdpkg -s libglib2.0-dev |grep '^Depends:.*pkg-config')に依存する必要があるため、一般的に理解できます。

ドキュメントが本当に不都合な場合は、ライブラリで定義したシンボルを一覧表示してみてください。

nm -D /usr/lib/x86_64-linux-gnu/libgio-2.0.so |awk '$2=="T" {print $3}'

他のライブラリが必要かどうかを知らないので、これは完璧な方法ではありません。

答え2

これらの#include命令はCプリプロセッサによって拡張されます。検索パスはコンパイラ(-I<dir>フラグなど)によって制御されます。生成されたオブジェクトファイルにシンボルを提供します。

その後、リンカはルールを使用してこれらのシンボルをアーカイブ/オブジェクトファイルにマッピングします。同様のフラグが与えられると、-l<namespec>リンカはライブラリパスlib<namespec>.aまたはのディレクトリから検索しますlib<namespec>.so。リンカは生成されたバイナリにこれらのファイル名を含め、動的リンカは実行時にこれらのファイル名を使用してシンボルを実際の実装として解釈します。

検索ディレクトリを使用してコンパイラリンカを見つけることができますld --verbose | grep SEARCH_DIR。たとえば、次は、リンカがライブラリ名をファイルにマップする方法をおおよそのシミュレートします.so

$ libname=glib-2.0; ld --verbose |  grep SEARCH_DIR |  tr -s ' ;' '\n' |  sed 's/SEARCH_DIR("=\?\(.*\)")/\1/g' |  xargs -I{} find {} -maxdepth 1 2>/dev/null | grep lib${libname}.so
/usr/lib/libglib-2.0.so.0.7000.0
/usr/lib/libglib-2.0.so
/usr/lib/libglib-2.0.so.0

(これらはすべて同じファイルへのシンボリックリンクです。)

パッケージマネージャでこのファイルを提供するパッケージを見つけることができますyum。たとえば、次のようになります。

$ yum whatprovides /usr/lib64/libglib-2.0.so.0

glib2-2.68.1-1.fc34.x86_64 : A library of handy utility functions
Repo        : fedora
Matched from:
Filename    : /usr/lib64/libglib-2.0.so.0

glib2-2.68.4-1.fc34.x86_64 : A library of handy utility functions
Repo        : @System
Matched from:
Filename    : /usr/lib64/libglib-2.0.so.0

glib2-2.68.4-1.fc34.x86_64 : A library of handy utility functions
Repo        : updates
Matched from:
Filename    : /usr/lib64/libglib-2.0.so.0

次のコマンドを使用してシンボルを表示できますnm

$ nm -D --defined-only /usr/lib/libglib-2.0.so.0
0000000000070000 T g_access
000000000001d600 T g_allocator_free
000000000001d5f0 T g_allocator_new
0000000000022810 T g_array_append_vals
000000000001e3a0 T g_array_binary_search
...

リンカの規則はに文書化されていますman ld

最後に、ご質問にお答えします。これらのメカニズムは実際の実装からヘッダーを分離するように設計されているため、設計上のヘッダーをオブジェクト/アーカイブにマッピングする一般的な方法はありません。結局のところ、.soシンボルを実装するファイルを見つける必要があります#include。他の答えで述べたように、これは一時的です。

ただし、パッケージマネージャは通常ヘッダファイルを提供するパッケージであり、<package>-develそのパッケージは<package>共有オブジェクトを提供するので、多くの役に立ちます。たとえば、yumこれを使用して開発パッケージを見つけることができます。

$ yum provides '*/glib.h'

glib-devel-1:1.2.10-62.fc34.i686 : Libraries and header files for glib development
Repo        : fedora
Matched from:
Filename    : /usr/include/glib-1.2/glib.h

glib-devel-1:1.2.10-62.fc34.x86_64 : Libraries and header files for glib development
Repo        : fedora
Matched from:
Filename    : /usr/include/glib-1.2/glib.h

glib2-devel-2.68.1-1.fc34.i686 : A library of handy utility functions
Repo        : fedora
Matched from:
Filename    : /usr/include/glib-2.0/glib.h

...

glib2-develパッケージにヘッダファイルが提供されていることがわかります。したがって、glib2パッケージはその.soファイルを提供し、そのファイル名で使用するフラグが何であるかを知ることができます-l

$ repoquery -l glib2 | grep '.so'

/usr/lib/libgio-2.0.so.0
/usr/lib/libgio-2.0.so.0.6800.4
/usr/lib/libglib-2.0.so.0
/usr/lib/libglib-2.0.so.0.6800.4
...

したがって、考慮すると、glib.h少なくとも使用する必要があることがわかります-lglib-2.0

関連情報