ar - 静的なライブラリファイルを作成する

スポンサーリンク

arコマンドはアーカイブファイルを作成するコマンドになります。アーカイブファイルにあるファイルはメンバといいます。arコマンドはC言語などで利用するオブジェクトファイルをまとめたライブラリファイルを作成できるため、バイナリユーティリティとして利用できます。

また、ここで利用するarコマンドはGNU arになります。

スポンサーリンク

arコマンドの構文

arコマンドの基本的な構文

arコマンドのopcodeはコマンドのオプションのように-(ハイフン)をつけて利用できます。
arコマンドはopcodeとarchiveの指定が必須になります。

操作コード(opcode):アーカイブファイルを動作を指定する1文字のコード
修飾子(mod):操作コードの動作を少し変更するコード
アーカイブファイル(archive):アーカイブファイル
ファイルまたはメンバ(file):指定するファイルまたはメンバ

GNU arの場合、操作コードと修飾子の順番を任意に行うことができます。
(例えば、通常: 'ar rc ...'、順番を変更: 'ar cr ...')

操作コードの一覧

操作コード 動作
r アーカイブにメンバを追加
d アーカイブからメンバを削除
t アーカイブの内容を表示
p アーカイブ内のメンバを標準出力
s アーカイブのインデックスを追加または更新
x アーカイブからメンバを展開
q Quick append
アーカイブの最後にメンバを追加
m アーカイブ内のメンバの配置を変更
修飾子なしの場合、アーカイブの最後に移動
修飾子a, b, iで移動する箇所を指定

修飾子の一覧

修飾子 動作
a アーカイブ内のメンバの後にファイルを追加
b アーカイブ内のメンバの前にファイルを追加
c アーカイブの作成
ただし、この修飾子がなくても基本的にアーカイブは作成されます
この修飾子がないときはアーカイブを作成するメッセージが表示されます
D deterministic mode
ファイルのUID・GID・タイムスタンプがすべてゼロへ設定
f ネイティブのarプログラムとの互換性のためにファイル名を切り捨てます
i 修飾子bと同じ
N 同名のメンバーが存在する場合にどれを選択するときに使用
o 元々のタイムスタンプを保存
存在しない場合、展開時のタイムスタンプに設定
P アーカイブ内のファイルマッチに絶対パスを使用
他のツールで作成されたアーカイブファイルのために使用
s シンボルテーブルを作成または更新
単独で使用した場合はranlibコマンドと同じ
S シンボルテーブルを作成しない
T thin archiveを作成
thin archiveはデータの実体がなく、アーカイブのシンボルテーブルとファイルの参照のみを持ちます
u 最新のファイルのみを追加
U deterministic modeで操作しない
v 詳細モード(操作内容)を表示
V バージョン情報を表示

 

 

 

arコマンドの操作コード(opcode)

メンバの追加(r)

操作コードr を用いると指定したアーカイブファイルにメンバを追加できます。アーカイブファイルが存在しない場合は、作成されます。

コマンド例と実行結果

 

操作コードt はアーカイブファイルの内容をリストします。

 

 

 

メンバの削除(d)

操作コードd を用いると指定したアーカイブファイルからメンバを削除できます。

コマンド例と実行結果

 

 

 

アーカイブの内容を確認(t)

操作コードt を用いるとアーカイブファイルの内容を確認できます。

コマンド例と実行結果

 

 

 

アーカイブ内のメンバを標準出力(p)

操作コードp を用いるとアーカイブ内のメンバを標準出力に出力できます。メンバを指定しない場合はすべてのファイルの内容が標準出力に出力されます。

file1.txt

file2.txt

file3.txt

コマンド例と実行結果

 

 

 

アーカイブのインデックスを追加または更新(s)

操作コードまたは修飾子s を用いるとアーカイブファイルにインデックス(シンボルテーブル)を追加・更新できます。また、操作コードs を用いなくても、アーカイブファイルにオブジェクトファイルを追加するとき、インデックスは基本的に作成されます。

