#title パッチシステムを用いないパッチ適用 As was mentioned above, one can patch the original source by simply making the changes in the unpacked source directory. A real-life example of this is '''cron'''. If you grab '''cron''''s source package and look at the `.diff.gz` you will see that several of the original source's files were changed. 前述したように、展開済みのソースディレクトリに対する変更点を元にパッチを作成することができます。実例としては'''cron'''パッケージがあります。'''cron'''のソースパッケージを取得し`.diff.gz`を見てみれば、オリジナルのソースファイルにさまざまな修正が加えられていることがわかるでしょう。 {{{ apt-get source cron zgrep +++ cron*.diff.gz }}} But as we mentioned before this is not really the best way to represent patches. One better way is to create individual patch files, but them in `debian/patches/` and apply the patches (using '''patch''') in `debian/rules`. This is what is done for '''udev''': しかし、前節でも述べたように、これはパッチとしてはいい方法ではありません。より良い方法は、個別にパッチファイルを作成し、`debian/patches/`ディレクトリに格納し、`debian/rules`で('''patch'''コマンドを使うことで)パッチを適用する方法です。これは、'''udev'''パッケージで行われています: {{{ apt-get source udev zgrep +++ udev*.diff.gz ls udev*/debian/patches/ less udev*/debian/rules }}} The `rules` file has the following rules for applying and unapplying the patches: `rules`ファイルでは、パッチを適用したり、元に戻したりするために、以下のようなルールが作成されています: {{{ # Apply patches to the package patch: patch-stamp patch-stamp: dh_testdir @patches=debian/patches/*.patch; for patch in $$patches; do \ test -f $$patch || continue; \ echo "Applying $$patch"; \ patch -stuN -p1 < $$patch || exit 1; \ done touch $@ # Remove patches from the package unpatch: dh_testdir @if test -f patch-stamp; then \ patches=debian/patches/*.patch; \ for patch in $$patches; do \ reversepatches="$$patch $$reversepatches"; \ done; \ for patch in $$reversepatches; do \ test -f $$patch || continue; \ echo "Reversing $$patch"; \ patch -suRf -p1 < $$patch || exit 1; \ done; \ rm -f patch-stamp; \ fi }}} That is all very nice, but how do we create new patches for '''udev''' using this scheme? The general approach is: これはすべてうまく動きます。では、この方法を使った'''udev'''のための新しいパッチを作成するためにはどうすればいいでしょうか。一般的な方法は: 1. copy the clean source tree to a temporary directory 1. apply all patches up to the one you want to edit; if you want to create a new patch, apply all existing ones (this is necessary since in general patches depend on previous patches) if you want, you can use debian/rules for this: remove the patches that come *after* the one you want to edit, and call 'debian/rules patch'. The actual name for the patch target varies, I have seen the following ones so far: patch setup apply-patches unpack patch-stamp. You have to look in `debian/rules` to see what it is called. 1. copy the whole source tree again: {{{ cp -a /tmp/old /tmp/new }}} 1. go into /tmp/new, do your modifications 1. go back into your original source tree, generate the patch with: {{{ diff -Nurp /tmp/old /tmp/new > mypatchname.patch }}} 1. クリーンなソースツリーを一時的に作成したディレクトリにコピーします。 1. 修正しようとしているパッチまでのパッチをすべて適用します。新規にパッチを作成したい場合は、すべてのパッチを適用します(一般的に、あるパッチはその前のパッチに依存するので、これは必要な作業です)。 もし望むなら、これをdebian/rulesを使って行うことも可能です:まず、修正したいと思っているパッチより「後の」パッチをすべて削除します。次に'debian/rules patch'を実行します。patchターゲットの名前は違うかもしれません。これまでに、patch setup apply-patches unpack patch-stampなどを見たことがあります。どのように呼び出すべきかについては、`debian/rules`の中を見てください。 1. 再び、ソースツリーをコピーします: {{{ cp -a /tmp/old /tmp/new }}} 1. /tmp/oldディレクトリに移動し、当初の目的だった修正を行います。 1. 元のソースツリーに戻り、次のようにパッチを作成します: {{{ diff -Nurp /tmp/old /tmp/new > mypatchname.patch }}} <> == 例1 == Let us make a new patch for '''udev''' called `90_penguins.patch` which replaces ''Linux'' with ''Penguin'' in the '''udev''' `README` file: 例として、'''udev'''の`README`ファイルの''Linux''をすべて''Penguin''に置き換える、`90_penguins.patch`を新規に作成してみましょう: {{{ cd udev*/ cp -a . /tmp/old pushd /tmp/old debian/rules patch cp -a . /tmp/new; cd ../new sed -i 's/Linux/Penguin/g' README cd .. diff -Nurp old new > 90_penguins.patch popd mv /tmp/90_penguins.patch debian/patches rm -rf /tmp/old /tmp/new }}} <> == 例2 == What happens if we want to edit an existing patch? We can us a similar procedure as Example 1 but we will apply the patch to be edited first: 既存のパッチを修正したい場合はどうなるでしょう。例1と似ているけれども、最初のパッチを編集するという例を見てみましょう(訳注:'''udev'''の最新版(113-0ubuntu16)では`10-selinux-include-udev-h.patch`は存在しません): {{{ cp -a . /tmp/old pushd /tmp/old cp -a . /tmp/new; cd ../new patch -p1 < debian/patches/10-selinux-include-udev-h.patch sed -i '1 s/$/***** HELLO WORLD ****/' udev_selinux.c cd .. diff -Nurp old new > 10-selinux-include-udev-h.patch popd mv /tmp/10-selinux-include-udev-h.patch debian/patches rm -rf /tmp/old /tmp/new }}} So this way of patching the source, while technically fine, can become very complicated and unmanageable. To make patching easier and more straightforward patch systems were developed. We will take a look at couple popular ones. このソースに対するパッチの作成方法は、技術的にはうまくいきますが、とても複雑で管理しづらいものになり得ます。もっと簡単で素直にパッチを作成できるパッチシステムが開発されました。次節以降で、もっとも一般的な二つの方法を見ていきましょう。 ||<:20%>,,<=,, ||<:60%>||<:20%> ,,=>,,|| ||<:20%>[[UbuntuPackagingGuideJa/ps-chap|パッチシステム]]||<:60%>'''パッチシステムを用いないパッチ適用'''||<:20%> [[UbuntuPackagingGuideJa/ch05s02|Simple PatchsysとCDBS]]||