The Linking Process Exposed – Static vs Dynamic Libraries

10月 19, 2021
admin

Creating Static and Dynamic Library

静的ライブラリの場合、バイナリファイル(拡張子.o)のオブジェクトコードは、拡張子.aの単一のアーカイブファイルに結合されます。 このアーカイブは、リンク時にそのライブラリを呼び出すプログラムで使用される可能性のあるすべてのツールを含むツールボックスと似ている。 ツールは必要な場所に挿入されます。 下の画像では、一連の .c ファイルがあります。

ライブラリはオブジェクト コードのアーカイブなので、次のコマンドでこれらすべての .c ファイルを .o ファイルに変換する必要があります:

gcc -Wall -Wextra -Werror -pedantic -c *.c

オブジェクト コード ファイル生成後にリンク直前に -c オプションでコンパイルを停止しています。

コマンドを実行すると、これらのファイルを 1 つの .a ライブラリ ファイルにアーカイブすることができます。 arコマンドはアーカイブ、-rオプションは拡張子.oを持つメンバーの移動、-cオプションはアーカイブが存在しない場合の作成に使用されます。 ライブラリファイルはプレフィックスがlibで始まり、拡張子が.aである。 システムによっては、リンクの速度を上げるためにアーカイブの内容に索引を付けることが必要な場合がある。 これは ranlib libholbertonschool.a で行うことができます。

Using the Static Library

このライブラリをあるテストファイルで使用するには、次の 2 つのコマンドのいずれかを使用して、テストファイルをライブラリでコンパイルしなければなりません:

gcc test.c ./libholbertonschool.a -o exename

gcc test.c -L. -lholbertonschool -o exename

これらはどちらも同じことを行いますが、2 番目は少し不可解なものです。 -L. オプションはカレントディレクトリにあるライブラリを検索し、 holbertonschool に接続されている -llib 接頭辞と .a 接尾辞が仮定されているライブラリファイルを暗黙のうちに検索するものである。 ライブラリファイルがない場合、gccはリンクしようとしている関数が提供されていないため、エラーを投げる。 コンパイル時にライブラリを提供することにより、コンパイラーは必要な関数をライブラリから検索し、必要な場所に挿入できるようになりました。

ダイナミック・ライブラリ

ダイナミック・ライブラリの作成は静的ライブラリとは若干異なりますが、コンセプトは概ね同じです。 同じ数の.cファイルと、そのプロトタイプを定義するヘッダーファイルがlists.hというファイルにありますね。

.so(共有オブジェクトの略)を持つ動的ライブラリを作成するには、以下のコンパイルコマンドを入力します。

gcc -fPIC -Wall -Werror -Wextra -pedantic *.c -shared -o libholberton.so

-fPICフラグは動的リンクに必要な位置独立コード(Position Independent Code)を意味しています。 この意味は、まさにそのとおりで、ダイナミックリンクされたライブラリは、メモリ上のどこにでも収まるので、このフラグにより、ライブラリファイルがどこに格納されていても使用できるようになります。

-shared フラグにより共有アーカイブを作成し、-o オプションにより出力ファイルの名前を libholberton.so に変更できます。

このコマンドを実行後、共有ライブラリができました!

Using the Dynamic Library

以下のコードを持っているとします:

#include "holberton.h"
#include <stdlib.h>
#include <stdio.h>/**
* main - check the code for Holberton School students.
*
* Return: Always EXIT_SUCCESS.
*/
int main(void)
{
printf("%d\n", _strlen("Holberton"));
return (EXIT_SUCCESS);
}

私は以下のコードでプログラムをコンパイルできます。

gcc -Wall -pedantic -Werror -Wextra -L. 0-main.c -lholberton -o len 

スタティックライブラリと同様に、-L.オプションはライブラリファイルをディレクトリから検索し、holbertonの先頭に付加されている-lは、プレフィックスlib、サフィックス.so、その間にholbertonを持つライブラリファイルを暗黙的に検索するものである。

作成したばかりのライブラリファイルを使用するには、コンパイラがメモリ内のすべてのライブラリファイルを見つけることができ、それらがそもそもメモリに正しくロードされていることを確認する必要があります。 今 ldd len を実行すると、次のようになります:

libholberton.so => not found から、先ほど作成したダイナミック ライブラリの依存関係が満たされていないことがわかります。 これを解決するには、環境変数$LD_LIBRARY_PATHを理解する必要があります。 Linux では、この変数はシステムがライブラリ・ファイルを探すために調べるディレクトリをコロンで区切ったリストです。 上の画像では、現在の状態でこの変数をエコーすると空であることがわかります。したがって、共有ライブラリがロードできないため、私がプログラムを実行しようとしても(len)うまくいかないのです。

私のカレント ディレクトリは次のようになります:

ご覧のように、ライブラリ ファイルは私のメイン ファイルおよびヘッダー ファイルと同じディレクトリにあります(現在のワーキング ディレクトリ)。 次の画像を観察してください:

コマンドは $LD_LIBRARY_PATH 環境変数を .: で更新し、システムがライブラリーのために現在の作業ディレクトリを検索すべきことを表します。 export コマンドはこの変更をグローバルにし、どのシェルも同じ値にアクセスできるようにする。 したがって、この変数を echo すると、自分の更新が表示されます。 もう一度 ldd len を実行すると、libholberton.so はアドレス位置 0x00007fb9216b9000 にあり、これはメモリ内の現在の作業ディレクトリにある場所と思われます。 このように、実行ファイルの共有ライブラリへの依存は満たされ、プログラムは「Holberton」という単語の長さである9を返します。

コメントを残す

メールアドレスが公開されることはありません。