インデックスの確認は'nm -s'コマンドで確認できます。

シンボルテーブルのないアーカイブファイルの作成

コマンド例と実行結果

 

修飾子Sを用いて、アーカイブファイルを作成するとインデックスを作成せずにアーカイブファイルを作成できます。しかし、インデックス(シンボルテーブル)がないアーカイブファイルを用いて、コンパイルを行うことはできないかもしれません。
そのような場合にarコマンドの操作コードs またはranlibコマンドを利用することでアーカイブファイルにインデックスを作成できます。

 

 

 

アーカイブからメンバを展開(x)

操作コードx を用いるとアーカイブファイルからメンバを展開できます。

コマンド例と実行結果

 

 

 

クイックアペンド(q)

操作コードq は通常より高速にアーカイブファイルにメンバを追加します。追加されるメンバはアーカイブファイル内の最後の位置になります。

コマンド例と実行結果

 

 

 

アーカイブ内のメンバの配置を変更(m)

操作コードm はアーカイブ内のメンバの配置を変更できます。修飾子を利用しない場合、メンバはアーカイブファイルの最後に移動します。修飾子aまたはb等を用いるとメンバの移動がより詳しく指定できます。

コマンド例と実行結果

 

 

 

arコマンドの修飾子(mod)

メンバのファイルを追加する位置を指定(a, b)

修飾子a またはb を用いるとアーカイブファイルへファイルを追加する位置を指定できます。

修飾子a を用いるとアーカイブファイル内の指定したメンバの後にファイルが追加されます。

 

修飾子b を用いるとアーカイブファイル内の指定したメンバの前にファイルが追加されます。また、修飾子iは修飾子b と同じ動作になります。

 

 

 

アーカイブの作成(c)

修飾子c は利用しなくてもアーカイブファイルを作成することができます。修飾子cを利用するとアーカイブファイルを作成したときのメッセージが表示されません。

修飾子cあり

修飾子cなし

 

 

 

deterministic mode(D, U)

deterministic modeはアーカイブファイルに保存されるファイルの所有者情報やタイムスタンプがすべてゼロに設定されます。

deterministic modeは修飾子DでONになります。

また、deterministic modeは修飾子Uを用いるとOFFになります。

 

 

 

元々のタイムスタンプで展開(o)

修飾子oを用いるとアーカイブファイルに保存されるファイルの元々のタイムスタンプで展開できます。修飾子oを利用しなかった時、アーカイブファイル内のメンバを展開すると、展開されたファイルは、展開された時点でのタイムスタンプが設定されます。

コマンド例と実行結果

 

 

 

シンボルテーブルを作成しない(S)

修飾子Sを利用するとシンボルテーブルを作成せずにアーカイブファイルを作成できます。シンボルテーブルがないライブラリを利用するとコンパイルを行えないかもしれない点に注意が必要になります。

コマンド例

実行結果

 

 

 

thin archiveを作成(T)

修飾子Tを利用するとthin archiveを作成できます。thin archiveは通常のアーカイブファイルと異なり、メンバの実際のデータを持っていません。thin archiveが持っているのは、シンボルテーブルとメンバになっているファイルの参照になります。参照しているファイルが利用できなくなるとアーカイブファイルとして利用できなくなります。

コマンド例と実行結果

 

 

 

最新のファイルのみを追加(u)

修飾子uを利用するとアーカイブファイル内のメンバと追加するファイルのタイムスタンプを比較して、ファイルを更新できます。この機能はアーカイブファイルのタイムスタンプを利用する必要があるため、deterministic modeがデフォルトでONならば、修飾子UでOFFにする必要があります。

コマンド例と実行結果

 

 

 

詳細モード(v)

修飾子vを用いると操作した内容が表示されます。また、操作コードt と一緒に用いるとファイル名のほかにファイルの情報が表示されます。

