Building open source RPM packages on IBM AIX


RPM is a program for installing and managing software packages on a system. It is commonly used by several Linux® distributions. It provides a simpler way to manage software compared to manual installation of files. The rpm command is also used as a build tool to create other RPM packages. By building an RPM package, you can automate the creation of an installable RPM package instead of manually performing the build process steps on the command line.

Building an RPM package on IBM® AIX® is exactly the same as on any Linux distribution which uses RPM as a package manager. The only notable difference is the installed directory structure.

RPM is a different installation format than the native AIX installp file sets. All the native AIX product file sets are provided in the installp format. By using RPM for miscellaneous open source packages that install on AIX (but are not part of AIX itself), the software can be managed separately. It also provides an installation method more familiar to Linux users.

Manual build and installation

Without using RPM, the manual build and installation of an open source software package can often be done in three steps (commands). Not every open source package uses these same steps, but this is by far the most common approach. Let’s look briefly at each of these steps:

  1. Configuring the software based on system settings (./configure):
    The configure script gets the software ready based on performing queries about the characteristics of your system. It will typically look for dependencies and system features, and it will generate a makefile and configuration header files appropriate for your system. These files might have content that slightly differs from one system to another, but the important point is that this configuration step takes care of these files for you.
    This command also typically identifies whether the C compiler available on your system (if needed, for C language source) is a compiler like gcc or a native compiler like AIX xlc, and identifies any compile options it deems necessary.
  2. Building the software (make):
    The make command is used to build the software. This command executes the instructions in a makefile to build the program from the downloaded source code. The makefile is normally generated in step 1, in which the configure process will use a template called provided by the software. This allows the makefile to be adapted to your system. During this step, the actual execution of the compiler against all necessary source takes place, resulting in binaries that should run. This varies of course, depending on the software. For example, packages that are scripting language extensions might not require compilation.
  3. Installing the software (make install):
    This command copies the built program, and its libraries and documentation to their final locations on the file system from where they are meant to be run or accessed. The installation step is defined in the makefile, so the location where the software is installed can change based on the options passed to the configure script.

The RPM build directory structure on AIX

On AIX, for a root user, the default RPM build directory structure is under /opt/freeware/src/packages.

Figure 1. AIX RPM build directory structure

For a non-root user, the directory structure is defined by the ~/.rpmmacros configuration file in /home/. Notice the reference to spec files here. The spec file is the key file with all necessary information for the rpmbuild command to build a software RPM package. Refer to the following sections for more details.

Note: In RPM version 4, the command to build an RPM package is rpmbuild and in RPM version 3, it is rpm. You can verify the RPM version on your system by running the rpm --version command. It is recommended to always use the latest RPM version. In this article, we are using RPM 4, and therefore, using the rpmbuild command to build the RPM packages.

Common packages for a build environment

Following are some of the generic packages that are commonly needed on AIX to build open source software. Not every package here is needed by every software project you want to build, but it is a good start to cover most common build requirements. You can download these packages from IBM’s AIX Toolbox web download sitefor Linux Applications.

autoconf findutils less textinfo
automake gcc libgcc unzip
bash gcc-c m4 wget
bison gcc-cpp make
coreutils gdbm patch
db gdbm-devel pkg-config
db-devel gettext readline
dejagnu gettext-devel readline-devel
diffutils grep rsync
expat info sed
expat-devel intltool tar

For building an RPM package, the most important requirement is the RPM utility itself. You should find RPM already available on your AIX system, provided in an installed file set called rpm.rte. You can check this and find the version using the # lslpp –l rpm.rte command.

It is strongly recommended that you ensure the most updated version of RPM is installed on your system. You especially want to update if you are still running some level of RPM version 3.0.5, which is quite old. Find the latest version in the following directory and install it before proceeding further:

It is also strongly recommended that you install yum for AIX. This will help you manage your RPM dependency installations from the AIX Toolbox site and simplifies installing updates and dependencies. Please download and run script from following location to install yum on AIX.

Procedure to build an RPM on AIX

