Last Update:
パッケージ(package)はオペレーティングシステム(OS, operating system)の重要なインフラのひとつです。OSといえばプロセス管理・メモリ管理・ファイルシステムのようなカーネルの機能を連想してしまいがちです。『4.4BSDの設計と実装』『詳解Linuxカーネル』『オペレーティングシステム設計と理論およびMINIXによる実装』などの分厚い書籍を思い浮かべるかもしれません。でもそれよりももっと高いレイヤのアプリケーションだって立派にOSの一部です。プログラマにとって統合開発環境やテキストエディタ・バージョン管理システム・コンパイラは欠かせなですし、一般ユーザにとっても統合デスクトップ環境が提供する豪華なグラフィカルは欠かせません。特にWebブラウザはもうそれ無しで生活することなど考えられないような時代になっています。
Debian GNU/LinuxやRed Hat Enterprise Linux(RHEL)のようにOS全体をパッケージで管理しているケースもあれば、NetBSDやFreeBSDのようにベースシステム(base system)に無いソフトウェアをパッケージで管理しているケースもあります。システム管理という面ではパッケージはとても便利な機能なので、FreeBSDではベースシステムをパッケージ化してパッケージマネージャから管理できるようにするPkgBase[FreeBSD Wiki]が開発されています(NetBSDも昔syspkgというPkgBaseと同じコンセプトの実装が進められていましたが現在は停滞しています[NetBSD Wiki])。
このようにパッケージは一般ユーザにとって一種のインフラのようなものと言っても過言ではないでしょう。そして、それをどう作りどう配布するのか?を調べると、OSはどのような構成をしているのかおおまかに眺めることもできます。パッケージングの技術をものにすれば、自分で好きなGNU/Linuxディストリビューションあるいはデスクトップ向けのBSD Unixを作ることだってできます。
OSに興味はなくても、パッケージには向き合わなければならないときがあります。もしなにかコードを書いてFLOSSとして公開するなら、そしてGNU/Linux向けにそれを書いたなら、deb(5)
かrpm
をいつでも(できれば両方)作れるようにしておくとそのソフトウェアを使いたいユーザにとって便利です。企業でGNU/Linux向け商用ソフトウェアを開発するときも、そのソフトウェアをパッケージにまとめ頒布する作業は必要です。
パッケージは「荷物」や「梱包」の他にソフトウェアの管理・配布形式(形態?)も意味します。しかしこの言葉がいつからソフトウェアに対して使うようになったのか分かりません。確かに「ソフトウェアやその設定ファイル・マニュアルなどを含んだ単一のアーカイブ」は言われてみれば荷物のようであるし、実際にこれを作るときはまるで段ボールのような箱にデータを詰め込んでいる感覚があるので「パッケージ」という言葉はまさにぴったりです。
パッケージはよく「ソフトウェア・ライブラリ・設定ファイル・マニュアルなどをアーカイブにしたもの」というような説明がされます。僕は「パッケージ自身の情報(メタデータ)」をこの説明に付け加えたいといつも考えてしまいます。たとえばDebian GNU/Linux上でdpkg(1)
やapt(8)
といったパッケージマネージャを実行してなんらかのパッケージをインストールするとき、インストール対象のパッケージが依存している別のパッケージも自動でインストールされるのはメタデータのおかげです。
メタデータはソフトウェアのパッケージにのみ存在するわけではありません。僕たちが引っ越しや贈り物の準備をするとき、段ボールにモノを詰め込むだけでなく、配送業者向けに宛先や送り主の名前を書いた伝票を段ボールに貼り付けますが、これもメタデータといっていいでしょう。
おそらく、テープやCD-ROMの形態でソフトウェアを「梱包」して販売する企業が初めに「パッケージ」をソフトウェアに対しても使い始めたのだと予想しています。しかしこのような配布形態にはパッケージマネージャが読み取り可能なメタデータはおそらく含まれていないでしょう。パッケージをソフトウェア+メタデータのアーカイブという観点からすると、これがパッケージの起源にせよ、機能がまだ不足しているわけです。現在僕たちが何気なくapt(8)
から操作する、Unix上で扱われるパッケージの形式はいつ成立したのでしょうか。
パッケージ主体のGNU/LinuxディストリビューションはDebian GNU/Linuxが先陣を切りました。Debian 0.01から0.90までのリリースについては不明ですが、1994年1月のDebian 0.91では「このリリースは、パッケージのインストールおよび削除ができる単純なパッケージシステムを備えていました」[Debian, 2017]とされています。また1995年3月のDebian 0.93R5では「基本システムのインストール後は、パッケージマネージャ (dpkg) がパッケージのインストールに使われました」[Debian, 2017]とあります。
しかしDebian GNU/Linuxがパッケージに関して独占的だったかというと、そうではなかったようです。GNU/LinuxディストリビューションをCD-ROMの形態で販売したRed Hat社が提供したRed Hat Linuxは、1994年の夏にRed Hat LinuxとそのパッケージマネージャRPPの展示のためにプレビュー版(バージョン0.8)がリリースされ、1994年10月31日にバージョン0.9となるHalloweenがリリースされました[Red Hat, 2014][Stephen, 2006]。Debian GNU/Linux 0.91のリリースと同じ年です。「Fully "packagized" system for fine-grained installation control, easy upgrades, and simple distribution mechanism for your applications」[Red Hat, 1995]とアピールされたのは1995年のバージョン1.1なので、Halloweenの時点でOS全体がパッケージ管理されていたのかは定かではありません。
Linuxカーネルが公開されたのは1991年の8月だった[Linus, 1991]。GNU/LinuxディストリビューションそのものはDebian GNU/Linuxではなく、1993年7月にリリースされたSlackwareが本源となっています[Slackware, 2005, Chapter 1]。しかもSlackwareはRed Hat Linux(のおそらくプレビュー版以前)より先にパッケージマネージャpkgtool(8)
を実装していました。しかしパッケージの依存関係はチェックせず、doinst.sh
というポストインストールスクリプトを実行する簡素なものだったようです。
There's a myth that's been going around ever since RedHat debuted RedHat Package Manager, that Slackware has no package management tool. This simply couldn't be further from the truth. Slackware has always included a package manager, even before RedHat existed. While not as full-featured or as ubiquitous as rpm (or for that matter deb), pkgtool and its associated programs are every bit as good at installing packages as rpm. The truth about pkgtool is not that it doesn't exist, but that it doesn't do any dependency checking.[Slackware, 2005, Chapter 18]
ではSlackwareがパッケージとパッケージマネージャを取り入れた最初のUnixだったのでしょうか?それを確定させるにはSlackware以前のUnixについて調査する必要があります。これは難しく、386BSD(1992年2月)や4.3BSD、System Vなどの他に、4.2BSDやSystem Vの後継製品も調査しなければならないからです。
AT&TのSystem ⅢまたはSystem Vの後継製品は、AT&T、Altos、Apollo、Compaq、Convergent、HP、Honeywel、IBM、ITT、Intel、Interactive、Masscomp、Microport、Microsoft、Motorola、NCR、NUXI、Opus、SCO、Silicon Graph ics、Sperry、Sun、Tandy、UniSoft、Wollongongから販売されていた。さらに、Amdahl、Apollo、Apple、CrayDEC、Data General、HP、IBM、Intel、Motorola、Unisys、およびほかのホストから、独自のUnixが発売されていた。それらの一部は、4.2BSDに基づいていた。[Salus, 2000]
これはそう簡単に調べられるものではありませんが、共立出版株式会社の『UNIX System V コマンド・ノート』がたまたま手に入ったので調べてみると、少なくともこの本の中にはパッケージの操作に関するコマンドは載っていませんでした[System V, 1986]。
FreeBSDのports(7)
は1993年12月にリリースされたFreeBSD 1.0から登場し、NetBSDとOpenBSDにも広まっていきました[ports(7), 2014][FreeBSD]。386BSDから分岐したBSD Unixの中でFreeBSDが初めてこのようなパッケージ管理システムを実装した(NetBSDで主に使われるpkgsrc(7)
はports(7)
から派生した[pkgsrc, 2018])ので、ports(7)
の前身が分かればおのずと答えが分かるのでしょうか?(TODO)
Debian GNU/Linuxはdpkg(1)
を通じてdeb(5)
形式のパッケージを操作します。dpkg(1)
のエンドユーザ向けインタフェースにapt-get(8)
やapt(8)
などがあります。パッケージをインストールするなら、最近は後者がよく使われているようです。
apt(8)
でvimのパッケージをインストールするには以下のように実行します。
# apt install vim
dpkg(1)
からパッケージをインストールする方法もありますが、一般ユーザは恐らく使う機会がありません。
deb(5)
パッケージの構造Debian GNU/Linux stretchのvimパッケージ vim_8.0.0197-4+deb9u1_amd64.debを例にdeb(5)
形式のパッケージの構造を眺めてみましょう。これをar(1)
で展開すると、以下に示すように3つのファイルが得られます。
vim_8.0.0197-4+deb9u1_amd64.deb/
├── control.tar.gz
├── data.tar.xz
└── debian-binary
これらのファイルについてはdeb(5)
のマニュアルを読むと詳細がわかります。
The first member is named debian-binary and contains a series of lines, separated by newlines. Currently only one line is present, the format version number, 2.0 at the time this manual page was written. Programs which read new-format archives should be prepared for the minor number to be increased and new lines to be present, and should ignore these if this is the case.
If the major number has changed, an incompatible change has been made and the program should stop. If it has not, then the program should be able to safely continue, unless it encounters an unexpected member in the archive (except at the end), as described below.
The second required member is named control.tar. It is a tar archive containing the package control information, either not compressed (supported since dpkg 1.17.6), or compressed with gzip (with .gz extension) or xz (with .xz extension, supported since 1.17.6), as a series of plain files, of which the file control is mandatory and contains the core control information. The control tarball may optionally contain an entry for ‘.’, the current directory.
The third, last required member is named data.tar. It contains the filesystem as a tar archive, either not compressed (supported since dpkg 1.10.24), or compressed with gzip (with .gz extension), xz (with .xz extension, supported since dpkg 1.15.6), bzip2 (with .bz2 extension, supported since dpkg 1.10.24) or lzma (with .lzma extension, supported since dpkg 1.13.25). [Debian]
要するにcontrol.tar.gz
とdebian-binary
はパッケージのメタデータで、data.tar.xz
がソフトウェアやライブラリ・マニュアルなどに相当するわけです。
RHELはrpm(8)
を通じてRPM(Red Hat package Manager)パッケージを操作します。エンドユーザ向けインタフェースにYellowdog Updater Modified(yum(8)
)やDandified YUM(dnf(8)
)があります。
企業や大学のネットワークで動くGNU/Linuxは、RHELかそのクローンのCentOSが採用されている場合が多く、サーバ機器製品のOSとしてRHELがあらかじめインストールされていることもあります。そのため商用製品として監視ツールやWebサーバ・メールサーバといったシステムソフトウェアを配布するのであればdeb(5)
よりむしろRPM形式が使われるでしょう。Eric Raymondは開発者と共同作業するためのFLOSSのディストリビューション方法について次のように述べています。
RPM(Red Hat Packageマネージャ)は、Linuxのもとでインストール可能なバイナリパッケージのための事実上の標準となったフォーマットである。RPMはもっともポピュラーなLinuxディストリビューションの重要な機能であり、他のほぼすべてのLinuxディストリビューションでサポートされている(DebianとSlackwareを除く。そして、DebianはRPMからインストールできる)。そこで、プロジェクトサイトは、ソースtarボールの他に、インストール可能なRPMも提供するとよい。[Raymond,2007]
FreeBSDのPorts Collectionは「Makefile, 修正パッチ、 説明文などの一連のファイルのこと」[FreeBSD]で、一般的には短縮してports(7)
と呼ばれます。パッケージのビルドやインストールなどの一連の命令はすべてBSD Makeを使います。たとえばGNU Emacsをインストールするときはroot権限で次のように実行します。コンパイル時のconfigure
のオプションはビルド途中に選択できます。
# cd /usr/ports/editors/emacs
# make install
最近のFreeBSDでは、ライセンスの都合上バイナリの配布を禁じられている場合やオプションを自分で細かく制御したい場合を除き、pkg(8)
でバイナリパッケージをインストールするのが楽です。先ほどのEmacsの例はpkg(8)
を使うと次のように実行できます。
# pkg install emacs
このpkg(8)
は「FreeBSD 10.X系移行で動作するように設計されて」[FreeBSD]おり、FreeBSD 11.0では基本システムにインストールされています。
ここで、ports(7)
あるいはpkgsrc(7)
におけるパッケージの表記方法について述べておきます。ここではEmacsパッケージをインストールする例を示しましたが、このパッケージは/usr/ports
ディレクトリから見た相対パス名でeditors/emacs
と書かれるのが一般的です。このような書き方をすると、どのディレクトリに当該パッケージが存在するのか一目瞭然だからです。
NetBSDのpkgsrc(7)
はFreeBSDのPorts Collectionから派生したパッケージ管理システムです。特徴としてNetBSD以外のUnixでも使える高い移植性があります。NetBSD以外のOSで初めてpkgsrc(7)
が動いたのはSolaris 2.6だといいます。
In 1999, I was working at an investment bank in London, and needed a packaging system to manage third-party software on a fairly large network of Solaris 2.6 machines - pkgsrc fitted the bill, and so the first non-NetBSD platform was Solaris, followed closely by Linux.[Weinem]
ports(7)
と同じくpkgsrc(7)
上の操作はBSD Makeを使います。NetBSD以外のUnixで使うときは、はじめにbootstrap/
ディレクトリ内のbootstrap
スクリプトを実行します。その後、bootstrap
でインストールされたbmake(1)
を使ってパッケージを操作します。たとえばvimをインストールするなら次のように実行します。
# cd /usr/pkgsrc/editors/vim
# make install
なぜパッケージに注目するのかを説明しました。パッケージはOSのインフラで、便利で手放せないものです。そしてインフラだからこそパッケージを調べればOSの構造を理解する手助けにもなります。同じ形式のパッケージを提供するOSを複数比べてみると、パッケージの管理・ビルド方法はそれぞれ異なっていることもあります。
ときどき、パッケージのオンラインマニュアルを読んでみてもいいのかもしれません。