パッケージの作成

提供: ArchWiki
2019年6月20日 (木) 22:43時点におけるHiromi-mi (トーク | 投稿記録)による版 (→‎PKGBUILD の関数: prepare() -> pkgvar() の順に呼び出されるので訂正, 英語版と同期, 古い情報残した)
ナビゲーションに移動 検索に移動

関連記事

この記事は、Arch Linux の ports 風のビルドシステムを使ってパッケージを自作するユーザーの助けになることを目的としています。この記事の扱う範囲は PKGBUILD (makepkg によって読み込まれるパッケージ定義ファイル) の書き方についてです。すでに PKGBUILD が用意できている場合、makepkg の項目を参照してください。パッケージの質を向上させるためのルール・方法などの説明は Arch パッケージングスタンダードを参照してください。

概要

Arch Linux のパッケージは、makepkg ユーティリティーと PKGBUILD に記載された情報からビルドされます。makepkg が実行されると、カレントディレクトリの PKGBUILD を見て、ソースをコンパイルするか必要なファイルをダウンロードするかの指示に従ってパッケージファイル (pkgname.pkg.tar.xz) が作成されます。こうして出来上がったパッケージはバイナリとインストールの実行スクリプトが含まれ、pacman でインストールできるものになります。

Arch のパッケージは、以下のファイルが tar アーカイブ、つまり 'tarball' にまとめられ、xz(1) で圧縮されたものです。

  • インストールするバイナリやファイル。
  • .PKGINFO: pacman でパッケージ管理や依存解決をするために必要なすべての情報が書かれたファイル。
  • .BUILDINFO: Reproducible Builds のための情報が含まれます。pacman 5.1 以降でのビルド時のみ含まれます。
  • .MTREE: ファイルのハッシュとタイムスタンプ。ローカルデータベースに含めることで pacman はパッケージの整合性を検証することができます。
  • .INSTALL: 任意のファイル。インストール/アップグレード/削除の後に実行される (PKGBUILD で指定された場合のみ存在する)。
  • .Changelog: パッケージメンテナによるパッケージの更新についての覚え書き (必ず付属するとは限らない)。

メタパッケージとグループ

パッケージグループはパッケージ作成者によって定義される関連パッケージのセットで、グループの名前を使うことで個々のパッケージを同時にインストールしたりアンインストールすることができます。グループはパッケージではありませんが、インストールする方法はパッケージと同じです。Pacman#パッケージグループのインストールPKGBUILD#groups を見てください。

メタパッケージ (大抵は -meta が名前に付いています) はパッケージグループと同じように相互に関連する複数のパッケージを同時にインストール・アンインストールするためのものです。メタパッケージは他のパッケージと同じようにインストールすることができます。Pacman#特定のパッケージのインストールを見てください。メタパッケージと通常のパッケージの違いは、メタパッケージの中身は空っぽであり、あくまで関連パッケージを互いに依存関係にリンクするためだけに存在することです。

グループと比べてメタパッケージには利点が存在しています。新しいパッケージが依存関係に追加された場合、メタパッケージの更新によってインストールされるということです。グループでは、新しいパッケージが追加されても自動的にはインストールされません。メタパッケージの欠点はグループよりも柔軟性に欠けるという点です。グループではインストールしたいパッケージを選択することが可能ですが、メタパッケージではどれをインストールするのか選べません。同じように、グループでは一部のパッケージだけをアンインストールすることができますが、メタパッケージでは中に入っているパッケージだけを削除するのは不可能です。

準備

ソフトウェアの準備

まず、必要なツールがインストールされているか確認してください。 base-devel があれば十分です。このグループには make などのコンパイルに必要なツールが含まれています。

# pacman -S base-devel

pacman で提供される makepkg はパッケージ作成で最も重要なツールの一つです。makepkg は以下を行います:

  1. 依存パッケージがインストールされているかどうか確認する。
  2. ソースをサーバーからダウンロードする。
  3. 圧縮されたソースファイルを展開する。
  4. fakeroot 環境でコンパイルし、インストールする。
  5. バイナリやライブラリから不要シンボルを除去する (symbol stripping)。
  6. パッケージのメタデータを生成する。
  7. fakeroot 環境をパッケージに圧縮する。
  8. パッケージファイルを出力先ディレクトリに保存する。デフォルトでは作業ディレクトリ。

インストールのダウンロードとテスト

