アップストリームのソースを修正する具体的なやり方について、何から何まで説明するにはとても紙面が足りませんが、よくあるパターンとしては大体以下のようなものでしょう。
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-1
debian/
一時ディレクトリーへと、package-2
debian/
や 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 に合わせてソースコードへの必要な変更を加える必要があります。