Product SiteDocumentation Site

Chapter 11. Controlling the Build with rpmbuild

11.1. Building RPMs with the rpmbuild Command
11.1.1. Customizing the build
11.1.2. Testing the build
11.1.3. Debugging the build
11.1.4. Cleaning up
11.1.5. Building for other platforms
11.2. Building RPMs Without an External Spec File
11.2.1. Options for working with tar archives
11.2.2. The expected archive structure
11.3. Working with Source RPMs
11.3.1. Rebuilding binary RPMS from source RPMs
11.3.2. Recompiling binaries from source RPMs
11.3.3. SRPMS? Finding source RPMs
11.4. Signing Built RPMs
11.4.1. Checking that the GPG software is installed
11.4.2. Configuring a signature
11.4.3. Signing with the rpmbuild command
11.4.4. Signing with the rpm command
11.4.5. Verifying signatures
11.4.6. Importing public keys
11.4.7. Getting the Red Hat public key
11.5. Summary
This chapter covers:
The preceding chapters in this Part cover details on how to put together RPMs. This chapter rounds out the discussion by delving into more details on the rpmbuild command.
You can customize how rpmbuild creates RPMs, and you can use RPM commands to test and debug your package.

Building RPMs with the rpmbuild Command

The rpmbuild command provides a workhorse command for building RPMs in all sorts of ways. The basic syntax, as shown in Chapter 8, Creating RPMs: An Overview, is:
rpmbuild -bBuildStage spec_file
The BuildStage is a letter, such as c, to prepare and compile the application, executing through the %build section, or i, to execute through the %install section. This allows you a good deal of flexibility for building the entire RPM or stopping at some point prior to a full build.
There’s more to the rpmbuild command, though. Quite a few additional options allow you to further customize the build.
As mentioned in Chapter 8, Creating RPMs: An Overview , previous versions of the RPM system used the rpm command with a -b, for build, option. This option is no longer supported. Use the rpmbuild command to build RPMs.

Customizing the build

You can customize the rpmbuild command with the options listed in Table 12-1.
Table 12-1 Extra build options for the rpmbuild command
--buildroot directory
Override the default root directory for building with directory, generally not very useful since most packages already name a buildroot
Remove the build tree after building
Just test the spec file and do not run the build
Remove the sources after the build
Remove the spec file after the build
With the -bc or -bi options, jump directly to the given stage and resume the build from that stage
Sign the package with a GPG signature
--target platform
Build for the given platform. May not work if you don't have the other platform build commands, such as cross compilers, set up. Can work for Intel platforms with i386, i686, and so on.

Testing the build

One of the most useful options is --nobuild, which tells the rpmbuild command to not build anything. This may seem silly, but the --nobuild option is very useful for testing whether your RPMs can be built. With the --nobuild option, the rpmbuild command parses the spec file and checks for errors, but does not run any of the build stages.
The --buildroot allows you to specify a different top-level directory for building, overriding the BuildRoot tag in the spec file. This means you can build in a separate location, which is helpful in case there are mistakes. Using a separate directory means the build won’t get mixed with anything else in the build root directory.

Debugging the build

The --short-circuit option tells the rpmbuild command to restart at a particular location in the build. Rather than working its way through all the steps up to the build stage you ask for, the --short-circuit option allows the rpmbuild command to restart just at the step you ask for.
This works with the -bc and -bi options only, as well as the -tc and -ti options covered later in this chapter.
For example, if you run the rpmbuild -bc command to stop after the %build section, you can use the --short-circuit option to restart the build at the %build section. If you found a problem in the %build section and corrected it, you can quickly get going again by restarting the build at the %build section rather than extracting all the sources yet again.
This option is most useful when you are compiling a package, hit an error, and fix that error. Without the --short-circuit option, you’ll likely end up spending a lot of time recompiling the code you have already compiled.
During normal development of an RPM package, you will likely execute each build section, one at a time, stop, fix any errors and restart where you left off. You’ll go through this cycle a number of times before the RPM finally builds right.
Never distribute an RPM made with the --short-circuit option. Instead, once you have everything working, start from scratch and rebuild the RPM. This is to avoid any problems with a partially-created RPM.