パッケージにしたいソフトウェアのソース tarball をダウンロードして、展開してください。その後ソフトウェアの作成者の指示に従ってプログラムをインストールしてください。ソフトウェアをコンパイル・インストールするのに必要なコマンド・手順を全て手控えておきましょう。PKGBUILD ファイルの中で同じコマンドを使うことになります。

ほとんどのソフトウェアは3ステップでビルドします:

./configure
make
make install

プログラムが正しく動作するか確認すると良いでしょう。

PKGBUILDの作成

パッケージ作成に必要な情報は全て PKGBUILD に書かれます。makepkg は実行されると、カレントディレクトリに PKGBUILD ファイルがあるか探し、そこに書かれていることに従ってソフトウェアのソースコードをコンパイルします。PKGBUILD に書かれている指示は、Bash として実行可能である必要があります。コンパイルが無事終了すれば、出来上がったバイナリと、バージョンや依存パッケージなどのパッケージのメタデータが パッケージ名.pkg.tar.xz にまとめられます。このパッケージファイルは pacman -U パッケージファイル でインストールすることができます。

新しいパッケージを作るには、まず空の作業ディレクトリを用意します (~/abs/パッケージ名 が推奨です)。このディレクトリにファイル PKGBUILD を作成します。プロトタイプとして、/usr/share/pacman/PKGBUILD.proto や、類似パッケージの PKGBUILD が使えます。オプションを変更するだけなどの場合、後者が便利になるかもしれません。

PKGBUILD の変数を定義する

PKGBUILD のサンプルは /usr/share/pacman/ にあります。PKGBUILD で利用できる変数は PKGBUILD の記事で説明されています。

パッケージをビルドするために必要な以下の変数は、makepkg によってあらかじめ定義されます:

srcdir
makepkg がソースファイルを展開、またはコピーしてくるディレクトリです。
pkgdir
build() が終わった後、makepkg はここに生成されたファイルをパッケージに入れます。ここがパッケージのルートディレクトリになります。

これらの変数は全て絶対パスなので、適切にこれらの変数を使う限り作業ディレクトリについて心配する必要はありません。

