Chapter 21

Customizing RPM Behavior

Copyright (c) 2005 by Eric Foster-Johnson. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/).

In This Chapter

*	Defining RPM macros

*	Configuring RPM settings

*	Adding popt aliases

RPM provides a high degree of customization in the form of basic settings, such as where your RPM database is located and the path to common commands like setup or make, to the ability to define new macros and command-line aliases. This chapter covers the three main ways to customize RPM behavior: RPM macros, RPM rc settings, and popt aliases.

Customizing with RPM Macros

Starting with RPM 3.0, RPM macros have replaced most RPM settings from the rpmrc files.

An RPM macro defines a setting to the RPM system. A macro can be defined as a static value, such as the directory where the RPM database is installed. A macro can also be defined in terms of other macros. Furthermore, a macro can be defined with parameters.

For example, the following defines two macros in a macro file:

%_usr /usr

%_usrsrc %{_usr}/src

In this case, the macro %_usr names the /usr directory. The macro %_usrsrc names the /usr/src directory, showing how to set a macro in terms of another macro.

Cross Reference

The macro syntax is used in the query formats introduced in Chapter 5.

Defining macros

RPM provides a number of places you can define macros, including inside spec files (probably the most common usage), in special macro initialization files, and on the command line.

In each case, the syntax is slightly different.

Defining Macros in Spec Files

You can define macros in most places in a spec file. With spec files, use the %define syntax to define a macro, which uses the following syntax:

%define name(options) body

The options are optional and can include the special values defined in Table 21-1.

Table 21-1 Special options for macros

Option	Holds
%0	The name of the macro
%1	The first argument, after processing with getopt
%2-%9	Additional arguments
%*	All arguments, except for flags that have been processed
%#	Number of arguments

These options are similar to those for shell scripting.

Cross Reference

Chapter 10 covers spec files.

In addition to these options, you can use a syntax of %{-a} to hold –a if an option of –a was passed. The syntax of %{-a*} indicates the value passed after the –a option.

You can assign a macro to the value returned by a shell command by using syntax like the following:

%(shell_command)

Note

This is similar to the $(shell_command) syntax supported by bash.

Defining Macros in Macro Initialization Files

Inside a macro file, define macros with the following syntax:

%macro_name value

Macros defined for the RPM system start with an underscore. Some older macros are left without the leading underscore.

Note

The macros defined with an underscore are not exported into rpm headers.

The %expand built-in macro will expand the value of something else, including executing a shell command. For example, the following sets the user’s home directory to the %home macro:

%home %{expand:%%(cd; pwd)}

Note that it is probably easier to simply set the %home macro in your per-user $HOME/.rpmmacros file to the name of your home directory rather than try to figure this out programmatically.

Defining Macros on the Command Line

The rpm command also lets you define macros with the --define option. The basic syntax is:

$ rpm --define 'macro_name value'

Note

Do not place the leading percent sign, %, on the macro you define with --define.

You can evaluate a macro or a macro expression with --eval. For example:

$ rpm --eval %_usrsrc

/usr/src

Customizing Macros

You can add your own macro definitions, using the syntax shown in the “Defining Macros in Macro Initialization Files” section. These macros are read on each invocation of the rpm or rpmbuild commands.

To add your custom macros, you must edit one of the macro definition files. Table 21-2 lists the macro definition files and their usage.

Table 21-2 RPM macro files

File	Usage
/usr/lib/rpm/macros	Official RPM macros
/etc/rpm/macros	Per-system customizations
$HOME/.rpmmacros	Per-user customizations

Note

Do not edit the /usr/lib/rpm/macros file, as this file gets overwritten when you upgrade to a new version of rpm.

Configuring RPM Settings

RPM includes hundreds of settings based on your current system architecture, environment, and which version of the RPM system you have installed. The old settings, called rc or rpmrc settings, are gradually being phased out by the newer, more consistent and more powerful macros.

You can still edit the rc settings, but in most cases you should edit macros instead.

Viewing the current settings

To view the current settings, use the --showrc command-line option:

$ rpm –showrc

ARCHITECTURE AND OS:

build arch : i386

compatible build archs: i686 i586 i486 i386 noarch

build os : Linux

compatible build os's : Linux

install arch : i686

install os : Linux

compatible archs : i686 i586 i486 i386 noarch

compatible os's : Linux

RPMRC VALUES:

macrofiles : /usr/lib/rpm/macros:/usr/lib/rpm/i686-linux/macros:/etc/

rpm/macros.specspo:/etc/rpm/macros.db1:/etc/rpm/macros.cdb:/etc/rpm/macros:/etc/

rpm/i686-linux/macros:~/.rpmmacros

optflags : -O2 -march=i686