First, of course, you need to locate and download the source itself into your AIX system. You might be able to find an SRPM (“source rpm”) of the package, which would be the most convenient case. This would be a file with a name like packagename-version.src.rpm. If you do not find an SRPM, however, you might likely find a compressed image (a .tar file) of the source. This may be something like filename-version.tar.gz if compressed with gzip. You might also find it with a .bz2 extention, or .Z, or possibly not compressed at all. It’s not really important, as long as you find the image of the source you want to build and copy it to your local system.

  1. Using SRPM (source RPM)

    There are two approaches to build an RPM from an SRPM.

    1. In the first approach, RPM is built using an SRPM without modifying the source. This is the most basic way of building an RPM.  
       Copy the **_<package-name>.src.rpm_** file into the SRPMS directory of the directory structure (shown in Figure 1). Then change to the SRPMS directory (using the `cd` command) and run the `rpmbuild –-rebuild <package-name.src.rpm>` command to build the RPM. If all goes smoothly, your result will be a finished RPM image in either the RPMS/ppc directory or the RPMS/noarch directory.
    1. In the second approach RPM is built after installing SRPM and then building it from the spec file. This is slightly more complex than the first approach, but the advantage is that you can modify the spec file and source code and add patches as per your needs.  
       Place the source RPM in the SRPMS directory and then install it using the following command:`rpm –i <package-name.src.rpm >`  
       You can also use the `rpm -qpl <package-name.src.rpm>` command to list the files in the source RPM file of the package, without actually installing it.  
       When you install an SRPM package, the spec file gets copied to the SPECS directory (see directory structure shown in Figure 1). Change to the SPECS directory and run the `rpmbuild -ba < package-name.spec>` command to build the software. This command generates the binary RPM package in the appropriate directory and also creates a new SRPM file.
  2. Using a spec file

    Following are the detailed steps for building the RPM package using a spec file that does not have an SRPM package.

    1. Download the source code of the package.
    1. Create a patch of any changes needed in the source code.
    1. Place the source code and patches in the **SOURCE** directory.
    1. Create a spec file for the package and place it in **SPECS** directory. If you do not have a spec file of the package, it might be easier to copy one from another package and edit each of the fields as needed for the new package.
    1. Run the `rpmbuild -ba <spec-file-name>` command to build the RPM from the **SPECS** directory.
    1. On successful completion of the build, notice that the RPM is generated in the **RPMS** directory and source RPM is generated in the **SRPMS** directory.

Note: If you need to make any changes in the source code, you can do it only through patches.

The spec file

The spec file has the specifications and instructions to build the package. The spec file contains the following fields:

  • Header
  • %prep
  • %build
  • %install
  • %clean
  • Some optional scripts:
    • pre
    • post
    • preun
    • postun
  • %file
  • %changelog

Let’s have a look at each of these fields separately. It might be easy to understand if you follow along with an existing spec file. You can find an example in the spec file example – the zip utility section of this article.

A standard header section must include the following fields:

  • Summary: A small description about the package and its usage.
  • Name: The name string from the RPM file name you plan to use.
  • Version: The version string from the RPM file name you plan to use.
  • Release: The release number for the package of the same version. This number is typically incremented each time you repackage the same version when you are just adding a fix.
  • Copyright: The copyright and licenses information of the package.
  • Source:
    • This line points to the home location from where you have downloaded the source code.
    • The file name in this line must match with the file name on your system. (You should not change the name of the file after downloading.)
    • If there are multiple sources, they should be specified as:
      Source0: xyz-1.0.0.tar.gz
      Source1: abc-1.0.0.tar.gz
      and so on….
      These files must be placed in the SOURCES directory without changing the name.
  • Patch:
    • This specifies the patches which you have made to make any changes in the source code. When a change is needed, it is best to use a patch instead of editing the original file inside the original source .tar file. This helps to ensure that your changes are tracked separately from the original, and it can help identify whether patches are still needed in the newer versions if you update the package later.
    • The file name in this field must match with the file name on your system.
    • If there are multiple patches, they should be numbered like this:
      Patch0: xyzabc.patch
      Patch1: abcxyz.patch
      These files must be placed in SOURCES directory without renaming it.
  • BuildRoot: This line allows you to specify a directory as the “root” for building and installing the new package.
  • %description: A multiline field that should be used to provide a comprehensive description about the package.


This section explains how the sources are prepared to build the package. Here all the patching and setting up of the sources are done, so that you can build them later.