Cleaning up

The --clean option tells the rpmbuild command to remove the build tree when complete. This helps ensure that the next time you run the rpmbuild command, you are starting from a known situation.
For example:
$ rpmbuild --clean /usr/src/redhat/SPECS/jikes.spec
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.98247
+ umask 022
+ cd /usr/src/redhat/BUILD
+ rm -rf jikes-1.17
+ exit 0
You can use the --clean option alone, as shown previously, or in concert with another option such as -bi to build and install a binary RPM. In the latter case, the rpmbuild command will clean the built files after the rest of the command finishes.
Similarly, the --rmsource option tells the rpmbuild command to remove the sources after completing the command. You can call this option with another option, such as -bi for building and installing a binary RPM (and then removing the sources), or alone on the command line to remove the sources only.
For example:
rpmbuild --rmsource jikes.spec
The abbreviation rm is short for remove. It comes from the Linux rm command, used for removing files.
The --rmspec option tells the rpmbuild command to remove the spec file when done with the command. As with the --rmsource option, you can use the --rmspec option in conjunction with another rpmbuild option or on its own to just remove the spec file.
For example:
rpmbuild --rmspec jikes.spec
The file you are removing with this command is the spec file you are passing to the command. Be careful, because you cannot undo this operation and you have now lost your spec file, except inside your source package.

Building for other platforms

The --target option tells the rpmbuild command to build a package for another platform. You need to pass the name of the platform. For example:
rpmbuild -bi --target i486-redhat-linux
The basic format is:
For example, i686-redhat-linux specifies a 686 CPU with Red Hat Linux. Other CPUs include ppc for PowerPC and sparc for Sun SPARC.
Cross Reference
The --target option sets the target architecture at build time. Chapter 3, Using RPM covers how you can use the --ignoreos and --ignorearch options when installing RPMs to ignore the operating system and architecture that is flagged within the RPM. Of course, this works only if you are installing on a compatible architecture.
On the surface level, the --target option overrides some of the macros in the spec file, %_target, %_target_arch, and %_target_os. This flags the RPM for the new target platform.
Under the covers, setting the architecture macros is not enough. You really cannot create a PowerPC executable, for example, on an Intel-architecture machine, unless you have a PowerPC cross compiler, a compiler that can make PowerPC executables.
Set the target with care. Make sure you can really build executable programs for that architecture.
If you try to compile a system that uses the GNU configure system to configure the build, your target will likely be ignored. For example, if you try to build the aforementioned jikes package with a target of ppc-ibm-aix, to specify IBM’s UNIX, called AIX, on a PowerPC architecture, you will see the target ignored as the configure system detects that it's running on Linux on an i686 architecture.
For example:
$ rpmbuild -bc --target ppc-ibm-aix /usr/src/redhat/SPECS/jikes.spec
Building target platforms: ppc-ibm-aix
Building for target ppc-ibm-aix
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.94955
+ umask 022
+ cd /usr/src/redhat/BUILD
+ export LANG
+ cd /usr/src/redhat/BUILD
+ rm -rf jikes-1.17
+ /usr/bin/gzip -dc /usr/src/redhat/SOURCES/jikes-1.17.tar.gz
+ tar -xf -
+ '[' 0 -ne 0 ']'
+ cd jikes-1.17
++ /usr/bin/id -u
+ '[' 500 = 0 ']'
++ /usr/bin/id -u
+ '[' 500 = 0 ']'
+ /bin/chmod -Rf a+rX,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.15710
+ umask 022
+ cd /usr/src/redhat/BUILD
+ cd jikes-1.17
+ export LANG
+ ./configure CXXFLAGS=-O3 --prefix=/tmp/jikesrpm/usr
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets ${MAKE}... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for g++... g++
As you can see, the command starts out with the target as the platform, but the configure script soon overrides that, as shown at the end of the truncated output.