Menu Close

2.6. 修复软件

在 RPM 打包中,而不是修改原始源代码,我们保留它,并在上面使用补丁。

补丁(patch)是用于更新其他源代码的源代码。它被格式化为 diff,因为它代表文本的两个版本之间的区别。使用 diff 实用程序创建 diff,然后使用 patch 实用程序应用到源代码。

注意

软件开发人员通常使用版本控制系统(如 git )来管理其代码库。这些工具提供自己创建 diffs 或 patching 软件的方法。

本节介绍如何修补软件。

以下示例演示了如何使用 diff 从原始源代码创建补丁,以及如何使用 patch 应用补丁。创建 RPM 时,将在后面的章节中使用补丁。

此流程演示了如何从原始源代码为 cello.c 创建补丁。

步骤

  1. 保留原始源代码:

    $ cp -p cello.c cello.c.orig

    -p 选项用于保留模式、所有权和时间戳。

  2. 根据需要修改 cello.c

    #include <stdio.h>
    
    int main(void) {
        printf("Hello World from my very first patch!\n");
        return 0;
    }
  3. 使用 diff 实用程序生成补丁:

    $ diff -Naur cello.c.orig cello.c
    --- cello.c.orig        2016-05-26 17:21:30.478523360 -0500
    + cello.c     2016-05-27 14:53:20.668588245 -0500
    @@ -1,6 +1,6 @@
     #include<stdio.h>
    
     int main(void){
    -    printf("Hello World!\n");
    +    printf("Hello World from my very first patch!\n");
         return 0;
     }
    \ No newline at end of file

    - 开头的行将从原始源代码中删除,并替换为以 + 开头的行。

    建议将 Naur 选项与 diff 命令一起使用,因为它符合大多数常见用例。然而,在这种情况下,只需要 -u 选项。具体选项可确保:

    • -N (或 --new-file)- 处理缺少的文件,就像它们是空文件一样。
    • -a (或 --text)- 将所有文件作为文本文件。因此,被 diff 认为是二进制的文件不会被忽略。
    • -u (or -U NUM--unified[=NUM]) - 以统一上下文的输出 NUM(默认为 3)行返回输出。这是一个易于阅读的格式,允许在将补丁应用到更改的源树时进行模糊匹配。
    • -r (or --recursive) - 递归比较任何找到的子目录。

      有关 diff 实用程序通用参数的更多信息,请参阅 diff 手册页。

  4. 将补丁保存到文件中:

    $ diff -Naur cello.c.orig cello.c > cello-output-first-patch.patch
  5. 恢复原始 cello.c

    $ cp cello.c.orig cello.c

    必须保留原始 cello.c,因为当构建 RPM 时,将使用原始文件,而不是修改的原始文件。如需更多信息,请参阅使用 SPEC 文件

以下步骤演示了如何使用 cello-output-first-patch.patchcello.c 进行补丁,构建补丁的程序并运行它。

步骤

  1. 将补丁文件重定向到 patch 命令:

    $ patch < cello-output-first-patch.patch
    patching file cello.c
  2. 检查 cello.c 的内容现在是否反映了这个补丁:

    $ cat cello.c
    #include<stdio.h>
    
    int main(void){
        printf("Hello World from my very first patch!\n");
        return 1;
    }
  3. 构建并运行补丁的 cello.c

    $ make clean
    rm cello
    
    $ make
    gcc -g -o cello cello.c
    
    $ ./cello
    Hello World from my very first patch!