\r\n\r\n
ソフトウェアを開発する際、Linuxのarコマンドを使用して関数ライブラリを作成する。このチュートリアルでは、静的ライブラリの作成方法、修正方法、プログラムでの使用方法をサンプルコードを交えて説明します。
arコマンドは、1971年から使われている老舗で、arという名前は、アーカイブされたファイルを作成するという本来の用途にちなんでいます。アーカイブファイルとは、他のファイルの入れ物として機能する1つのファイルのことです。他のファイルを対象としていることもあります。アーカイブにファイルを追加したり、削除したり、アーカイブからファイルを取り出したりすることができます。このような機能を求める人は、もはやarに頼ることはなく、tarなどの他のユーティリティにその役割を奪われているのです。
arは静的ライブラリの作成に使用されます。arは、Debian Linuxディストリビューションやその派生版(Ubuntuなど)で使われている「.deb」ファイルのようなパッケージファイルの作成にも使用されます。
静的ライブラリの作成と変更に必要な手順を実行し、プログラムでのライブラリの使用方法を実演します。そのためには、静的ライブラリがある要件を満たす必要があります。本ライブラリは、テキスト文字列のエンコードと、エンコードされたテキストのデコードを目的としています。
これはデモのためのクイック&ダーティなハックであることにご注意ください。この暗号化は、価値のあるものには使用しないでください。AがBになり、BがCになり、という世界一簡単な置き換え暗号です。
関連:Linuxでtarコマンドを使ってファイルを圧縮・解凍する方法
ここでは "library" というディレクトリで作業し、後で "test" というサブディレクトリを作成します。
このディレクトリには、2つのファイルがあります。cipheru encode.cというテキストファイルの中に、cipheru encode()関数があります。
void cipher_encode(char *text) { for (int i=0; text[i] != 0x0; i++) { text[i]++; } } // end of cipher_encode対応するcipheru decode()関数は、cipheru decode.cというテキストファイル内にある。
void cipher_decode(char *text) { for (int i=0; text[i] != 0x0; i++) { text[i]--; } } // end of cipher_decodeプログラミング命令が書かれたファイルをソースコードファイルと呼びます。この2つのソースコード・ファイルをコンパイルしたものを含むlibcipher.aというライブラリ・ファイルを作成する予定です。また、libcipher.hという短いテキストファイルも作成します。これは、新しいライブラリに含まれる2つの関数の定義を含むヘッダーファイルである。
ライブラリとヘッダーファイルを持っていれば、誰でも自分のプログラムで両関数を使うことができます。彼らは、車輪の再発明や関数を書き直す必要はなく、私たちのライブラリのコピーを使用すればいいのです。
ソースファイルのコンパイルには、GNU標準のコンパイラであるgccを使用します。 c (compile, no link) オプションは、gccにファイルをコンパイルした後に停止するように指示します。gccリンカは通常、すべてのオブジェクトファイルを取り込み、それらをリンクして実行可能なプログラムを生成します。cオプションでこのステップをスキップしました。オブジェクトファイルだけが必要です。
持っていると思われる書類があるかどうか確認しよう。
ls -lこの2つのソースファイルはこのディレクトリに存在するので、gccでオブジェクトファイルにコンパイルしてみましょう。
gcc -c cipher_encode.c gcc -c cipher_decode.cすべてうまくいけば、gccは何も出力しないはずです。
ソースファイルと同じ名前で拡張子が".o "のオブジェクトファイルが2つ生成されますが、これらはライブラリファイルに追加する必要があるファイルです。
ls -l実際にアーカイブファイルであるライブラリファイルを作成するために、arを使用することにします。
ライブラリファイルの作成には-c(create)オプション、ライブラリファイルにファイルを追加するには-r(addwithreplace)オプション、ライブラリファイル内のファイルのインデックスを作成するには-s(index)オプションを使用します。
このライブラリファイルを libcipher.a と呼ぶことにします。この名前を、ライブラリに追加するオブジェクトファイルの名前と一緒にコマンドラインで指定します。
ar -crs libcipher.a cipher_encode.o cipher_decode.oディレクトリ内のファイルをリストアップすると、現在 libcipher.a ファイルがあることがわかります。
長征 - The Long March
arの-t(テーブル)オプションを使うと、ライブラリファイル内のモジュールを見ることができます。
ar -t libcipher.alibcipher.h ファイルは libcipher.a ライブラリを使用するすべてのプログラムに含まれます。 libcipher.h ファイルにはライブラリ内の関数の定義が含まれている必要があります。
ヘッダーファイルを作成するためには、テキストエディタ(geditなど)で関数定義を打ち込む必要があります。ファイル名を「libcipher.h」とし、libcipher.a ファイルと同じディレクトリに保存してください。
void cipher_encode(char *text); void cipher_decode(char *text);新しいライブラリをテストする唯一の確実な方法は、それを使う小さなプログラムを書くことです。まず、testというディレクトリを作成します。
mkdir test新しいディレクトリに、ライブラリとヘッダーファイルをコピーします。
cp libcipher.* ./test新カタログに切り替わります。
cd testここで、2つの資料を確認してみましょう。
ls -lこのライブラリを利用できるアプレットを作成し、期待通りに動作することを証明する必要があります。エディタに次のテキスト行を入力します。エディターの内容をtestディレクトリの "test.c "というファイルに保存してください。
#include <stdio.h> #include <stdlib.h> #include "libcipher.h" int main(int argc, char *argv[]) { char text[]="How-To Geek loves Linux"; puts(text); cipher_encode(text); puts(text); cipher_decode(text); puts(text); exit (0); } // end of main手順の流れはとてもシンプルです。
テストプログラムを生成するには、test.cプログラムとライブラリ内のリンク先をコンパイルする必要があります。o(出力)オプションは、gccが生成する実行ファイルをどのように呼び出すかを指示します。
gcc test.c libcipher.a -o testgccが無言でコマンドプロンプトに戻るようなら、すべて順調です。さて、プログラムをテストしてみましょう。
./test期待通りの出力が確認できます。テストプログラムは、平文を印刷し、暗号化されたテキストを印刷し、そして復号化されたテキストを印刷する。新しいライブラリの機能を利用しています。私たちの図書館の仕事
成功です。しかし、なぜそこで止まるのでしょうか?
ライブラリにもう一つ関数を追加してみましょう。プログラマーが使用しているライブラリのバージョンを表示するための機能を追加する予定です。新しい関数を作成し、コンパイルして、新しいオブジェクトファイルを既存のライブラリファイルに追加する必要があります。
エディタに以下の行を入力し、エディタの内容をライブラリディレクトリのcipheru version.cというファイルに保存します。
#include <stdio.h> void cipher_version(void) { puts("How-To Geek :: VERY INSECURE Cipher Library"); puts("Version 0.0.1 Alpha\n"); } // end of cipher_version新しい関数の定義を libcipher.h ヘッダーファイルに追加する必要があります。そのファイルの一番下に新しい行を追加して、次のように記述します。
void cipher_encode(char *text); void cipher_decode(char *text); void cipher_version(void);変更した libcipher.h ファイルを保存します。
cipheru version.o オブジェクトファイルを作成するために、cipheru version.c ファイルをコンパイルする必要があります。
gcc -c cipher_version.cこれにより、cipheru version.o ファイルが作成されます。新しいオブジェクトファイルを libcipher.a ライブラリに追加するには、次のコマンドを使用します。v (verbose) オプションは、通常は無言の ar が何を行うかを教えてくれるようにします。
ar -rsv libcipher.a cipher_version.o新しいオブジェクトファイルがライブラリファイルに追加されます。 ar 印刷確認。
ライブラリファイルにどのモジュールが入っているかは、-t(テーブル)オプションで確認することができます。
ar -t libcipher.aこれで、ライブラリファイルに3つのモジュールができましたので、この新しい関数を利用してみましょう。
testディレクトリから古いライブラリとヘッダファイルを削除し、新しいファイルをコピーして、testディレクトリに戻ろう。
旧バージョンのファイルを削除します。
rm ./test/libcipher.*新しいバージョンをtestディレクトリにコピーします。
cp libcipher.* ./testtestディレクトリに切り替えます。
cd testここで、新しいライブラリ関数を使用するようにtest.cプログラムを修正することができます。
cipheru version() 関数を呼び出すために test.c プログラムに新しいコード行を追加する必要があります。これを最初のput (text);の行の前に置くことにします。
#include <stdio.h> #include <stdlib.h> #include "libcipher.h" int main(int argc, char *argv[]) { char text[]="How-To Geek loves Linux"; // new line added here cipher_version(); puts(text); cipher_encode(text); puts(text); cipher_decode(text); puts(text); exit (0); } // end of mainこれを test.c という名前で保存します。これをコンパイルして、新しい関数が動作することをテストします。
gcc test.c libcipher.a -o test新バージョンのテストを実行してみましょう。
テスト出力の冒頭にライブラリのバージョンが表示されているのがわかる。
しかし、問題があるかもしれません。
これはライブラリーの第1版ではなく、第2版です。バージョン番号に誤りがあります。最初のバージョンでは、cipheru version()関数がありませんでした。これはそうですね。ですから、これはバージョン "0.0.2 "であるべきです。ライブラリにあるcipheru version()関数を正しい関数に置き換える必要があります。
arがこれを簡単にしてくれたのはありがたいことです。
まず、libraryディレクトリにあるcipheru version.cファイルを編集します。Version 0.0.1 Alpha」の文字を「Version 0.0.2 Alpha」に変更します。このように表示されるはずです。
#include <stdio.h> void cipher_version(void) { puts("How-To Geek :: VERY INSECURE Cipher Library"); puts("Version 0.0.2 Alpha\n"); } // end of cipher_version再度コンパイルして、新しい cipheru version.o オブジェクトファイルを作成する必要があります。
gcc -c cipher_version.cここで、ライブラリ内の既存の cipheru version.o オブジェクトを、新しくコンパイルされたバージョンに置き換えます。
以前、-r(addwithreplace)オプションを使って、新しいモジュールをライブラリに追加したことがあります。すでにライブラリに存在するモジュールと一緒に使うと、arは古いバージョンを新しいバージョンに置き換えます。s(インデックス)オプションはライブラリのインデックスを更新し,-v(冗長)オプションはarが何をしたかを教えてくれるようになります.
ar -rsv libcipher.a cipher_version.o今回、arはcipheru version.oモジュールを置き換えたことを報告する。'r'は置き換えを意味する。
修正したライブラリを使って、動作確認をする必要があります。
ライブラリファイルをtestディレクトリにコピーしておきます。
cp libcipher.* ./testtestディレクトリに切り替えます。
cd ./test新しいライブラリでテストプログラムを再コンパイルする必要があります。
gcc test.c libcipher.a -o testこれで、プログラムをテストする準備が整いました。
./testテストプログラムの出力は期待通りのものでした。バージョン文字列は正しいバージョン番号を示し、暗号化ルーチンと復号化ルーチンは動作しています。
惜しい気がしますが、ライブラリファイルからcipheru version.oファイルを削除してみましょう。
そのために、-d(delete)オプションを使用します。また、-v(verbose)オプションを使って、arが何をしたかを教えてくれるようにします。また、ライブラリファイルのインデックスを更新するために、-s(index)オプションも付けます。
ar -dsv libcipher.a cipher_version.oarはモジュールが削除されたことを報告します。"d "は "deleted "を意味します。
arにライブラリファイルのモジュールをリストアップさせると、2つのモジュールに戻ることが確認できる。
ar -t libcipher.aモジュールをライブラリから削除したい場合は、ライブラリヘッダからその定義を削除することを忘れないでください。
ライブラリは、実用的でありながらプライベートな方法でコードを共有することを可能にします。ライブラリファイルとヘッダーを公開した人は、誰でもライブラリを使用することができますが、実際のソースコードは非公開のままです。