This command displays the architecture and operating system information first, and then lists all the rpmrc values, shown here truncated for space.

Locating the rpmrc files

The --showrc option reads in all the rpmrc files from the various locations. By default, this is /usr/lib/rpm/rpmrc, /etc/rpm/rpmrc, and a file named .rpmrc (with a leading period) in your home directory.

These files are read in the order given, so that the later files can override settings in the earlier files.

The uses for these files are listed in Table 21-3.

Table 21-3 Uses for the rpmrc files

File	Holds
/usr/lib/rpm/rpmrc	RPM standard settings
/etc/rpm/rpmrc	Per-system configuration
$HOME/.rpmrc	Per-user configuration

Note

The file /usr/lib/rpm/rpmrc gets overwritten each time you upgrade RPM. Do not customize this file.

You can override this list of files by calling the rpm or rpmbuild commands with the --rcfile option. This option expects a semicolon@nddelimited list of files to read in, in order. For example, if you are working on a 686-architecture Intel platform, you can create a file with the following setting:

optflags: i686 -g

Note that this disables optimization, so it is not a good setting. (The use of this value will make the result more visible.)

If you name this file .rpmnew and place it in your home directory, you can configure an alternate set of files with the --rcfile option and then evaluate the new optflags setting. For example:

$ rpm --eval "%{optflags}"

-O2 -march=i386 -mcpu=i686

$ rpm --rcfile $HOME/.rpmnew --eval "%{optflags}"

-g

This example shows the value before and after changing the configuration files.

When you use the --rcfile option, only the first file listed must exist. The rest of the files are optional. When you use the --rcfile option, however, the file /usr/lib/rpm/rpmrc is read first, and then the list of files you provide with the --rcfile option. The file /usr/lib/rpm/rpmrc is always used.

Changing settings

You can edit the per-user or per-system rc files to change the settings. The format of the rpmrc files is fairly simple but contains a few exceptions. The most basic format is:

setting: value

The settings get more complicated as the rpmrc syntax supports defining settings for multiple architectures at once. In that case, the typical format is:

setting: uname: value

The uname portion is replaced by a value that comes from the uname(2) system call, for example, i686 on a 686-class Intel architecture machine.

Note

In most cases, your best bet is to copy an existing setting and modify it, rather than remembering all the exceptions.

Setting the optflags

One exception to the rule is the optflags setting, which controls C compiler options for optimization. The format for the optflags setting is:

setting: arch value

There is no colon after the architecture. For example:

optflags: i686 -O2 -march=i686

optflags: alphaev5 -O2 -mieee -mcpu=ev5

This example sets the optimization flags for an i686 system to -O2 -march=i686 and an alphaev5 system to -O2 -mieee -mcpu=ev5. If your system is running on a 686-class processor, you will get one set of optimization flags. If your system is running on a V5 Alpha processor, you will get a different set.

Setting the Architecture Values

The arch_canon setting builds up a table of mappings between architecture names and the numbers used internally. The following example shows the Intel and SPARC architecture settings to 1 and 3 internally.

arch_canon: athlon: athlon 1

arch_canon: i686: i686 1

arch_canon: i586: i586 1

arch_canon: i486: i486 1

arch_canon: i386: i386 1

arch_canon: sparc: sparc 3

arch_canon: sun4: sparc 3

arch_canon: sun4m: sparc 3

arch_canon: sun4c: sparc 3

arch_canon: sun4d: sparc 3

arch_canon: sparcv9: sparcv9 3

The arch_compat setting builds a table of compatible architectures. The format is:

arch_compat: arch: compatible_with

This sets the given architecture arch as being compatible with another architecture.

For example:

arch_compat: athlon: i686

This setting indicates that an athlon architecture is compatible with an i686. The table gets built up further with the following Intel-architecture compatibilities:

arch_compat: i686: i586

arch_compat: i586: i486

arch_compat: i486: i386

arch_compat: i386: noarch

The os_canon setting defines a table of operating system labels and internal numeric values. The basic syntax is:

os_canon: arch: name value

The arch comes from the uname(2) call. The name provides an RPM name for that operating system, and the value defines an internal numeric ID for that OS, for example:

os_canon: Linux: Linux 1

os_canon: HP-UX: hpux10 6

The buildarchtranslate setting defines the operating system settings to use as the build architecture. This value translates information from the uname(2) call to a value used by the arch_canon setting. For example:

buildarchtranslate: athlon: i386

buildarchtranslate: i686: i386

buildarchtranslate: i586: i386

buildarchtranslate: i486: i386

buildarchtranslate: i386: i386

buildarchtranslate: sun4c: sparc

buildarchtranslate: sun4d: sparc

buildarchtranslate: sun4m: sparc

buildarchtranslate: sparcv9: sparc