ノート: makepkg、そして build()package() 関数は対話式になるようにはなっていません。特にビルドログを有効にして (-l)、これらの関数で対話式のユーティリティやスクリプトを呼び出すと makepkg が破壊される可能性があります (FS#13214 を参照)。
ノート: 現在のパッケージメンテナの他に、以前のメンテナが貢献者として記載されることがあります。

PKGBUILD の関数

5つの関数が存在し、全て存在する場合ここに記載している順番どおりに実行されます。関数が存在しないときは、スキップされます。

ノート: package() 関数は省略できません、この関数は全ての PKGBUILD で必須になります。

関数 prepare()

Pacman 4.1 から prepare() 関数が導入されました。この関数では、パッチなどの、ソースをビルドする前の準備に使われるコマンドを実行します。この関数は build 関数の前、パッケージの展開の後に実行されます。展開が省略された場合 (makepkg -e)、prepare() は実行されません。

ノート: (man PKGBUILD より) この関数は bash -e モードで実行されるため、コマンドのどれかが0以外のステータスコードで終了したときこの関数は終了します。

関数 pkgver()

pacman 4.1 から採用され、makepkg の実行中に pkgver 変数を更新することができます。pkgver() はソースが取得・展開されたすぐ後に実行されます。

git/svn/hg などのパッケージを作成するときにこの関数は特に便利です。なぜならビルドプロセスは同じままでも、ソースは毎日・毎時間更新される可能性があるからです。昔は日時を pkgver フィールドに入れていたため、ソフトウェアが更新されていなくても、makepkg はバージョンが変更されたと考えてリビルドをしていました。この関数では git describe, hg identify -ni などのコマンドが有用です。PKGBUILD を投稿する前に、pkgver() 関数がビルドを停止させないかテストしてください。

ノート: pkgver には空白やハイフン (-) を含めることができません。sed を使って対処してください。

関数 build()

さて、PKGBUILD ファイルの中に build() 関数を定義しなくてはなりません。この関数、build()Bash の文法を使って、ソフトウェアを自動的にコンパイルします。そして pkg ディレクトリを作成しここにソフトウェアをインストールします。これによって makepkg はファイルシステムをふるいにかけることなくファイルをパッケージにまとめることができます。

build() 関数はまず展開されたソースコードのディレクトリに入ります。makepkgbuild() を実行する前にカレントディレクトリを $srcdir に移動するので、ほとんどの場合最初のコマンドは以下のようになるでしょう:

cd "$pkgname-$pkgver"

そして、手動でソフトウェアをコンパイルをするのと同じコマンドを書き連ねます。build() 関数は、煎じ詰めて言えば手でコンパイルするのに必要な操作を自動化したものなのです。今パッケージしているソフトウェアが configure を使っているのなら、--prefix=/usr を使うのが良いでしょう。(多くのソフトウェアがファイルをインストールするのに使う) /usr/local ディレクトリは、手動でインストールする場合のみに限って使われるべきです。すべての Arch Linux パッケージは、/usr ディレクトリを使うべきです。/usr/share/pacman/PKGBUILD.proto に書かれているように、次の2行はだいたい以下のようになるでしょう:

./configure --prefix=/usr
make
ノート: 何もビルドする必要がないソフトウェアの場合は、build() 関数は使用しないでください。build() 関数は不要ですが、package() 関数は必須です。

関数 check()

ここでは make check などのテストを動作させます。ソフトウェアが正しくビルドできたか確認したり依存関係が問題ないか調べるのに役立つので check() を記述することは推奨されています。

テストの必要のないユーザー(や、時にはテストを通過させるようにパッケージを修正できないメンテナ)は、PKGBUILD や makepkg.conf で BUILDENV+=('!check') オプションを指定する (もしくは --nocheck フラグを付けて makepkg を呼び出す) ことで、これをスキップできます。

関数 package()

最後に、コンパイルされたファイルを、makepkg がファイルを読み込むことができる(そしてパッケージを作成する)ディレクトリに置きます。デフォルトでは pkg ディレクトリです。このディレクトリは単なる fakeroot 環境です。すなわち、このディレクトリはインストール先のファイルシステムの / (root ファイルシステム) に相当します。インストールするファイルは全て pkg 以下に、ディレクトリ構造を保ったまま置かれる必要があります。例えば、ファイルを /usr/bin にインストールさせたい場合は ${pkgdir}/usr/bin にファイルを置きます。数ダースのファイルを手動でコピーしなくてはならない場合はほとんどありません。ほとんどのソフトウェアでは、代わりに make install を呼び出すことでコピーが行われます。ソフトウェアを pkg ディレクトリに正しくインストールするために、最後の行は以下のようになるでしょう:

make DESTDIR="$pkgdir/" install
ノート: ときどき MakefileDESTDIR が使われていない場合があります。このときは prefix を使ってください。パッケージのビルドに autoconf/automake が使われているときは、DESTDIR を使ってください。これはマニュアルに文書化されています。もし DESTDIR が使えなければ、make prefix="$pkgdir/usr/" install を試してください。それでもだめなら、"make <...> install" によって実行されるインストールコマンドをもっと調べる必要があります。

稀に、一つのディレクトリの中にすべてのファイルが置かれ、ソフトウェアをそこから実行するようにされていることがあります。こうした場合には、そのディレクトリを $pkgdir/opt にコピーするのが賢明です。

多くの場合では、pkg 下のサブディレクトリはインストールプロセスで自動的に作られます。しかし、そうでない場合は makepkg は大量のエラーを吐いて失敗します。この場合、必要なサブディレクトリを build() 関数内で mkdir -p コマンドを実行することで、インストール作業の前にあらかじめ生成してください。

昔のパッケージでは package() 関数はなく、この操作は build() でまとめて行われていました。PKGBUILDbuild() がない場合は、build() 全体が fakeroot で実行されます。package() が定義されている場合、build()makepkg を実行したユーザで実行され、package() だけが fakeroot で実行されます

また、makepkg --repackagepackage() だけを呼び出します。パッケージの depends 変数をだけ変更したときなどに、ソースを再コンパイルせずパッケージを作成ができ、時間を節約することができます。

ノート: package() は PKGBUILD で唯一の必須関数です。プログラムをインストールするのに必要なのがファイルをディレクトリにコピーするだけの場合、build() 関数ではなく package() 関数にコマンドを記述してください。

PKGBUILD とパッケージのテスト

build() 関数を記述している間、バグがないことを確認するために変更をテストしたくなるかもしれません。PKGBUILD ファイルが含まれているディレクトリで makepkg コマンドを実行してすることでテストすることができます。フォーマットが正しい PKGBUILD なら、makepkg はパッケージを作成します。PKGBUILD が壊れていたり未完成だと、エラーを吐きます。

makepkg は問題なく終了すると、作業ディレクトリに pkgname-pkgver.pkg.tar.xz という名前のファイルを作成します。このパッケージは pacman -U コマンドでインストールすることができます。ただし、パッケージファイルが作られたというだけでは完全に機能するとは言えません。あるいはディレクトリだけでファイルが全く含まれていない可能性もあります (例えば、prefix が間違って指定されているとか)。pacman の query 関数を使うことでパッケージに含まれているファイルのリスト、パッケージが必要とする依存パッケージを pacman -Qlp [package file]pacman -Qip [package file] でそれぞれ表示することができます。

パッケージが問題ないようでしたら、これであなたの作業は終了です!ただし、PKGBUILD ファイルを公開するつもりならば、depends の中身を何度もチェックするべきです。

また、パッケージバイナリが完璧に動くことを確認しましょう!全ての必要なファイルが含まれているが、(システムの他の部分と問題を起こすような)度しがたい設定オプションによってクラッシュするパッケージを公開するのは迷惑です。勿論、あなた自身のためだけにパッケージをコンパイルするのなら、品質保証について心配しすぎる必要はありません。誤りによって苦しむのはあなただけなのですから。

パッケージの正常性のテスト

パッケージが機能するかテストした後 namcap を使ってエラーがないか確認してください:

$ namcap PKGBUILD
$ namcap <package file name>.pkg.tar.xz

Namcap は以下を行います:

  1. PKGBUILD の中身を見て、よくある間違いやパッケージファイルの階層に不必要な・間違って置かれたファイルがないか確認します。
  2. ldd を使ってパッケージ内の全ての ELF ファイルをスキャンし、必要な共有ライブラリがあるパッケージが depends に欠けていることや、推移的な依存として省略できるパッケージを自動で報告します。
  3. 欠けている、もしくは不要な依存パッケージのヒューリスティック検索。

などなど。パッケージを namcap でチェックする習慣を実践することでパッケージを投稿した後に単純な間違いを修正する手間が省けます。

AUR にパッケージを送信する

Arch User Repository#パッケージを投稿する に、投稿する方法について詳しい説明があります。

要約

  1. パッケージにしたいソフトウェアのソース tarball をダウンロードする。
  2. パッケージのコンパイルを試行し任意のディレクトリにインストールする。
  3. プロトタイプの /usr/share/pacman/PKGBUILD.proto をコピーして PKGBUILD に名前を変更して一時的な作業ディレクトリに置く -- ~/abs/ が推奨。
  4. パッケージの必要に応じて PKGBUILD を編集する。
  5. makepkg を実行して作られたパッケージが正しくビルドされているか確認する。
  6. 正しくビルドされるまで、前の2つの手順を繰り返す。

注意点

  • パッケージのビルドプロセスを自動化する前に、あらかじめ何をするのか正確にわかっている場合(その場合あなたはそもそもこの文章を読まないと思いますが)を除いて、少なくとも一度は手動でビルドを行なって下さい。残念ながら、大勢のプログラムの作者が "./configure; make; make install" のビルド3ステップに従っているにもかかわらず、これがいつも上手く行くとは限りません。下手をすると、全てを問題なく動かすにはパッチを適用する必要がある場合も考えられます。大雑把に言うと: プログラムをソース tarball からコンパイルして、規定の一時サブディレクトリにインストールすることができない場合、パッケージングを試行する必要さえありません。makepkg にはソースの問題を解決してくれるような妖精の粉はないからです。
  • 稀に、ソースからパッケージを作成することができなくて sh installer.run などのようにコマンドを実行しなくてはならないことがあります。そのようなときは、パッケージを作成するためにドキュメント (README や INSTALL の手順、man ページ、あるいは Gentoo の ebuild や他のパッケージインストーラのソースパッケージ、それでも駄目なら Makefile やソースコードまで) を相当読まなくてはなりません。最悪の場合、ソースファイルに編集を加える必要さえ出てくることもあります。しかしながら、makepkg はユーザーの補助がなくてもビルドが通るように完全に自動化する必要があります。そのため、Makefile を編集しなくてはならないときは、PKGBUILD にカスタムパッチを供えて prepare() 関数の中からパッチをインストールするか、あるいは prepare() 関数の中で sed コマンドを実行してください。

より詳細なガイドライン

PKGBUILD ジェネレーター

パッケージによっては、PKGBUILD を自動的に生成できます。

ノート: ジェネレーターの利用者であっても、自動生成されたファイルを AUR へ投稿する前に、パッケージが高い品質基準を満たしていると保証する責任があります。

参照