2.6. Patching software
In RPM packaging, instead of modifying the original source code, we keep it, and use patches on it.
A patch is a source code that updates other source code. It is formatted as a diff, because it represents what is different between two versions of the text. A diff is created using the diff
utility, which is then applied to the source code using the patch utility.
Software developers often use Version Control Systems such as git to manage their code base. Such tools provide their own methods of creating diffs or patching software.
This section explains how to patch the software.
The following example shows how to create a patch from the original source code using diff
, and how to apply the patch using patch
. Patching is used in a later section when creating an RPM.
This procedure shows how to create a patch from the original source code for cello.c
.
Procédure
Preserve the original source code:
$ cp -p cello.c cello.c.orig
The
-p
option is used to preserve mode, ownership, and timestamps.Modify
cello.c
as needed:#include <stdio.h> int main(void) { printf("Hello World from my very first patch!\n"); return 0; }
Generate a patch using the
diff
utility:$ 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
Lines starting with a
-
are removed from the original source code and replaced with the lines that start with+
.Using the
Naur
options with thediff
command is recommended because it fits the majority of usual use cases. However, in this particular case, only the-u
option is necessary. Particular options ensure the following:-
-N
(or--new-file
) - Handles absent files as if they were empty files. -
-a
(or--text
) - Treats all files as text. As a result, the files thatdiff
classifies as binaries are not ignored. -
-u
(or-U NUM
or--unified[=NUM]
) - Returns output in the form of output NUM (default 3) lines of unified context. This is an easily readable format that allows fuzzy matching when applying the patch to a changed source tree. -r
(or--recursive
) - Recursively compares any subdirectories that are found.For more information on common arguments for the
diff
utility, see thediff
manual page.
-
Save the patch to a file:
$ diff -Naur cello.c.orig cello.c > cello-output-first-patch.patch
Restore the original
cello.c
:$ cp cello.c.orig cello.c
The original
cello.c
must be retained, because when an RPM is built, the original file is used, not the modified one. For more information, see Working with SPEC files.
The following procedure shows how to patch cello.c
using cello-output-first-patch.patch
, build the patched program, and run it.
Procédure
Redirect the patch file to the
patch
command:$ patch < cello-output-first-patch.patch patching file cello.c
Check that the contents of
cello.c
now reflect the patch:$ cat cello.c #include<stdio.h> int main(void){ printf("Hello World from my very first patch!\n"); return 1; }
Build and run the patched
cello.c
:$ make clean rm cello $ make gcc -g -o cello cello.c $ ./cello Hello World from my very first patch!