パッケージにパッチを適用
関連記事
このドキュメントでは Arch Build System (ABS) を使ってパッケージにパッチを作成したり適用する手順を説明します。
パッチ にはファイルにおけるとある行の変更が複数記されています。ソースコードの変更を自動化するのに主に用いられます。
パッチの作成
パッチには特定のファイル、あるいは複数のファイルの変更行が含まれています。ソースコードの変更を自動化するときにパッチは使われます。
diff
ツールは行毎にファイルを比較します。ツールの出力を保存することでパッチを作成できます (例: diff --unified --recursive --text foo bar > patch
)。ディレクトリを指定すると diff
はディレクトリに含まれているファイルを比較します。
- パッケージをビルド済みの場合は
src
ディレクトリを削除してください。 makepkg --nobuild
を実行してください。PKGBUILD
に記述されたソースファイルがダウンロード・展開されます。src
ディレクトリに展開されたディレクトリのコピーを2つ作成してください。ひとつは元のまま取っておくコピーで、もうひとつは変更を加えるコピーです。ここではpackage.orig
とpackage.new
と呼称します。package.new
ディレクトリのファイルに必要な変更を加えてください。diff --unified --recursive --text package.orig package.new --color
を実行してパッチがどのように出来るか確認してください。diff --unified --recursive --text package.orig package.new > package.patch
を実行してパッチを作成してください。package.orig
ディレクトリに移動してpatch -p1 < ../package.patch
でパッチを適用してください。makepkg --noextract --install
で変更を加えたパッケージがビルド・インストールできることを確認します。
diff
について、さらなる詳細は diff(1) や git-diff(1) を参照してください。
パッチの適用
このセクションでは自分で作成した、あるいはインターネットからダウンロードしてきたパッチを PKGBUILD
の prepare()
関数で適用する方法を説明します。以下の手順に従ってください:
PKGBUILD
のsource
配列にパッチファイルのエントリを追加してください。元のソース url とは空白で区切られます。ファイルがオンライン上に存在する場合、完全な URL を記入すればsrc
ディレクトリに自動的にダウンロード・配置されます。パッチを自分で作成した場合、あるいはインターネット上からパッチを取得できない場合、PKGBUILD
ファイルと同じディレクトリにパッチファイルを置いて、source
配列にファイルの名前を追加してください。ファイルがsrc
ディレクトリにコピーされるようになります。PKGBUILD
を再配布する場合、PKGBUILD
とパッチを一緒にする必要があります。- 次に、パッケー pacman-contrib に含まれる
updpkgsums
を使用してmd5sums
配列を更新してください。あるいは手動でmd5sums
配列にエントリを追加してください。md5sum
ツールを使うことでパッチのチェックサムを生成できます。 PKGBUILD
の中にprepare()
関数を(存在しない場合)作成してください。- まずはパッチをあてる必要があるディレクトリに移動します (移動を行うのは
prepare()
関数の中で、ターミナルではありません。パッチの適用を自動化します)。cd $srcdir/$pkgname-$pkgver
などとすることでディレクトリを移動できます。$pkgname-$pkgver
はダウンロードされたソースファイルが展開されたときによく作られるディレクトリの名前ですが、必ずしもこの名前になるとは限りません。 - ディレクトリの中からパッチを適用してください。
prepare()
関数に以下を追加するだけです (pkgname.patch
は差分が含まれているファイルの名前に置き換えてください。パッチファイルはPKGBUILD
のsource
配列に追加したので自動的にsrc
ディレクトリにコピーされています):
prepare 関数の例:
prepare() { cd "$pkgname-$pkgver" patch --forward --strip=1 --input="${srcdir}/eject.patch" }
あるいは、最初に cd せずに、patch
の --directory
フラグを使用することもできます。上記の例は次のようになります:
prepare() { patch --directory="$pkgname-$pkgver" --forward --strip=1 --input="${srcdir}/eject.patch" }
(ターミナルから) makepkg
を実行してください。全てが上手くいっていれば、パッチが自動的に適用されて、新しいパッケージにはパッチに含まれている変更が追加されているはずです。そうならない場合、patch の -p
オプションを使って実験を行ってみてください (--dry-run
や --reverse
や --verbose
などのオプションが有用でしょう)。詳しくは patch(1) を読んでください。
基本的には次のようになっています。myversion/
のファイルにパッチを適用する diff ファイルが作成された場合、diff ファイルは myversion/file
に適用されます。(PKGBUILD
で cd した) yourversion/
ディレクトリの中から実行する場合、ファイルにパッチが適用されるときに、myversion/
の部分は省いて file
ファイルに適用されるようにしなくてはなりません。--strip=1
でパスからディレクトリが一つ削除されます。しかしながら、開発者が myfiles/myversion
にパッチを適用した場合、ディレクトリを二つ削除する必要があるので、--strip=2
を使います。
--strip
オプションを指定しなかった場合、全てのディレクトリ構造が取り除かれます。全てのファイルがベースディレクトリに存在する場合はそれで ok ですが、パッチを作成したのが myversion/
で編集したファイルが myversion/src/file
の場合、yourversion
の中から --strip
オプションを付けずにパッチを実行したときに、yourversion/file
という名前のファイルにパッチが適用されてしまいます。
ほとんどの開発者はパッチを適用するディレクトリの親ディレクトリからパッチを作成するので、通常は --strip=1
が適切です。
quilt を使う
多数のパッチを管理する場合、quilt を使うことでパッチの適用や更新、パッチをあてたファイルのリバートなどが楽になります。quilt は Debian でパッチを管理するのに使われています。基本的な使用方法は Using Quilt を見てください。
参照
- http://www.kegel.com/academy/opensource.html — パッチの適用に関する有用な情報