Linuxの共有ライブラリを理解する


プログラミングでは、ライブラリはプログラム内で再利用できる、コンパイル済みのコードの集まりです。ライブラリは、プログラム内で使用できる再利用可能な関数、ルーチン、クラス、データ構造など(他のプログラマによって書かれたもの)を提供するという点で、プログラマの生活を簡素化します。

たとえば、数学演算を実行する必要があるアプリケーションを構築している場合は、そのために新しい数学関数を作成する必要はありません。そのプログラミング言語のライブラリで既存の関数を使用するだけで済みます。

Linuxのライブラリの例には、 libc (標準Cライブラリ)または glibc (標準CライブラリのGNUバージョン)、 libcurl (マルチプロトコルファイル)があります。転送ライブラリ)、 libcrypt (Cでの暗号化、ハッシュ、およびエンコードに使用されるライブラリ)その他多数。

Linuxは2つのクラスのライブラリをサポートしています。

  • Static libraries – are bound to a program statically at compile time.
  • Dynamic or shared libraries – are loaded when a program is launched and loaded into memory and binding occurs at run time.

動的ライブラリまたは共有ライブラリは、さらに次のように分類できます。

  • Dynamically linked libraries – here a program is linked with the shared library and the kernel loads the library (in case it’s not in memory) upon execution.
  • Dynamically loaded libraries – the program takes full control by calling functions with the library.

共有ライブラリの名前は、ライブラリ名(a.k.a soname )と「ファイル名」(ライブラリコードを格納するファイルへの絶対パス)の2通りです。

たとえば、 libc soname libc.so.6 です。 lib はプレフィックス、です。 > c はわかりやすい名前なので共有オブジェクトを意味し、 6 はバージョンです。そしてそのファイル名は /lib64/libc.so.6 です。 sonameは実際にはファイル名へのシンボリックリンクです。

共有ライブラリは ld.so (または ld.so.x )と ld-linux.so (または ld->)によって読み込まれます。 x がバージョンであるlinux.so.x )プログラム。 Linuxでは、 /lib/ld-linux.so.x はプログラムで使用されるすべての共有ライブラリを検索してロードします。

プログラムは、そのライブラリ名またはファイル名を使用してライブラリを呼び出すことができ、ライブラリパスは、ファイルシステム内でライブラリを見つけることができるディレクトリを格納します。デフォルトでは、ライブラリは/usr/local/lib /usr/local/lib64 /usr/lib にあります。/usr/lib64 ;システムスタートアップライブラリは/lib /lib64 にあります。ただし、プログラマはカスタムの場所にライブラリをインストールできます。

ライブラリパスは /etc/ld.so.conf ファイルで定義でき、これはコマンドラインエディタで編集できます。

# vi /etc/ld.so.conf 

このファイルの行は、 /etc/ld.so.conf.d にファイルをロードするようにカーネルに指示します。このようにして、パッケージメンテナやプログラマーは自分のカスタムライブラリディレクトリを検索リストに追加することができます。

/etc/ld.so.conf.d ディレクトリを見ると、いくつかの一般的なパッケージ(これにはkernel、mysql、postgresql)の .conf ファイルがあります場合):

# ls /etc/ld.so.conf.d

kernel-2.6.32-358.18.1.el6.x86_64.conf  kernel-2.6.32-696.1.1.el6.x86_64.conf  mariadb-x86_64.conf
kernel-2.6.32-642.6.2.el6.x86_64.conf   kernel-2.6.32-696.6.3.el6.x86_64.conf  postgresql-pgdg-libs.conf

mariadb-x86_64.confを見れば、パッケージのライブラリへの絶対パスがわかります。

# cat mariadb-x86_64.conf

/usr/lib64/mysql

上記の方法は、ライブラリパスを恒久的に設定します。一時的に設定するには、コマンドラインで LD_LIBRARY_PATH 環境変数を使用します。変更を永続的なものにしたい場合は、この行をシェル初期設定ファイル/etc/profile (グローバル)または〜/ .profile (ユーザー固有)に追加します。

# export LD_LIBRARY_PATH=/path/to/library/file

共有ライブラリの扱い方を見てみましょう。バイナリファイルに対するすべての共有ライブラリの依存関係のリストを取得するには、 lddユーティリティを使用できます。 ldd の出力は次の形式です。

library name =>  filename (some hexadecimal value)
OR
filename (some hexadecimal value)  #this is shown when library name can’t be read

このコマンドは、lsコマンドに対するすべての共有ライブラリの依存関係を表示します。

# ldd /usr/bin/ls
OR
# ldd /bin/ls
	linux-vdso.so.1 =>  (0x00007ffebf9c2000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003b71e00000)
	librt.so.1 => /lib64/librt.so.1 (0x0000003b71600000)
	libcap.so.2 => /lib64/libcap.so.2 (0x0000003b76a00000)
	libacl.so.1 => /lib64/libacl.so.1 (0x0000003b75e00000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003b70600000)
	libdl.so.2 => /lib64/libdl.so.2 (0x0000003b70a00000)
	/lib64/ld-linux-x86-64.so.2 (0x0000561abfc09000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003b70e00000)
	libattr.so.1 => /lib64/libattr.so.1 (0x0000003b75600000)

共有ライブラリはさまざまなディレクトリに存在する可能性があるため、プログラムの起動時にこれらのディレクトリすべてを検索することは非常に非効率的です。これは、動的ライブラリの欠点の1つです。したがって、 ldconfig プログラムによって実行されるキャッシュのメカニズムが採用されています。

デフォルトでは、 ldconfig /etc/ld.so.conf の内容を読み取り、ダイナミックリンクディレクトリに適切なシンボリックリンクを作成してからにキャッシュを書き込みます。 > /etc/ld.so.cache これは他のプログラムによって簡単に使用されます。

これは、新しい共有ライブラリをインストールしたばかりの場合、独自のライブラリライブラリを作成した場合、または新しいライブラリディレクトリを作成した場合に特に重要です。変更を有効にするには、 ldconfig コマンドを実行する必要があります。

# ldconfig
OR
# ldconfig -v 	#shows files and directories it works with

共有ライブラリを作成したら、それをインストールする必要があります。上記の標準ディレクトリに移動して ldconfig コマンドを実行できます。

または、次のコマンドを実行して、 soname からファイル名へのシンボリックリンクを作成します。

# ldconfig -n /path/to/your/shared/libraries

あなた自身のライブラリを作成することを始めるために、The Linux Documentation Project(TLDP)からこのガイドを調べてください。

それは今のところすべてです!この記事では、ライブラリーの紹介、共有ライブラリー、そしてそれらをLinuxで管理する方法について説明しました。質問や意見がある場合は、下記のコメントフォームを使用してください。