All the sections in the spec file contain the shell scripts for building the package.

You need to use the following macros to prepare the sources:

  • %setup macro: It just unpacks the sources and places them in the SOURCE directory. Options:
    • -n name: Set the name of the directory to the listed name
    • -c: Creates and change directory to the named directory before extracting the .tar file.
    • -b: Extracts the source before changing into the named directory.
    • -a: Extracts the source after changing into the named directory.
    • -T: Overrides the default action of extracting the source and requires a -b 0 or -a 0 to get the main source file extracted.
    • -D: Does not delete the directory before unpacking. This option is useful if you have more than one setup macro.
  • %patch macro: This macro automates the process of applying patches to the sources. Options:
    • #: Applies the patchnumber as the patch file.
    • -p #: Specifies the number of directories to strip for the GNU patch command.
    • -b extension: Saves originals as filename.extensions before applying the patches.

Anything you include till now is executed using shell command line (sh).


This section explains how to build the software.

  • There are no macros for this section.
  • In this section, you need to enter the commands required to build the software after extracting the source and patching it.
  • This is just another set of commands passed to the shell command line (sh). So, any legal sh commands can go here (including comments).
  • Note that your current working directory is reset in each of these sections to the top level of the source directory. You can change to subdirectories if necessary.
  • The RPM_OPT_FLAGS variable is set using values in /usr/freeware/lib/rpm/rpmrc.
    • Look there to make sure you are using values appropriate for your system or
    • Simply don’t use this variable in your spec file because it is optional.
    • Instead define your compile settings.
  • Some common environment variables that need to be set in this section are as follows:
    • To add a specific location to the PATH environment variable of your system:
      export PATH=/opt/freeware/bin:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:
      Note that /opt/freeware/bin is first in the path. This ensures that the common open source versions of key utilities are found before the AIX native versions. For example, the GNU make has different variations of behavior than the native AIX make, and most open source expects the GNU behavior. Putting your path in this order ensures that the required version is used.
    • To set contain options that are passed through to the linker:
      export LDFLAGS="-L/opt/freeware/lib -Wl,-blibpath:/opt/freeware/lib:/usr/lib:/lib"
    • To set the shell with which to run configure, ksh, bash and so on.
      export CONFIG_SHELL=/usr/bin/ksh
    • To set binary to remove objects such as files, directories and so on:
      export RM="/usr/bin/rm -f"
    • To set commands to maintain the indexed libraries used by the linkage editor, if you need to build both 32-bit and 64-bit libraries:
      export AR="/usr/bin/ar -X32_64"
    • To set commands to examine binary files and to display the contents of those files, or meta information stored in them, specifically the symbol table:
      export NM="/usr/bin/nm -X32_64"

Note: Environment variables regarding the gcc/xlc compiler are provided in detail later in this article.


This section explains how to install the built software at target location.

  • There are no macros for this section.
  • You basically need to enter all the necessary commands here to perform installation.
  • If you have the make install command available to you in the package you are building, include it in this section
  • If not, you can either modify makefile to add the make install command and just include that command here, or you can include shell commands here to perform installation.
  • You can consider your current directory to be at the top level of the source directory.
  • The RPM_BUILD_ROOT variable provides the path set as BuildRoot in the header section of the spec file. The usage of BuildRoot is optional but highly recommended to prevent your system from getting cluttered with software that isn’t in your RPM database.


This section helps in cleaning build root

  • The %clean macro makes sure that the build root is clean at the end of the build.
  • %clean
    [ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT} It is recommended to check if RPM_BUILD_ROOT is not set to root directory before cleaning RPM_BUILD_ROOT.

Pre- and post-installation/uninstallation script

If you need to run any script before and after installation or uninstallation, you can put those scripts under the following macros and it will run as any normal shell script.

  • Macros for each of the scripts are as following:
    • %pre: Macro to run pre-installation scripts.
    • %post: Macro to run post-installation scripts.
    • %preun: Macro to run pre-uninstallation scripts.
    • %postun: Macro to run post-uninstallation scripts.
  • The content of this section should be just like shell scripting. The script should be written so that it returns zero if successful and returns non-zero if there is an error which should abort the installation.


In this section, the files to include in the binary package must be listed.

