Linux下的一些开源的软件源码包释放时会有一个软件包和补丁文件,我们根据需求可以选择是否对这个软件包进行打补丁。同时,有时为了记录对一些比较庞大的软件工程的源码的更改位置时,也会将自己对源代码的更改的生成补丁文件。补丁文件便于释放给别人,也可以记录我们对源码更改的位置,便于我们后期进行追溯。因此,学习如何制作补丁文件和打补丁操作很有意义。
1、补丁生成
补丁文件是通过diff命令生成的,生成补丁文件的命令使用格式如下:
diff -uNr src modify > patch_file
对于diff命令,它的功能就是逐行比较两个文件的不同,然后输出比较的结果。如果将diif输出的比较结果保存到某个文件中,这个文件也就是所谓的diff补丁文件
命令选项:
- -u:选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些
- -N:选项确保补丁文件将正确地处理已经创建和删除文件的情况
- -r:递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件
FILES:
- src:源文件(目录),未进行修改的
- modify:基于src,根据需求对里面的文件内容修改之后结果
">" 是重定向符号,表示将diff比较的结果重定向输入到patch_file文件中(如不指定重定向,diff的结果将打印到标准输出),patch_file文件一般指定以.patch为后缀。
上述的补丁命令的功能就是逐个比较源文件(夹)和目标文件(夹)的所有文件,将差异信息记录到patch_file中,patch_file文件也就是我们所谓的补丁文件。
2、打补丁
有了补丁文件那么就可以来进行打补丁操作了,打补丁是通过patch命令完成的。一般情况下,打补丁命令使用格式如下(这里只介绍了对源文件(夹)进行打补丁操作):
patch -pN < xxx.patch
xxx.patch文件是上面diff命令生成的补丁文件,打补丁就是patch利用diff制作的补丁来实现源文件(夹)和目的文件(夹)的转换。这样说就意味着你可以从源文件(夹)到目的文件(夹),也可以目的文件(夹)到源文件(夹)。一般情况下,我们都是将源文件打补丁到我们修改后的目的文件。
选项:
- -pN:选项打补丁时要忽略掉第N层目录
这里还是以实例来说明-pN选项的作用,假如补丁文件内有这样格式内容:
diff -uNr src/bsp/bsp_led.c modify/bsp/bsp_led.c
当我们在src目录下进行打补丁时,此时打补丁所在的目录是在src目录,它从当前目录下可以寻找bsp的文件夹,在它下面找bsp_led.c,所以此时需要用-p1来指定忽略第一个/前的目录(这里用到的是相对路径)。
3、简单测试
创建src目录及各目录下的文件,将src目录内容拷贝到modify目录,修改modify目录里的各个源文件。
目录层次信息如下所示:
├── modify
│ ├── bsp
│ │ ├── bsp_led.c
│ │ └── bsp_uart.c
│ └── main.c
├── src
│ ├── bsp
│ │ ├── bsp_led.c
│ │ └── bsp_uart.c
│ └── main.c
使用diff命令生成补丁文件,补丁文件名src_20210416.patch
diff -uNr src/ modify/ > src_20210416.patch
src_20210416.patch补丁文件内容格式如下:
diff -uNr src/bsp/bsp_led.c modify/bsp/bsp_led.c ------------------->① --- src/bsp/bsp_led.c 2021-04-16 09:07:19.638716463 +0800 -------->② +++ modify/bsp/bsp_led.c 2021-04-16 09:48:08.966764603 +0800 @@ -1,7 +1,9 @@-------------------->③ #include "bsp_led.h" - -------------------------------->④ +/* + * @brief: led initialization + */ void bsp_led_init(void) { - + }
① 表示下面内容是哪个源文件和目标文件的比较结果
② ‘---‘表示的是源文件是哪个,‘+++‘表示的是目标文件是哪个
③ 源文件和目标文件差异位置描述,-1,7表示源文件的1到7行,+1,9表示目标文件的1到9行
④ -表示源文件中该位置本来内容,+表示将源文件中的内容要替换成的内容
使用patch命令对src文件进行打补丁,打补丁完成后,src中的各文件内容和modify中各文件的内容一致了。
patch -p0 < src_20210416.patch
测试目录下各文件内容
src目录:
int main(int argc, char **argv) { return 0; }
#include "bsp_led.h" void bsp_led_init(void) { }
#include "bsp_uart.h" void bsp_uart_init(void) { }
modify目录:
#include "bsp_uart.h" #include "bsp_led.h" int main(void) { bsp_led_init(); bsp_uart_init(); while(1) { } return 0; }
#include "bsp_led.h" /* * @brief: led initialization */ void bsp_led_init(void) { }
#include "bsp_uart.h" /* * @brief: uart initialization */ void bsp_uart_init(void) { }