Tuesday, February 10, 2009

How to patch and recompile a source rpm ?

Let me explain this through an example. The source rpm that I have in my Laptop while writing this is for pam_krb5. So I am taking this as an example. The base system which is used to do this is an RHEL5 system.

- Make sure that rpm-build package is installed on the system.

# yum install rpm-build

- Install the source rpm.

# rpm -ivh pam_krb5-2.2.14-1.el5_2.1.src.rpm

- Change to /usr/src/redhat/SPECS direcotry.

# cd /usr/src/redhat/SPECS/

- Just prepare the source for compilation by unpacking the source and applying the patches already defined.

# rpmbuild -bp pam_krb5.spec

Note: It's highly likely that the above command could fail with missing dependency errors which are required to compile the package. Just installing the recommended packages in the output and re-running the above command after that would be fine to run the above command without any errors.

- Move to /usr/src/redhat/BUILD directory. We can see the source unpacked in that directory.

# ls
pam_krb5-2.2.14-1

- Take a backup of the entire unpacked source which is required to generate the patch.

# cp -r pam_krb5-2.2.14-1/ pam_krb5-2.2.14-1.orig

Now the modification that I need to make to the source is to change the warining message given in pam_krb5-2.2.14-1/src/sly.c line no 168 from

warn("won't refresh credentials while running under sudo");

To

warn("Sir, couldn't refresh credentials while running under sudo");

- Simply Edit the file using your favorite editor and make the above change in the pam_krb5-2.2.14-1/src/sly.c and save the file.

- Now change the directory to /usr/src/redhat/BUILD directory using "cd" command and generate a patch using the diff command and save the patch in /usr/src/redhat/SOURCES. Name the file just like other patches for pam_krb5 are named in the SOURCES directory.

[root@localhost BUILD]# diff -Naur pam_krb5-2.2.14-1.orig/ pam_krb5-2.2.14-1 > ../SOURCES/pam_krb5-2.2.14-warning.patch

- The content of the pam_krb5-2.2.14-warning.patch would be as below.

diff -Naur pam_krb5-2.2.14-1.orig/src/sly.c pam_krb5-2.2.14-1/src/sly.c
--- pam_krb5-2.2.14-1.orig/src/sly.c 2009-02-11 11:07:36.000000000 +0530
+++ pam_krb5-2.2.14-1/src/sly.c 2009-02-11 11:11:16.000000000 +0530
@@ -165,7 +165,7 @@
/* nothing: everything's okay */
break;
case 1:
- warn("won't refresh credentials while running under sudo");
+ warn("Sir, Couldn't refresh credentials while running under sudo");
return PAM_SERVICE_ERR;
break;
case 2:

- Now come back to /usr/src/redhat/SPECS directory and start editing the spec file. My spec file is named pam_krb5.spec. Make the below changes to apply the patch while compiling the rpm.

* Increment the Release number. It was as below in my spec file.

Release: 1%{?dist}.1

I changed it to

Release: 1%{?dist}.2

* Define your patch as the last patch in the "Patchx" section. I defined it as below.

Patch1 pam_krb5-2.2.14-warning.patch

* In the %prep section, come to the last of %patchx and add your patch as the last patch. I added the below line.

%patch1 -p1 -b .warning

* In the %changelog section, document this change as the first entry. I made the below change.

* Wed Feb 11 2009 Blah Blah - 2.2.14-1%{?dist}.2
- Change the warning message when trying to refresh while running under sudo (bz #xxxx)

- Now we are all set to start recompiling the rpm. Below command can be used to recompile an rpm.

# rpmbuild -ba pam_krb5.spec

Watch that the patch is applied cleanly. I can see the below message which clearly says that the patch has been applied cleanly.

+ echo 'Patch #1 (pam_krb5-2.2.14-warning.patch):'
Patch #1 (pam_krb5-2.2.14-warning.patch):
+ patch -p1 -b --suffix .warning -s

- Once the compilation process is complete, we can see the new rpm in /usr/src/redhat/RPMS/$arch/.

1 comment:

Joshua Daniel Franklin said...

For dependencies, there is also mock or auto-buildrequires:

http://et.redhat.com/~rjones/auto-buildrequires/