给文件打补丁
接触到打补丁还是在下linux内核的时候,在linux内核下载资源的网站上提供了相对应前一个版本的补丁下载,这样如果下载了前一个版本,要更新到当前版本,不用再把整个的内核都下载下来,只要下载当前版本相对于前一个版本的补丁就可以了,这样既节约了时间也节约了带宽。本文先介绍了怎样给linux内核打补丁,然后介绍怎样制作自己的补丁文件,并根据补丁文件给文件打补丁。
一、 给linux内核打补丁
给linux内核打补丁首先要明白每个新版本的补丁都是基于某个稳定版做的,所以我们先要理解linux内核的版本号代表的意思:
Linux内核版本有两种:稳定版和开发版 ,Linux内核版本号由3组数字组成:第一个组数字.第二组数字.第三组数字
第一个组数字:目前发布的内核主版本。
第二个组数字:偶数表示稳定版本;奇数表示开发中版本。
第三个组数字:错误修补的次数。
例如我的电脑的内核版本为2.6.32-38,代表的意思就是主版本为2,是稳定版本,第32次修改,38代表的是当前版本的第38次微调patch。
如果我要把版本升级到2.6.32-39,到内核官网上下载补丁patch-2.6.32.39,这个补丁是基于稳定版2.6.32的,所以如果我的内核版本要升级到2.6.32-39,就要先将版本回退到2.6.32,然后再升级到2.6.32-39。具体如下:
假设我已经在内核的目录中。补丁放在内核目录。
xzcat patch-2.6.32.38.xz | patch -p0 -R #回退到2.6.32
xzcat patch-2.6.32.39.xz | patch -p0 #升级到2.6.32.39
如果我要升级到2.6.33版本呢?一样的,先要回退大都2.6.32版本,然后从2.6.32升级到2.6.33版本,方法和前面一样。
二、 制作自己的补丁文件
准备一个旧文件macro.c,它的内容如下:
#include <iostream> struct test { int a; int b; }; struct test p; #define inc(rq, field) do {(rq)->field++;} while (0) int main(void) { struct test *pp = &p; pp->a = pp->b = 0; inc(pp, a); inc(pp, b); std::cout << pp->a << " " << pp->b << std::endl; return 0; }
准备一个新文件macro_new.c,它的内容如下:
#include <iostream> struct test { int a; int b; }; struct test p; #define inc(rq, field) do {(rq)->field++;} while (0) int main(void) { struct test *pp = &p; pp->a = pp->b = 0; inc(pp, a); inc(pp, b); /*去除打印语句*/ return 0; }
制作补丁文件:
diff -up macro.c macro_new.c > patch-macro-2013-10-30
制作的patch-macro-2013-10-30补丁文件内容为:
1 --- macro.c 2013-10-30 17:29:44.594212235 +0800 2 +++ macro_new.c 2013-10-30 18:33:49.164108493 +0800 3 @@ -20,6 +20,6 @@ int main(void) 4 pp->a = pp->b = 0; 5 inc(pp, a); 6 inc(pp, b); 7 - std::cout << pp->a << " " << pp->b << std::endl; 8 + /*去掉打印语句*/ 9 return 0; 10 }
第七行的-表示新文件中去掉了该行,+表示新文件中增加了改行。
根据补丁文件修改原文件为新文件的内容:
patch -p0 < patch-macro-2013-10-30
这样macro.c文件的内容和macro_new.c一样了。
回退到原来的文件:
patch -p0 -R < patch-macro-2013-10-30