Red Hat Training

A Red Hat training course is available for RHEL 8

Chapter 3. Preparing software for RPM packaging

To prepare a piece of software for packaging with RPM, you can first patch the software, create a LICENSE file for it, and archive it as a tarball.

3.1. Patching software

When packaging software, you might need to make certain changes to the original source code, such as fixing a bug or changing a configuration file. In RPM packaging, you can instead leave the original source code intact and apply patches on it.

A patch is a piece of text that updates a source code file. The patch has a diff format, because it represents the difference between two versions of the text. You can create a patch by using the diff utility, and then apply the patch to the source code by using the patch utility.

Note

Software developers often use Version Control Systems such as Git to manage their code base. Such tools offer their own methods of creating diffs or patching software.

3.1.1. Creating a patch file for a sample C program

You can create a patch from the original source code by using the diff utility. For example, to patch a Hello world program written in C (cello.c), complete the following steps.

Prerequisites

  • You installed the diff utility on your system:

    # yum install diffutils

Procedure

  1. Back up the original source code:

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

    The -p option preserves mode, ownership, and timestamps.

  2. Modify cello.c as needed:

    #include <stdio.h>
    
    int main(void) {
        printf("Hello World from my very first patch!\n");
        return 0;
    }
  3. Generate a patch:

    $ 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 that start with + replace the lines that start with -.

    Note

    Using the Naur options with the diff command is recommended because it fits the majority of use cases:

    • -N (--new-file)

      The -N option handles absent files as empty files.

    • -a (--text)

      The -a option treats all files as text. As a result, the diff utility does not ignore the files it classified as binaries.

    • -u (-U NUM or --unified[=NUM])

      The -u option returns output in the form of output NUM (default 3) lines of unified context. This is a compact and an easily readable format commonly used in patch files.

    • -r (--recursive)

      The -r option recursively compares any subdirectories that the diff utility found.

    However, note that in this particular case, only the -u option is necessary.

  4. Save the patch to a file:

    $ diff -Naur cello.c.orig cello.c > cello.patch
  5. Restore the original cello.c:

    $ mv cello.c.orig cello.c
    Important

    You must retain the original cello.c because the RPM package manager uses the original file, not the modified one, when building an RPM package. For more information, see Working with spec files.

Additional resources

  • diff(1) man page

3.1.2. Patching a sample C program

To apply code patches on your software, you can use the patch utility.

Prerequisites

Procedure

The following steps apply a previously created cello.patch file on the cello.c file.

  1. Redirect the patch file to the patch command:

    $ patch < cello.patch
    patching file cello.c
  2. Check that the contents of cello.c now reflect the desired change:

    $ cat cello.c
    #include<stdio.h>
    
    int main(void){
        printf("Hello World from my very first patch!\n");
        return 1;
    }

Verification

  1. Build the patched cello.c program:

    $ make
    gcc -g -o cello cello.c
  2. Run the built cello.c program:

    $ ./cello
    Hello World from my very first patch!

3.2. Creating a LICENSE file

It is recommended that you distribute your software with a software license.

A software license file informs users of what they can and cannot do with a source code. Having no license for your source code means that you retain all rights to this code and no one can reproduce, distribute, or create derivative works from your source code.

Procedure

  • Create the LICENSE file with the required license statement:

    $ vim LICENSE

    Example 3.1. Example GPLv3 LICENSE file text

    $ cat /tmp/LICENSE
    This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
    
    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Additional resources

3.3. Creating a source code archive for distribution

An archive file is a file with the .tar.gz or .tgz suffix. Putting source code into the archive is a common way to release the software to be later packaged for distribution.

3.3.1. Creating a source code archive for a sample Bash program

The bello project is a Hello World file in Bash.

The following example contains only the bello shell script. Therefore, the resulting tar.gz archive has only one file in addition to the LICENSE file.

Note

The patch file is not distributed in the archive with the program. The RPM package manager applies the patch when the RPM is built. The patch will be placed into the ~/rpmbuild/SOURCES/ directory together with the tar.gz archive.

Prerequisites

  • Assume that the 0.1 version of the bello program is used.
  • You created a LICENSE file. For instructions, see Creating a LICENSE file.

Procedure

  1. Move all required files into a single directory:

    $ mkdir bello-0.1
    
    $ mv ~/bello bello-0.1/
    
    $ mv LICENSE bello-0.1/
  2. Create the archive for distribution:

    $ tar -cvzf bello-0.1.tar.gz bello-0.1
    bello-0.1/
    bello-0.1/LICENSE
    bello-0.1/bello
  3. Move the created archive to the ~/rpmbuild/SOURCES/ directory, which is the default directory where the rpmbuild command stores the files for building packages:

    $ mv bello-0.1.tar.gz ~/rpmbuild/SOURCES/

Additional resources

3.3.2. Creating a source code archive for a sample Python program

The pello project is a Hello World file in Python.

The following example contains only the pello.py program. Therefore, the resulting tar.gz archive has only one file in addition to the LICENSE file.

Note

The patch file is not distributed in the archive with the program. The RPM package manager applies the patch when the RPM is built. The patch will be placed into the ~/rpmbuild/SOURCES/ directory together with the tar.gz archive.

Prerequisites

  • Assume that the 0.1.1 version of the pello program is used.
  • You created a LICENSE file. For instructions, see Creating a LICENSE file.

Procedure

  1. Move all required files into a single directory:

    $ mkdir pello-0.1.1
    
    $ mv pello.py pello-0.1.1/
    
    $ mv LICENSE pello-0.1.1/
  2. Create the archive for distribution:

    $ tar -cvzf pello-0.1.1.tar.gz pello-0.1.1
    pello-0.1.1/
    pello-0.1.1/LICENSE
    pello-0.1.1/pello.py
  3. Move the created archive to the ~/rpmbuild/SOURCES/ directory, which is the default directory where the rpmbuild command stores the files for building packages:

    $ mv pello-0.1.1.tar.gz ~/rpmbuild/SOURCES/

Additional resources

3.3.3. Creating a source code archive for a sample C program

The cello project is a Hello World file in C.

The following example contains only the cello.c and the Makefile files. Therefore, the resulting tar.gz archive has two files in addition to the LICENSE file.

Note

The patch file is not distributed in the archive with the program. The RPM package manager applies the patch when the RPM is built. The patch will be placed into the ~/rpmbuild/SOURCES/ directory together with the tar.gz archive.

Prerequisites

  • Assume that the 1.0 version of the cello program is used.
  • You created a LICENSE file. For instructions, see Creating a LICENSE file.

Procedure

  1. Move all required files into a single directory:

    $ mkdir cello-1.0
    
    $ mv cello.c cello-1.0/
    
    $ mv Makefile cello-1.0/
    
    $ mv LICENSE cello-1.0/
  2. Create the archive for distribution:

    $ tar -cvzf cello-1.0.tar.gz cello-1.0
    cello-1.0/
    cello-1.0/Makefile
    cello-1.0/cello.c
    cello-1.0/LICENSE
  3. Move the created archive to the ~/rpmbuild/SOURCES/ directory, which is the default directory where the rpmbuild command stores the files for building packages:

    $ mv cello-1.0.tar.gz ~/rpmbuild/SOURCES/

Additional resources