アップストリームのソースを修正する具体的なやり方について、何から何まで説明するにはとても紙面が足りませんが、よくあるパターンとしては大体以下のようなものでしょう。
quilt プログラムはアップストリームソースに対する Debian
パッケージ向け修正を記録する、基本的な方法を提供します。Debian
パッケージで使うには、多少カスタマイズしたデフォルトを使うのが望ましいので、以下の行を ~/.bashrc
に追加し Debian パッケージ作成用のエリアス dquilt を作りましょう。第 2 行目は
quilt コマンドのシェル入力完了機能と同様の機能を dquilt
コマンドに与えます:
alias dquilt="quilt --quiltrc=${HOME}/.quiltrc-dpkg"
complete -F _quilt_completion -o filenames dquilt
~/.quiltrc-dpkg ファイルを次のように作成しましょう:
d=. ; while [ ! -d $d/debian -a `readlink -e $d` != / ]; do d=$d/..; done
if [ -d $d/debian ] && [ -z $QUILT_PATCHES ]; then
# if in Debian packaging tree with unset $QUILT_PATCHES
QUILT_PATCHES="debian/patches"
QUILT_PATCH_OPTS="--reject-format=unified"
QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"
QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"
if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi
fi
quilt の使い方については、quilt(1) と /usr/share/doc/quilt/quilt.pdf.gz を参照してください。
Let's assume you find an error in the upstream Makefile
as follows, where install: gentoo should have been
install: gentoo-target.
install: gentoo
install ./gentoo $(BIN)
install icons/* $(ICONS)
install gentoorc-example $(HOME)/.gentoorc
これを修正して、dquilt コマンドを使って
fix-gentoo-target.patch として登録しましょう: [22]
$ mkdir debian/patches $ dquilt new fix-gentoo-target.patch $ dquilt add Makefile
Makefile ファイルを次のように変更します:
install: gentoo-target
install ./gentoo $(BIN)
install icons/* $(ICONS)
install gentoorc-example $(HOME)/.gentoorc
パッチを更新して debian/patches/fix-gentoo-target.patch
を作成するように dquilt に要求し、それから説明を DEP-3:
Patch Tagging Guidelines に準拠して追記します:
$ dquilt refresh $ dquilt header -e ... パッチの詳細
通常、サードパーティーソフトウェアは自分自身を /usr/local
サブディレクトリーにインストールします。Debian 上ではこれはシステム管理者 (もしくはユーザー) の個人用に予約されているため、パッケージャーは
/usr/local のようなディレクトリーを使わず、Filesystem Hierarchy Standard (FHS) に従って
/usr/bin サブディレクトリーのようなシステムディレクトリーを使わなくてはなりません。
プログラムのビルドを自動化するには、通常 make(1) が使われており、make
install を実行すると、(Makefile
のinstall ターゲットに従い) 希望する場所へ直接インストールされます。Debian
ではビルド済みのインストール可能なパッケージを提供するために、実際のインストール先のかわりに、一時ディレクトリーの下に作成されたファイルツリーのイメージへプログラムをインストールするようにビルドシステムを変更します。
普通のプログラムインストールとDebian パッケージ作成というこれら二つの違いには、debhelper パッケージの
dh_auto_configure と dh_auto_install
のコマンドを使うことで特に意識せずに対応できます:
Makefile ファイルが GNU
の慣例に準拠し、$(DESTDIR) 変数をサポートしていること。[23]
ソースは Filesystem Hierarchy Standard (FHS) に準拠している必要があります。
GNU autoconf を使っているプログラムは、自動的に GNU
規約に準拠するので、そのパッケージ作成はいとも簡単にできます。こういう事実や他から類推すると、debhelper パッケージはビルドシステムに立ち入った変更を加えることなく、約 90%
のパッケージで使えると推定されます。そのため、パッケージ作成は見かけほど複雑ではありません。
もし Makefile ファイルを変更する必要があるなら、これら
$(DESTDIR)
変数をサポートするように注意しましょう。デフォルトではアンセットされているとはいえ、プログラムのインストールに使われる各ファイルパスの前に$(DESTDIR)
変数は付与されます。パッケージ作成スクリプトは $(DESTDIR) を一時ディレクトリーにセットします。
単一バイナリーパッケージを生成するソースパッケージでは、debian/
が dh_auto_install コマンドが使う一時ディレクトリーとして指定されます。[24]
一時ディレクトリーに含まれているものはすべて、ユーザーがあなたのパッケージをインストールする時に、ユーザーのシステムにインストールされます。唯一の違いは、dpkg
はファイルをあなたの作業ディレクトリーではなくルートディレクトリーからの相対パスにインストールするということです。
package
パッケージの作成時は、あなたのプログラムは
debian/
にインストールされますが、package.deb
パッケージからルートディレクトリー下にインストールされた場合も正しく動作する必要があることを覚えておいてください。こうするためには、ビルドシステムがパッケージファイルの中のファイル中に
/home/me/deb/
といった文字列をハードコードしないようにしなければなりません。
package-version/usr/share/package
gentoo の
Makefile で該当する部分はこれです[25]:
# Where to put executable commands on 'make install'? BIN = /usr/local/bin # Where to put icons on 'make install'? ICONS = /usr/local/share/gentoo
We see that the files are set to install under
/usr/local. As explained above, that directory
hierarchy is reserved for local use on Debian, so change those paths as
follows:
# Where to put executable commands on 'make install'? BIN = $(DESTDIR)/usr/bin # Where to put icons on 'make install'? ICONS = $(DESTDIR)/usr/share/gentoo
バイナリー、アイコン、文書など、それぞれのファイルを保存すべき正確な場所については、Filesystem Hierarchy Standard (FHS) 中に規定されています。全体に目を通して、あなたのパッケージに該当する箇所を読むことをお勧めします。
そういうわけで、実行可能バイナリーは /usr/local/bin ではなく
/usr/bin へインストールしなければなりませんし、マニュアルページは
/usr/local/man/man1 の代わりに
/usr/share/man/man1 へインストールする必要があります。ここで gentoo の Makefile
には、マニュアルページに関する記述がまったく無いことに注意してください。Debian
ポリシーでは、すべてのプログラムがそれぞれマニュアルを用意しなければならないと定めていますから、後で gentoo のマニュアルを作成して、それを
/usr/share/man/man1 以下へインストールすることにします。
プログラムの中には、このようなパスを定義するための Makefile
変数を使っていないものもあります。このような場合、C
のソースそのものをいじって、指定された場所を使うように修正しなければなりません。でもどこを探し、何を確認すればよいのでしょうか?
以下のコマンドを実行すれば該当箇所を見つけることができます:
$ grep -nr --include='*.[c|h]' -e 'usr/local/lib' .
grep がソースツリーを再帰的に検索し、該当箇所を見つけたらそのファイルの名前と検索対象の文字列が含まれる行番号とを表示します。
それらのファイルを編集し、該当行の usr/local/lib を
usr/lib に置き換えてください。これは以下の様にすると自動化出来ます:
$ sed -i -e 's#usr/local/lib#usr/lib#g' \
$(find . -type f -name '*.[c|h]')
こうする代わりに、各置換を確認したい場合は、これは以下のようにインタラクティブにできます:
$ vim '+argdo %s#usr/local/lib#usr/lib#gce|update' +q \
$(find . -type f -name '*.[c|h]')
修正が終ったら、 install ターゲットを探しましょう(install:
で始まる行を探してください。この方法でたいていうまくいきます)。Makefile
の先頭で定義されているものを除いて、ディレクトリーへの参照をすべて変更してください。
修正前は、gentoo の
install ターゲットはこうなっています:
install: gentoo-target
install ./gentoo $(BIN)
install icons/* $(ICONS)
install gentoorc-example $(HOME)/.gentoorc
dquilt
コマンドを使って、debian/patches/install.patch
としてアップストリームバグを修正して記録しましょう。
$ dquilt new install.patch $ dquilt add Makefile
Debian パッケージ用に、これをエディタで次のように変更します:
install: gentoo-target
install -d $(BIN) $(ICONS) $(DESTDIR)/etc
install ./gentoo $(BIN)
install -m644 icons/* $(ICONS)
install -m644 gentoorc-example $(DESTDIR)/etc/gentoorc
お気づきになったでしょうが、変更後はこのルールの他のコマンドより前に install -d
コマンドが追加されています。make install を実行するようなシステムなら
/usr/local/bin やその他のディレクトリーはたいがい既に存在しているでしょうから、もともとの
Makefile
ではこのコマンドは使われていませんでした。しかし、私たちは独自に空っぽの(あるいはまだ存在さえしていない)ディレクトリーにインストールするわけですから、これらの各ディレクトリーを毎回作成する必要があります。
ルールの最後には、アップストリームの作者が省略することの多い付加的な資料のインストールなど、他の作業を追加することもできます:
install -d $(DESTDIR)/usr/share/doc/gentoo/html
cp -a docs/* $(DESTDIR)/usr/share/doc/gentoo/html
しっかりチェックをして、何も問題がないようであれば、dquilt でパッチを更新して
debian/patches/install.patch を作成し、パッチの説明を追記してください:
$ dquilt refresh $ dquilt header -e ... パッチの詳細
これで、一連のパッチができました。
アップストリームのバグ修正: debian/patches/fix-gentoo-target.patch
Debian 固有のパッケージ上の変更: debian/patches/install.patch
Whenever you make changes that are not specific to the Debian package such
as debian/patches/fix-gentoo-target.patch, be sure to
send them to the upstream maintainer so they can be included in the next
version of the program and be useful to everyone else. Also remember to
avoid making your fixes specific to Debian or Linux — or even Unix!
Make them portable. This will make your fixes much easier to apply.
アップストリームの作者へ debian/* ファイルを送らなくてもよいことに注意してください。
There is one other common problem: libraries are often different from
platform to platform. For example, a Makefile can
contain a reference to a library that doesn't exist on the Debian system.
In that case, we need to change it to a library that does exist in Debian,
and serves the same purpose.
あなたのプログラムの Makefile (もしくは
Makefile.in) が以下のようになっていると仮定しましょう。
LIBS = -lfoo -lbar
foo
ライブラリーが存在しないためにあなたのプログラムがコンパイルしないで、foo2 ライブラリーがその等価を
Debian システム上で提供する場合、foo を foo2 に変更する
debian/patches/foo2.patch
としてこのビルド問題を解決できます:[26]
$ dquilt new foo2.patch $ dquilt add Makefile $ sed -i -e 's/-lfoo/-lfoo2/g' Makefile $ dquilt refresh $ dquilt header -e ... describe patch
[22] 前に説明したように dh_make
を実行していれば、debian/patchesディレクトリーはもう存在しているはずです。この操作例では、既存のパッケージを更新している場合に合わせて作成しています。
[24] 複数バイナリーパッケージを生成するソースパッケージでは、debian/tmp を
dh_auto_install
コマンドが使う一時ディレクトリーとしますが、debian/tmp の中身を
debian/ や
package-1debian/
一時ディレクトリーへと、package-2debian/
や package-1.installdebian/
ファイルによる指定に従い dh_install コマンドが分配することで複数バイナリー
package-2.install*.deb パッケージを作成されます。
[25] これは Makefile
ファイルがこうなっているべきである、ということを示すための例にすぎません。Makefile ファイルが
./configure コマンドで作成されているなら、この手の
Makefile
を修正する正しい方法は、dh_auto_configure コマンドに
--prefix=/usr
を含むデフォルトのオプションを与えて、./configure コマンドを実行させることです。
[26] foo ライブラリーから foo2 ライブラリーへの API
変更があった場合、新しい API に合わせてソースコードへの必要な変更を加える必要があります。