linux下补丁制作及打补丁实例【转】

转自:http://www.latelee.org/using-gnu-linux/diff-and-patch-on-linux.html

搞ARM有一段时日了,期间看了不少开发板的手册,手册的内容多数为教我们如何使用开发板,而不是教我们如何开发。手册中少不了显示linux下的命令,不过对这些命令有几点看法:

1、很多操作都使用了绝对路径,我想大约是为了表示这个路径的关系吧,不然的话,对于新手来说,来回几个cd,就搞不清楚在哪个目录了,这点表示赞同。不过对于我来说,实在不会如此操作;

2、统一使用root用户,因为许多人都使用虚拟机的linux作主机系统,所以想用哪个用户都无所谓,然而在实际开发中却不是这样。因此这点我就不赞同了。linux的权限意识非常强的,如果试过多人工作于同一台服务器的话,就能体会到了。不过话又说回来,对于新手来说,用root可能十分便利,因为不会存在不能访问哪个文件、哪个设备的问题,畅通无阻。最近,boss用root用户在rhel中编译qtopia,出现了使用g++错误的问题:

g++: error trying to exec ‘cc1plus‘: execvp: No such file or directory

我们想了很久,得到一个非权威的解释:rhel不允许root来编译qtopia,用普通用户无此问题。

本文背景:

1、练习制作补丁和打补丁;

2、以以前的程序代码lib-test为例,演示制作补丁和打补丁过程。

lib-test示例见http://www.latelee.org/programming-under-linux/multi-makefile-for-app.html

为了不造成误解,引起误导,本文的假设如下:

1、原工程目录为lib-test-org,修改后的工程目录为lib-test-new,两个目录均在cst目录下:

[[email protected] cst]$ pwd

/home/latelee/cst

2、本文提到的“原始文件”及“原始工程目录”等等,是指未经修改过的工程目录、源代码包等,比如在网上下载qtopia-2.2.0的原始代码包、U-Boot原始代码包、Linux内核原始代码包。

3、由于这里只是测试,因此建立了lib-test-new,并在这个目录下修改文件。

4、实际应用中,一般会提供原始代码包及补丁文件。

示例

修改地方如下:

1、在三个头文件中添加如下类似信息:

/**

* @file   foo.h

* @author Late Lee <http://www.latelee.org>

* @date   Thu Apr  7 2011

*

* @brief  none

*

*

*/

2、修改main.c,将头文件包括的双引号(“”)改为尖括号(<>),此外添加一些版权信息及编译命令等等。

3、修改主目录下的Makefile,主要添加:

%.o: %.c

$(CC) $(CFLAGS) -c $^ -I ./configs

即由-I选项指定头文件位置(因此可以在代码中使用尖括号)。

4、其它修改若干。

注:上述修改仅为示例,以实际修改为准。

示例过程:

1、制作补丁

在cst目录下(即在两个工程目录的同一目录下)使用diff命令制作补丁:

[[email protected] cst]$ diff -urN lib-test-org/ lib-test-new/ > lib-test.patch

(注:-r表示递归搜索子目录,更多选项,请man diff。)

这样就在该目录下生成了一个叫lib-test.patch的补丁文件。

这里分析一下patch文件,以第一块为例:

diff -urN lib-test-org/configs/backtrace.h lib-test-new/configs/backtrace.h

— lib-test-org/configs/backtrace.h 2011-04-07 09:04:06.000000000 +0800

+++ lib-test-new/configs/backtrace.h 2011-04-07 08:22:55.000000000 +0800

@@ -1,3 +1,13 @@

+/**

+ * @file   backtrace.h

+ * @author Late Lee <http://www.latelee.org>

+ * @date   Thu Apr  7 2011

+ *

+ * @brief  none

+ *

+ *

+ */

+

#ifndef _BACKTRACE_H

#define _BACKTRACE_H

这里分三部分来分析。

第一部分即第1行,文中以粗体字体标示,是制作补丁所使用的命令,后面的是两个工程目录的文件。

第二部分为第2、3行,“—”表示原始文件,“+++”表示修改过的文件。