buildarchtranslate: sun4u: sparc64

Adding Popt Aliases

Popt provides a powerful library and RPM subsystem for handling the very complex RPM command-line options. You can customize your RPM usage by defining popt aliases for complex command-line arguments to the rpm or rpmbuild commands. A popt alias is a command-line option that expands to other command-line options.

This technique is used internally to define quite a few command-line options to the rpm and rpmbuild commands in terms of other, more complex options. Many of these aliases define simple command-line options in place of more complex query format options.

Cross Reference

Chapter 5 covers the query format.

For example, the following entry defines the --requires and –R command-line options to the rpm command:

rpm alias --requires --qf \

"[%{REQUIRENAME} %{REQUIREFLAGS:depflags} %{REQUIREVERSION}\n]" \

--POPTdesc=$"list capabilities required by package(s)"

rpm alias -R --requires

These options are set in the file /usr/lib/rpm/rpmpopt-4.1.

Note

This is specific to RPM 4.1. Other releases of RPM use the same naming format but with the current RPM version number, such as 4.2 and so on.

Defining aliases

Defining aliases is pretty easy. The basic syntax is:

command_name alias option expansion

To create an alias for the rpm command, you use rpm for the command_name.

Note

The command_name must be the name passed to the C poptGetContext function, covered in Chapter 16.

Follow this with alias and then the option. You will need separate aliases for the long and short options. The expansion defines the alias in terms of other already-defined command-line parameters.

You can define some complex aliases, such as the following one to display information about a package:

rpm alias --info --qf 'Name : %-27{NAME} Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocateable)}|\n\

Version : %-27{VERSION} Vendor: %{VENDOR}\n\

Release : %-27{RELEASE} Build Date: %{BUILDTIME:date}\n\

Install date: %|INSTALLTIME?{%-27{INSTALLTIME:date}}:{(not installed) }| Build Host: %{BUILDHOST}\n\

Group : %-27{GROUP} Source RPM: %{SOURCERPM}\n\

Size : %-27{SIZE}%|LICENSE?{ License: %{LICENSE}}|\n\

Signature : %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|\n\

%|PACKAGER?{Packager : %{PACKAGER}\n}|\

%|URL?{URL : %{URL}\n}|\

Summary : %{SUMMARY}\n\

Description :\n%{DESCRIPTION}\n' \

--POPTdesc=$"list descriptive information from package(s)"

Popt aliases get evaluated into Linux commands, so you can use pipes and other aspects of Linux shells in your aliases.

Cross Reference

Look closely at the examples in the /usr/lib/rpm/rpmpopt-4.1 file. This is the most complete set of popt alias examples for RPM commands.

You can also define aliases that can set RPM macros, such as the following alias for setting the path to the RPM database:

rpm alias --dbpath --define '_dbpath !#:+'

In this example, !#:+ was defined to behave like a shell history-editing command. With popt, this means to grab the next command-line parameter and place it into the command defined for the alias.

To support the --help and --usage options, you can define the --POPTdesc and --POPTargs options to the alias as shown in the previous examples. These options also support internationalization.

All together, the popt alias setting is very close to the popt option table entries used with the C programming API.

Cross Reference

Chapter 16 shows how to program with the popt library.

Customizing popt aliases

Like RPM macros and settings, popt aliases are defined in a cascading set of files. The official RPM aliases are defined in /usr/lib/rpm/rpmpopt-4.1 for rpm 4.1.

Note

Do not modify this file! The RPM system depends on this file for proper functioning. Incorrect changes might disable many options to the rpm command.

Store per-system popt aliases in /etc/popt. Store per-user aliases in $HOME/.popt (with a leading period).

Note

These files are shared by all applications that use popt.

For example, you can define an alias for rpm -qa that executes faster than the normal query all packages command, by turning off the tests for digest signature verification. To do so, add the following line to a file named .popt in your home directory:

rpm alias --qall -qa --nodigest --nosignature

Once you set up this alias, you can run the following command in place of rpm -qa:

$ rpm --qall

This should execute about one-third to one-half faster than the normal rpm -qa command.

Warning

Turning off the signature and digest tests means you are ignoring important information that pertains to the integrity of your system. That is why the alias shown here does not override the normal -qa option, and instead defines a new --qall option

Summary

This chapter shows the many ways you can customize RPM usage for your system or your own personal environment. You can define RPM macros, which is the preferred way to make RPM settings. Or you can set RPM values in the older rpmrc files, which are now mostly replaced by RPM macros.

Using popt, the powerful command-line option parser, you can define aliases to add simple options that popt expands into whatever you define. Many of the rpm command-line options are defined this way.

Chapter 21

Chris Ricker

2003-01-25T10:30:00

Eric Foster-Johnson