有相当多的关于使用ABS时,如何自己制作软件包的补丁及如何使用补丁的问题。本文将大致讲述其步骤及必要的条件。http://www.kegel.com/academy/opensource.html也有很多关于补丁文件的信息。
制作补丁
如果你正在使用从别处得到的补丁(比如,下载的kernel补丁),你可以跳过本节,直接阅读下一节。但如果你想编辑源代码、makefile、配置文件等,你可能会需要制作补丁。
注意:如果你仅仅需要改动一个文件的一两行(比如,一个makefile),或许你更应该研究一下sed。
制作软件包的补丁牵涉到建立两个版本的软件包,编辑新包并就两个文件建立标准的diff。当建立软件包时,可按以下方法来进行:
1.将下载的源文件名加入你要建立的PKGBUILD文件的source列表中。当然,如果你是修改一个软件包,得仔细一点。
2.建立一个空的build函数(只有一行echo的最好)。如果你在修改PKGBUILD文件,最好注释掉build函数中的一些语句。因为可能要运行makepkg好几次,你可能不想花时间去建一个没用的包。
3.运行makepkg,这将会下载你将在src目录中修改的源代码。
4.进入src目录。正常情况下,这儿已生成一个包含已解压文件的目录(有时会只有一个文件,但diff仍旧可以工作)。你应该为这些目录做两个备份——一个用来备份,别碰它;另一个用来生成新版本的包,并以此来做补丁。你可以分别为这两份拷贝命名为package.pristine和package.new或是其他类似的名称。
5.进入package.new目录,编辑需改动的文件。如何改动取决于补丁的制作,可能是纠正Makefile的路径,可能是改正源码中的错误(例如,gcc 3.4)等等。你也可以修改package.new的子目录中的文件。不要执行会在package.new目录中建立一堆新文件的命令,也就是说,不要为了确认你的修改而编译程序。问题在于,所有的新文件都将被包含在补丁中,显然,你要的并不是这个。应该将补丁应用在另一个目录中(不是备份的package.pristine),或者手动为其打上补丁,也可以在PKGBUILD中实现打补丁,并在这个目录中测试。
6.回到src目录。
7.运行diff -aur package.pristine package.new。这将以标准的diff格式输出你所做的修改。你可以检查以确信补丁的正确。
8.运行diff -aur package.pristine package.new > package.patch,将所有的改变输出到名为package.patch的文件中。这就是我们要的补丁文件。你现在就可以将这些改变应用到原目录中去,以证实其可以完好地运行。你还应该检查,以确信补丁中没有包含任何无关的信息。例如,你不希望补丁将文件中的所有的tab转换成空格,但你的文本编辑在幕后这么做了。你可以用文本编辑器来编辑补丁文件,或者,更安全一点,编辑源文件,重新生成补丁(不会偶然地将错误带入补丁文件)。
应用补丁
本节将概述如何在PKGBUILD文件中的build函数中应用自己制作的或下载的补丁文件。步骤如下:
1.在PKGBUILD文件的source列表中加入补丁文件名。如果补丁文件可以下载,你可以将其URL加入其中,它会被自动下载并放入src目录。如果是你自己制作的补丁,或者无处可下,你应该将补丁文件与PKGBUILD文件放在同一目录中,并直接将补丁文件名放在source列表中。如果你发布了PKGBUILD文件,你应该同时发布补丁文件。
2.建立PKGBUILD文件中的build函数。大多数情况下,第一件事就是打补丁,但你应该知道何时打补丁是最合适的。
3.第一步是进入需打补丁的目录(这是在build函数中,而不是在你的终端里!你要的是自动打上补丁)。你可以像这样进入目录cd $startdir/src/$pkgname-$pkgver或使用类似的命令。$pkgname-$pkgver通常就是下载的源文件解压后的目录名,但并不总是这样。
4.现在,你只才有可能在此目录中简单地应用补丁就可以了。非常简单,在build函数中加入patch -p1 -i ../pkgname.patch就可以了,将pkgname.patch用包含diff的文件名代替(因为这个文件的名字出现在PKGBUILD文件的source列表中,它将被自动拷入src目录)。
5.运行makepkg(这回是在终端里了)。如果一切顺利,补丁就自动打上了,你的新包也会包含你所修改的部分了。如果有问题,你就要试试patch命令的-p选项了,具体可以看一看patch的手册页。
一般地,一切将如下所述。如果diff文件是用来为myversion/目录下的filey文件打补丁的,那么diff文件就会作用于myversion/file。你会在yourversion/目录中运行(因为在PKGBUILD中已进入此目录了),所以当打完补丁后,你希望它作用于file文件,忽略myversion/部分。-p1选项会这么做,从路径中拿掉一个目录。不管怎样,如果开发者为myfiles/myversion打补丁,你就需要忽略两个目录,那么就使用-p2选项。
如果你没有使用-p选项,它将忽略所有目录结构。如果所有文件都在一个目录的话,一切OK。但是,当补丁是基于myversion/目录建立的,并且有一个修改后的文件为myversion/src/file,如果你在yourversion目录中运行不带-p选项的patch命令,它将试图为yourversion/file打补丁。
大多数开发者是从需打补丁的父目录制作补丁文件,所以通常情况下,使用-p1就对了