剩下的是第三部分,“@@ -1,3 +1,13 @@”中的“-1,3”表示原始文件的第1行到第3行,“+1,13”表示修改过的文件的第1行到第13行。两者之差的内容即为修改的内容,其中减号(“-”)表示删除,加号(“+”)表示添加。

下面看一下backtrace.h文件。

backtrace.h完整的原始代码如下(注意该文件的第1行到第3行内容):

1  #ifndef _BACKTRACE_H

2  #define _BACKTRACE_H

3

4   /* Even complicated programs rather seldom have a nesting

5   * level of more than, say, 50 and with 200 possible entries

6   * probably all programs should be covered. — from glibc manual

7   */

8   /* here, we let it be 30 */

9  #define NEST        30

10  void print_trace(int sig);

11  void print_trace_fd(int sig);

12  void print_trace_file(int sig);

13

14  #endif  /* _BACKTRACE_H */

修改后的代码如下(注意该文件的第1行到第13行内容):

1    /**

2    * @file   backtrace.h

3    * @author Late Lee

4    * @date   Thu Apr  7 2011

5    *

6    * @brief  none

7    *

8    *

9    */

10

11   #ifndef _BACKTRACE_H

12   #define _BACKTRACE_H

13

14    /* Even complicated programs rather seldom have a nesting

15    * level of more than, say, 50 and with 200 possible entries

16    * probably all programs should be covered. — from glibc manual

17    */

18    /* here, we let it be 30 */

19   #define NEST        30

20   void print_trace(int sig);

21   void print_trace_fd(int sig);

22   void print_trace_file(int sig);

23

24   #endif  /* _BACKTRACE_H */

应该看到了区别了吧?因此,所谓打补丁的大约意思可以这么说:

将原来的backtrace.h文件的第1行到第3行内容用“下面”的内容代替,行数从第1行到第13行。

其中的“下面”就是指那些“+”、“-”的内容了。

2、打补丁

进入lib-test-org目录下,使用patch命令打补丁:

[[email protected] lib-test-org]$ patch -p1 < ../lib-test.patch

patching file configs/backtrace.h

patching file configs/bar.h

patching file configs/foo.h

patching file main.c

patching file Makefile

patching file nomain.c

一般地,都将patch文件放到与原始工程目录同一级目录中。

在man patch中有一句话:but usually just patch -pnum <patchfile

实际中常用的是-p1,网上说法是忽略第一个目录,看了一下man手册,准确说法是忽略第一个斜杠(“/”),比如/u/howard/src/blurfl/blurfl.c,如果是-p1的话,表示u/howard/src/blurfl/blurfl.c,用-p4的话,表示blurfl/blurfl.c,等等。

以上述patch片段的第一行为例:

diff -urN lib-test-org/configs/backtrace.h lib-test-new/configs/backtrace.h

如果用-p1,则表示configs/backtrace.h,这个是相对于工程目录路径,无论是在lib-test-org,还是lib-test-xxx中,也不管这个lib-test-org在哪个目录,路径依然不改变(当然,我们的前提是两者是同一事物,比如内核树、u-boot)。

上面的提示信息表示正在给哪个文件打补丁。打完补丁后,两个目录的内容就一致了。不信的话,可以再次用diff命令测试一下:

[[email protected] cst]$ ls -l lib-test.patch

-rw-r–r– 1 latelee root 4137 04-07 09:05 lib-test.patch

[[email protected] cst]$ diff -urN lib-test-org/ lib-test-new/ > lib-test-new.patch

[[email protected] cst]$ ls -l lib-test-new.patch

-rw-r–r– 1 latelee root 0 04-07 09:07 lib-test-new.patch

可以看到,lib-test-new.patch大小为0,证明两个目录内容无差别。

本文语法高亮工具由迟思堂工作室(www.latelee.org)参考网上资料使用lex工具编写,代码添加行号由awk语句完成。语句如下:

$ awk ‘{printf(“%2d   %2sn”, FNR, $0)}’ backtrace.h > test.h

行文过程中并未过度引用网上资料,因此存在非权威解释,术语使用不当等问题,然而却由实践而来,具有实际操作性。

本文固定链接: http://www.latelee.org/using-gnu-linux/diff-and-patch-on-linux.html

时间: 2024-08-24 10:35:54