Macros that we can use in this section are:

  • %doc: Is used to mark documentation in the source package that you want to include in the RPM package.
    The documentation will be installed at the following location:
    You can list multiple documents on the command line with this macro, or
    You can list them all separately using a macro for each of them.
  • %config: Is used to mark configuration files in a package. You can list multiple files with this macro as well.
  • %dir: Marks a single directory in a file list to be included as being owned by a package. If you are not using the %dir macro with a directory name, by default everything in that directory is included in the file list and later installed as part of the package. If you do not include the %dir directory listings, these directories might be left behind on the system if you later uninstall the package.
  • %defattr: Allows you to set default attributes for the files listed after the defattr declaration.
  • %files -f <filename>: Allows you to list your files in some arbitrary file within the build directory of the sources. This is useful if the list is larger than you want to include in the spec file itself.


This provides a log of all the changes that had occurred when the package is updated. If you are modifying an existing RPM, list all the changes in this section.


Start each new entry line with a ‘*’, followed by the date, your name, and email address.

Environment settings for IBM XL C/C++ compiler

Following is the list of environment variables that you need to set in build section before building the package (using the IBM XL C/C++ compiler). Other than $CFLAGS all these environment variables would be same irrespective of different AIX versions.

export CC=cc
export CXX=xlC
                    export CXXFLAGS=$CFLAGS
export F77=xlf 
export FFLAGS="‑qmaxmem=16384 ‑O ‑I/opt/freeware/include" 
export LD=ld export LDFLAGS="‑L/opt/freeware/lib ‑Wl,‑bmaxdata:0x80000000" 

AIX v6.1:

export CFLAGS="‑qmaxmem=16384 ‑DSYSV ‑D_AIX ‑D_AIX32 ‑D_AIX41 ‑D_AIX43 ‑D_AIX51 ‑D_AIX52
‑D_AIX53 ‑D_AIX61 ‑D_ALL_SOURCE ‑DFUNCPROTO=15 ‑O ‑I/opt/freeware/include" 

AIX v7.1:

export CFLAGS="‑qmaxmem=16384 ‑DSYSV ‑D_AIX ‑D_AIX32 ‑D_AIX41 ‑D_AIX43 ‑D_AIX51 ‑D_AIX52
‑D_AIX53 ‑D_AIX61 ‑D_AIX71 ‑D_ALL_SOURCE ‑DFUNCPROTO=15 ‑O ‑I/opt/freeware/include" 

AIX v7.2:

export CFLAGS="‑qmaxmem=16384 ‑DSYSV ‑D_AIX ‑D_AIX32 ‑D_AIX41 ‑D_AIX43 ‑D_AIX51 ‑D_AIX52
‑D_AIX53 ‑D_AIX61 ‑D_AIX71 ‑D_AIX72 ‑D_ALL_SOURCE ‑DFUNCPROTO=15 ‑O ‑I/opt/freeware/include" 

Environment settings for gcc

Same as xlc, the following environment variables would be same irrespective of the AIX versions other than $CFLAGS.

 export CC=gcc
 export CXX=g++
export F77=g77 
export FFLAGS="‑O ‑I/opt/freeware/include" 
export LD=ld export LDFLAGS="‑L/opt/freeware/lib ‑Wl,‑bmaxdata:0x80000000" 

AIX v6.1:

export CFLAGS="‑DSYSV ‑D_AIX ‑D_AIX32 ‑D_AIX41 ‑D_AIX43 ‑D_AIX51 ‑D_AIX52
‑D_AIX53 ‑D_AIX61 ‑D_ALL_SOURCE ‑DFUNCPROTO=15 ‑O ‑ I/opt/freeware/include" 

AIX v7.1:

export CFLAGS="‑DSYSV ‑D_AIX ‑D_AIX32 ‑D_AIX41 ‑D_AIX43 ‑D_AIX51 ‑D_AIX52
                    ‑D_AIX53 ‑D_AIX61 ‑D_AIX71 ‑D_ALL_SOURCE ‑DFUNCPROTO=15 ‑O ‑ I/opt/freeware/include" 

AIX v7.2:

