パッケージにパッチを適用

提供: ArchWiki
ナビゲーションに移動 検索に移動

関連記事

このドキュメントでは Arch Build System (ABS) を使ってパッケージにパッチを作成したり適用する手順を説明します。

パッチ にはファイルにおけるとある行の変更が複数記されています。ソースコードの変更を自動化するのに主に用いられます。

パッチの作成

パッチには特定のファイル、あるいは複数のファイルの変更行が含まれています。ソースコードの変更を自動化するときにパッチは使われます。

ノート: 特定の行を変更するだけであれば、sed を代わりに使用するという手もあります。

diff ツールは行毎にファイルを比較します。ツールの出力を保存することでパッチを作成できます (例: diff --unified --recursive --text foo bar > patch)。ディレクトリを指定すると diff はディレクトリに含まれているファイルを比較します。

  1. パッケージをビルド済みの場合は src ディレクトリを削除してください。
  2. makepkg --nobuild を実行してください。PKGBUILD に記述されたソースファイルがダウンロード・展開されます。
  3. src ディレクトリに展開されたディレクトリのコピーを2つ作成してください。ひとつは元のまま取っておくコピーで、もうひとつは変更を加えるコピーです。ここでは package.origpackage.new と呼称します。
  4. package.new ディレクトリのファイルに必要な変更を加えてください。
  5. diff --unified --recursive --text package.orig package.new --color を実行してパッチがどのようにできるか確認してください。
  6. diff --unified --recursive --text package.orig package.new > package.patch を実行してパッチを作成してください。
  7. package.orig ディレクトリに移動して patch -p1 < ../package.patch でパッチを適用してください。makepkg --noextract --install で変更を加えたパッケージがビルド・インストールできることを確認します。
ノート: Gitgit diff または git format-patch を使ってパッチを作成することもできます [1]

diff について、さらなる詳細は diff(1)git-diff(1) を参照してください。

パッチの適用

このセクションでは自分で作成した、あるいはインターネットからダウンロードしてきたパッチを PKGBUILDprepare() 関数で適用する方法を説明します。以下の手順に従ってください:

  1. PKGBUILDsource 配列にパッチファイルのエントリを追加してください。元のソース url とは空白で区切られます。ファイルがオンライン上に存在する場合、完全な URL を記入すれば src ディレクトリに自動的にダウンロード・配置されます。パッチを自分で作成した場合、あるいはインターネット上からパッチを取得できない場合、PKGBUILD ファイルと同じディレクトリにパッチファイルを置いて、source 配列にファイルの名前を追加してください。ファイルが src ディレクトリにコピーされるようになります。PKGBUILD を再配布する場合、PKGBUILD とパッチを一緒にする必要があります。
  2. 次に、パッケージ pacman-contrib に含まれる updpkgsums を使用して md5sums 配列を更新してください。あるいは手動で md5sums 配列にエントリを追加してください。md5sum ツールを使うことでパッチのチェックサムを生成できます。
  3. PKGBUILD の中に prepare() 関数を(存在しない場合)作成してください。
  4. まずはパッチをあてる必要があるディレクトリに移動します (移動を行うのは prepare() 関数の中で、ターミナルではありません。パッチの適用を自動化します)。cd $srcdir/$pkgname-$pkgver などとすることでディレクトリを移動できます。$pkgname-$pkgver はダウンロードされたソースファイルが展開されたときによく作られるディレクトリの名前ですが、必ずしもこの名前になるとは限りません。
  5. ディレクトリの中からパッチを適用してください。prepare() 関数に以下を追加するだけです (pkgname.patch は差分が含まれているファイルの名前に置き換えてください。パッチファイルは PKGBUILDsource 配列に追加したので自動的に 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 を使うことでパッチの適用や更新、パッチをあてたファイルのリバートなどが楽になります。quiltDebian でパッチを管理するのに使われています。基本的な使用方法は Using Quilt を見てください。

参照