linux下补丁制作及打补丁实例【转】的相关文章

linux下递归删除空目录的bash实例

# $1必须是绝对路径crurl=$1func_hdir(){echo $crurl  cd $crurl  for aitem in `ls -l | grep "^d" | awk '{print $9}'`; do        crurl=$crurl/$aitem        func_hdir $aitem  done dirc=`ls $crurl`  if [ "$dirc" = "" ]  then    echo $crur

Linux下实现MySQL多端口多实例运行

声明 作者:昨夜星辰 博客:http://yestreenstars.blog.51cto.com/ 本文由本人创作,如需转载,请注明出处,谢谢合作! 目的 Linux下实现MySQL多端口多实例运行. 主要操作 创建/etc/my_multi.cnf文件 vi /etc/my_multi.cnf 内容如下(注意!如果你的MySQL是通过源代码方式安装,请根据实际情况更改mysqld和mysqladmin这两项,还有就是注意更改root的密码.) [mysqld_multi] mysqld = 

在Linux下的找不同-打补丁

Q:为什么要找不同,为什么要打补丁? A: 在Linux应用中,作为DBA,我们知道MySQL跑在Linux系统之上,数据库最重要的追求就是性能,"稳"是重中之重,所以不能动不动就是换系统或是换这换那的,这个时候除非是万不得已,要不然都是在原有基础上改改就行了,也就是给内核及下载的一些源码打补丁或者说是升级,那么在Linux下使用diff制作补丁以及如何使用patch打补丁显得尤为重要. 一.找不同:diff命令(differences) -- compare files line b

linux下如何制作initrd镜像?

1. 准备文件 加入已经准备好了所有文件在/home/initrd-base目录下 2. 制作initrd镜像 cd /home/initrd-base/ ;find . | cpio --quiet -H newc -o | gzip -9 -n > ../initrd.gz mkimage -n 'uboot ext2 ramdisk rootfs' -A arm64 -O linux -T ramdisk -C gzip -d initrd.gz initrd.gz.uboot (Wron

Linux下vi替换字符命令操作实例

在Linux下的开发中,经常涉及到对文件里的字符进行处理,当中,对字符的替换操作也是非常的频繁. 本文以一个实际的文件为例,具体介绍了Linux下经常使用的vi替换字符命令,为相关的开发工作提供给了參考. 本文中被操作的文件为TestFile.txt,当中的内容例如以下: [email protected]:~/zhouzx/Test> cat TestFile.txt 12345678907890 ABCDABCDEFGHIJ 12345^&*()() 98765432103210 abc

linux下mysql的安装以及多实例操作

一.linux系统基本信息 [[email protected] application]# cat /etc/redhat-release CentOS release 6.7 (Final) [[email protected] application]# uname -a Linux db01 2.6.32-573.el6.x86_64 #1 SMP Thu Jul 23 15:44:03 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux 二.mysql的安装

linux下select函数详解及实例

一.概述: 系统提供select函数来实现I/O复用输入/输出模型.select系统调用是用来让我们的程序监视多个文件句柄的状态变化的.程序会停在select这里等待,直到被监视的文件句柄中有一个或多个发生生了状态改变. 二.select函数: 以下为man文本中的解释:  /* According to POSIX.1-2001 */        #include <sys/select.h>        /* According to earlier standards */     

linux下支持伪静态和rewrite的实例

虽然很多域名提供商均支持url转发,但是有时我们需要自己实现转发,以下为自己工作中遇到的问题,特别上 : 1,用.htaccess来实现 在apache配置文件内或虚拟主机配置文件内 开启AllowOverride(all) <Directory /www/users/xxx> AllowOverride all </Directory> 在/www/users/xxx目录下创建.htaccess文件 写入 Redirect permanent / http://www.baidu

【转】Linux下RabbitMQ服务器搭建(单实例)

阅读目录 系统环境 安装步骤 注意事项 参考资料 回到顶部 系统环境 操作系统:CentOS6.9 erlang:OTP 19.3 rabbitmq:rabbitmq-server 3.6.12 回到顶部 安装步骤 安装erlang 1,安装预环境 通过yum安装以下组件,运行命令: [[email protected] erlang]# yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel 2,下