コマンド例と実行結果

 

 

 

arコマンドの対話モード

arコマンドは-Mオプションを用いると対話モードになります。この対話モードでは、特定の命令を実行することでアーカイブファイルを操作できます。また、スクリプトは標準入力を用いて実行することもできます。

命令の種類

コマンド 機能
CREATE アーカイブファイルの作成し、対話モードで操作する現在のアーカイブファイルに設定
OPEN アーカイブファイルを開き、対話モードで操作する現在のアーカイブファイルに設定
ADDLIB アーカイブファイルの内容を現在のアーカイブファイルに追加
ADDMOD メンバを追加
DELETE メンバを削除
EXTRACT メンバを展開
LIST 現在のアーカイブファイルの内容を表示
REPLACE 現在のアーカイブファイルでの既存のメンバを、
その既存のメンバに対応するカレントディレクトリのファイルで置き換える
CLEAR SAVEコマンドを行うまでの現在のアーカイブファイルの操作内容を取り消す
SAVE 現在のアーカイブファイルの変更を保存し、
作成またはオープンしたファイル名でアーカイブファイルを保存
END arコマンドの対話モードを終了
変更を保存していない場合はその変更内容を破棄
DIRECTORY アーカイブファイルの内容を表示
VERBOSE DIRECTORYコマンドでの表示内容を'ar t'形式か'ar tv'形式かで切り替える

参考:GNU Binary Utilities: ar scripts

 

コマンド例と実行結果

 

 

 

静的ライブラリを利用してコンパイル

gccを利用して、静的ライブラリを利用してコンパイルを行う場合、オプションを用いない場合と-Lオプションや-lオプション等のオプションを用いる場合があります。

オプションを用いない場合

オプションを利用しない場合、単純にソースファイルと一緒にライブラリファイルをコマンドライン引数に指定して、コンパイルします。

libarchive.a(nmコマンドでのシンボルの内容)

testlib.c

コマンド例と実行結果

 

ライブラリファイルにあるfunc1, func2, func3の関数はそれぞれ自身の関数名を出力する単純な関数になります。

 

 

 

オプションを用いる場合

-Lオプションは利用するライブラリファイルが存在するディレクトリを指定します。このディレクトリはライブラリファイルを検索するためのディレクトリになります。

-lオプションは利用するライブラリファイルを指定します。ライブラリファイルは基本的に接頭辞に'lib'を、接尾辞に'.a'があるファイルが利用されます。

例えば、'-l archive'を指定した場合は、libarchive.aという名前のファイルが検索されます。
また、最初に':'を付けることでファイル名をそのまま指定することもできます。':'を付けた場合は例えば、'-l:libarchive.a'のように指定します。

コマンド例と実行結果

 

また、ヘッダーファイルを利用する場合、-Iオプションでヘッダファイルを検索するディレクトリを指定できます。

testlib.h

testlib2.c

コマンド例と実行結果

 

 

 

ライブラリファイルを利用しファイルをコンパイルする際の引数の順序について

ライブラリファイルを利用してコンパイルする際、コマンドライン引数にあるファイルや-lオプションの順序によって、ファイルのコンパイルが失敗する場合があります。

失敗例

コンパイラはコマンドライン引数のファイル(-lオプションで指定しているファイルを含めて)を順番に処理していきます。処理しているファイルに未定義のシンボルがあり、次以降にアーカイブファイルを処理する場合、そのアーカイブファイルを一回検索し、未定義のシンボルに該当するシンボルがあるなら、そのシンボル同士を関連付けます。

そのため、上の失敗例のように先にアーカイブファイルを処理すると未定義のシンボルをうまく関連付けることができません。
なので、ライブラリファイルを利用する場合は、ファイルをコンパイルする順序を少し意識する必要があります。

 

 

 

参考

GNU Binary Utilities

Man page of ar