export CFLAGS="‑DSYSV ‑D_AIX ‑D_AIX32 ‑D_AIX41 ‑D_AIX43 ‑D_AIX51 ‑D_AIX52
                    ‑D_AIX53 ‑D_AIX61 ‑D_AIX71 ‑D_AIX72 ‑D_ALL_SOURCE ‑DFUNCPROTO=15 ‑O ‑ I/opt/freeware/include" 

Creating and applying patches

Sometimes, we may need to change the downloaded source code of the package in order to compile it error free or to fix any known issue.

It is improper to change the base source code and build RPM without creating a patch. You should properly create a patch file (one patch per issue) and apply on the source code while building RPMs.

Steps to create patch

  1. Save the original files that you want to change with different name in the same directory. For example, if the file name is xyz.c, you can save it as xyz.coriginal.
    _cp <filename_original> <filename>

    Example: cp xyz.c_original xyz.c
  2. Make changes in the original file, that is, in the file without the “_original” extension. Actually, you can change any of the files but for simplicity and to follow the same method everytime, you can proceed as specified above.
  3. Notice that we have two files:
    xyz.c: Changed file, with fix.
    xyz.c_original: The original file.
  4. Create a patch using the following command:
    diff -u <filename_original> <filename> > <patch_file.patch>
    For example: diff -u xyz.c_original xyz.c > fix.patch
  5. If more than one file is modified, you can use the same diff command as in step 4 for other files as well and concatenate the patch in the same file created above.
    Example: diff -u abc.c_original abc.c >> fix.patch.


  • If the file that needs to be modified is present in a sub-directory, then also run the diff command from the top source directory itself by specifying the relative path name. Otherwise, the patch command may not be able to find the path of the file to patch.
    e.g. diff -u ./sub-dir1/sub-dir2/xyz.c_original ./sub-dir1/sub-dir2/xyz.c > fix.patch
  • It is advisable to use the /opt/freeware/bin/diff binary to create the patch.

Steps to apply patches

You need to perform the following steps to apply patches:

  1. Copy the patch file in the SOURCE directory specified earlier.
  2. Define all the patches at the beginning of the spec file as Patch0, Patch1, Patch2, and so on.
  3. In the spec file, the application for the patch is defined in the %prep section. Add your created patch entry under %prep section:
    %patch1 -p1 -b .xyz

In the above command, patch1, patch2 and so on should be according to how you have defined the patches in step3. The option p1 is for the path to the target file. If you have created a patch file from the main package directory, you should use p1. The -b option is to create a backup of the target file. Before applying the patches, the original file will be saved with the last option as the extension. In this example, the original xyz.c and abc.c files will be saved as and

After saving the backup of the original file, patch will be applied to the target files and then usual RPM build can be proceeded.

Useful RPM command

Command Description
rpm -qa Show all installed RPM packages.
rpm -qpl <rpm-file> List contents of a specific RPM package.
rpm -qpi <rpm-file> Show information about an RPM package.
rpm -qp –requires <rpm-file> Show package requirements of an RPM package.
rpm -qf </path/to/xyz> Identify the RPM package to which the xyz file belong to.
rpm -qp –scripts <rpm-file> Show pre- and post-installation scripts of an RPM package.
rpm -qp –changelog <rpm-file> Show change log history of an RPM package.
rpm -ivh <rpm-file> Install an RPM package.
rpm -Uvh <rpm-file> Update an RPM package.
rpm -e <rpm-file> Remove an RPM package.

spec file example – the zip utility

This is just one example of a spec file, for the zip utility. It is worth examining a few different ones to get an idea of different types of build commands included by different packages. This is an example of a fairly simple package, but (for example) it doesn’t show the application of a patch file. You can find examples of other spec files at the AIX Toolbox server space, in the following directory:

#"zip‑3.0‑2.spec" file starts here
Summary: A file compression and packaging utility compatible with PKZIP
Name:       zip
Version:    3.0
Release:    2
License:    BSD‑like
Group:      Archiving/Compression
#The Prefix macro sets the default location on AIX to /opt/freeware
#This helps avoid interfering with system files under /usr
Prefix:     %{_prefix}
#BuildRequires should list packages that this one needs as build dependency
#If there are runtime dependencies, you would list them in a similar way:
#Requires: package1 package2  (etc; run‑time dependencies)
BuildRequires:  bzip2
BuildRoot:  %{_tmppath}/%{name}‑root
#The description here can be displayed by a user querying the package with
#"rpm –qi zip".  The –q is a query flag; ‑i asks for general information.
The zip program is a compression and file packaging utility. Zip is analogous
to a combination of the UNIX tar and compress commands and is compatible with
PKZIP (a compression and file packaging utility for MS‑DOS systems).
Install the zip package if you need to compress files using the zip program.
This version support crypto encryption.
#The %prep section extracts the source from SOURCES and applies patches
#The %setup command does this for you.  %{name}30 reflects the name of
#the package in the SOURCES directory, where %{name} expands to zip in this #case,
as reflected by the Name indicator near the top of this file.
%setup ‑q ‑n %{name}30
#The %build section is the primary compilation action.  Notice the commands
#are typical shell commands.
#The "default compiler" section here could be eliminated if you are just
#using gcc. (This part is trying to see if you have xlc, but falling back to
#gcc otherwise. You don't need this part if you're just using gcc.)
export PATH="$PATH:/usr/vac/bin"
export RM="/usr/bin/rm ‑f"
#Use the default compiler for this platform ‑ gcc otherwise
if [ ‑z "$CC" ]then
    if test "Xtype %{DEFCC} 2>/dev/null" != 'X'; then
       export CC=%{DEFCC}
       export CC=gcc
export TARGET=generic_gcc
if test "X$CC" != "Xgcc"
       export RPM_OPT_FLAGS=echo $RPM_OPT_FLAGS | sed 's:‑fsigned‑char::'
       export CFLAGS="$RPM_OPT_FLAGS"
       export TARGET=generic
#Everything above is just config. This make command is where the real build #action happens,
using the provided makefile.  This example doesn't include
#the ./configure step, which wasn't necessary for this case.  If it were, it
#would be found in front of the make command.
make ‑f unix/Makefile prefix=%{_prefix} "RPM_OPT_FLAGS=$RPM_OPT_FLAGS" $TARGET
#This section will run only if the build succeeds.  This copies the desired
#files for installation into the RPM_BUILD_ROOT tree, reflecting the top
#directory. The $RPM_BUILD_ROOT%{_prefix}/bin becomes /opt/freeware/bin
mkdir ‑p $RPM_BUILD_ROOT%{_prefix}/bin
mkdir ‑p $RPM_BUILD_ROOT%{_prefix}/man/man1
#This is the main "make install" line.
make ‑f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} \
    mandir=${RPM_BUILD_ROOT}%{prefix}/man \
    infodir=${RPM_BUILD_ROOT}%{prefix}/info \
    #Not mandatory, but if an executable isn't stripped it takes more space.
    #This simply is stripping the binaries since the build didn't do so.
    #(This could have been done at the end of the %build section).
    for n in zipnote zipsplit zip zipcloak ; do
        /usr/bin/strip .%{_prefix}/bin/$n 2>/dev/null || :
        chmod 755 .%{_prefix}/bin/$n
    #Be careful if you do this.  These lines are creating symbolic links in
    #/usr/bin pointing to the files in /opt/freeware/bin.  This helps to
    #find the commands at run time, but is dangerous if you aren't careful
    #because you don't want to overwrite an existing AIX command in /usr/bin
    #if the system already has a command with the same name.
    mkdir ‑p usr/bin
    cd usr/bin
    ln ‑sf ../..%{_prefix}/bin/∗ .
#This just cleans up your build files.  If you are debugging, you might want
#to leave the files behind for examination. Otherwise, leave as is.
#List the files that get installed with the package. Always include the
#license file!  And again, be careful about installing anything in /usr/bin.
#Make sure no existing system files already have these names, or leave these
#out altogether.
#Example changelog entries.  It's good practice to include these. They are
#listed in reverse chronological order (newest at top).
∗ Wed Oct 30 2013 Gerard Visiedo <> 3.0‑2
‑ Build on Aix6.1
∗ Fri Jun 4 2010 Jean Noel Cordenner <ean‑>
‑ Update to version 3.0
∗ Fri Nov 22 2002 David Clissold <>
‑ Add IBM ILA license.
∗ Fri Aug 31 2001 David Clissold <>
‑ Build with _LARGE_FILES
∗ Wed Mar 21 2001 David Clissold <>
‑ Change to allow build with non‑gcc compiler