[ 教学 ] 如何制作和应用补丁

有时候打包的时候,或者编译的时候会遇到问题,

需要改动源代码。

但是又面临这种情况:

  1. 这是重复工作,下次还得干
  2. 需要回馈给别人,比如上游开发者

这时候你就需要制作补丁了。

Linux 下制作补丁使用 diff 程序,打补丁使用 patch 程序。

一般新手不需要了解那么多(可用 命令行程序名 --help 查看更多选项),因为使用一个程序不是一定要了解全部选项才能叫「会」的。

我们假设你有一个名为 sourcecode 的源代码文件夹,首先你要做的是把它复制成 sourcecode.orig

然后进入 sourcecode 文件夹修改

制作补丁用

diff -urN sourcecode.orig sourcecode > sourcecode.patch

打补丁用

patch -p1 < sourcecode.patch

-p{0,1,2,3,…} 选项的含义是这样的:

--- sddm-20130319.orig/CMakeLists.txt
+++ sddm-20130319/CMakeLists.txt

如果 sddm-20130319.orig 和 sddm-20130319 都存在于你补丁放的目录,那么可以 -p0,比如这种情况

CMakeLists.txt.orig
CMakeLists.txt

否则就需要跳过第一个 / 前面的目录,于是也就是 -p1。以此类推。

简单说,就是这样。

** 补丁的格式: **

Index: sddm-20130319/CMakeLists.txt
===================================================================0@@ -86,11 +86,11 @@ endif()
 
 # set constants
 set(BIN_INSTALL_DIR     "${CMAKE_INSTALL_PREFIX}/bin"               CACHE PATH      "System binary install directory")4 set(CONF_INSTALL_DIR    "/etc"                                      CACHE PATH      "System config directory")
 
 set(PASSWD_FILE         "${CONF_INSTALL_DIR}/passwd"                CACHE PATH      "Path of the passwd file")
-set(CONFIG_FILE         "${CONF_INSTALL_DIR}/sddm.conf"             CACHE PATH      "Path of the sddm config file")
+set(CONFIG_FILE         "${CONF_INSTALL_DIR}/kde4/sddm/sddm.conf"             CACHE PATH      "Path of the sddm config file")
 set(LOG_FILE            "/var/log/sddm.log"                         CACHE PATH      "Path of the sddm log file")
 
 add_subdirectory(components)
--- sddm-20130319.orig/CMakeLists.txt
+++ sddm-20130319/CMakeLists.txt

表示未打补丁的文件是 .orig 文件夹的 CMakeLists.txt,下面那个是打了补丁的。但没人会有需要去修改这个。

-set(DATA_INSTALL_DIR    "${CMAKE_INSTALL_PREFIX}/share/apps/sddm"   CACHE PATH      "System application data install directory")
+set(DATA_INSTALL_DIR    "${CMAKE_INSTALL_PREFIX}/share/kde4/apps/sddm"   CACHE PATH      "System application data install directory")

表示把减号标记的代码替换成加号标记的。所以简单的补丁修改可以直接修改加号部分。

@@ -86,11 +86,11 @@

最 tricky 的是这行,一般人看不懂。

实际上它表示的是:

把 .orig/CMakeLists.txt 文件的第 86 行开始的 11 行,替换为 ./CMakeLists.txt 文件的第 86 行开始的 11 行。

有时候补丁打不上,出现 save to .rej 的提示的时候,是因为你这个程序有过改动,比如还打了别的补丁,或者制作补丁时候程序的版本和现在的版本不一样。除了手动把 .rej 文件中的内容给修改上去,还可以修改这里。

** 不用新建文件夹就做补丁: **

复制文件夹有时候太麻烦了。于是我们可以用 Debian 开发的 quilt 程序。

sudo zypper in quilt

进入 sourcecode 目录后,

quilt new 1.patch

这会初始化你的补丁。

quilt add CMakeLists.txt

这会添加要打补丁的文件。

然后直接修改文件。(注意,一定要 add 之后才能修改)

然后

quilt refresh 1.patch

补丁就生成在 sourcecode/patches/1.patch 下了。

于是你就可以把自己修改的东西反馈给上游,做一个尊重上游尊重开发者的玩家了。

虽不明但觉厉 :joy:

nano 才是普通人的选择啊……

sudo nano _filename_ 

vi 起码也要灌输一下神马是模式还奇怪的 ijk 之类的……nano 基本就是一个终端里面的记事本(虽然更加强大)……下面就列出了主要的快捷键,比 vim 容易上手多了,而且基本的编辑功能完全够用啦~~

就是有些发行版可能开始没有装 nano……

修改源码还是用 git 之类管理下,git diff 什么的也很方便

嗯 patch 这之类的功能我觉得应该放在进阶区, 或者编译打包之类的区里面