table of contents
| RPM-MACROS(7) | Miscellaneous Information Manual | RPM-MACROS(7) |
NAME¶
rpm-macros - RPM macro processor
SYNOPSIS¶
Defining¶
%NAME BODY
%NAME([OPTIONS]) BODY
Expanding¶
%NAME
%NAME [OPTIONS] [ARGUMENTS]
%{NAME}
%{NAME [OPTIONS] ARGUMENTS}
%{NAME:ARGUMENT}
%{?NAME}
%{?NAME:VALUE-IF-DEFINED}
%{!?NAME:VALUE-IF-NOT-DEFINED}
%(SHELL-COMMAND)
%[EXPRESSION]
%[EXPRESSION ? VALUE-IF-TRUE : VALUE-IF-FALSE]
%{lua:LUA-CODE}
DESCRIPTION¶
RPM has a powerful built-in macro processor. The primary uses of macros are configuration and other utility functions for RPM itself, and as a packaging aid in spec files.
In addition to simple text substitution, the macro processor supports the following facilities:
- function-like PARAMETRIC MACROS with options and arguments processing and locally scoped automatic and user-defined macros
- Shell expansion
- Expression expansion
- Lua expansion for embedded Lua processing
- various BUILT-IN MACROS for string processing and OS interaction
The syntax for defining simple macros is:
All whitespace surrounding BODY is removed. NAME may be composed of alphanumeric characters and the underscore (_), and must be at least two characters in length. The body is (re-)expanded on each macro invocation. Macro names and options are case-sensitive.
See PARAMETRIC MACROS for the more advanced macro variant with options and arguments processing.
Macros can be defined via rpm-macrofile(5) files, and fully managed with macro primitives %define, %global and %undefine, RPM command-line described in rpm-common(8) and the API (C, Python, Lua).
Except for those defined inside parametric macros, macros are always global in scope.
RPM macros are stacked, ie. when redefining an already existing macro, it shadows the previous definition instead of replacing it, and undefining a macro only pops the topmost definition, thus activating the previous macro definition.
Note that this manual only describes the macro processor engine itself. On a normal RPM based system, there are a vast number of other macros defined through rpm-macrofile(5) files that will not be covered here.
EXPANSION¶
To expand a macro, place % in front of it. Several forms are supported:
%NAME
%{NAME}
%NAME [OPTIONS] [ARGUMENTS]
-- can be used to separate options from arguments.
%{NAME [OPTIONS] [ARGUMENTS]}
%{NAME:ARGUMENT}
Note: The syntaxes for calling parametric and built-in macros are generally interchangeable now, but prior to 4.18, the %{NAME:ARGUMENT} syntax was exclusive to built-in macros.
Macro expansion can be escaped by placing a second % in front of the macro, for example %%{name} would be expanded to %{name}.
Attempting to expand an undefined macro expands to the literal invocation, e.g. %_undefined expands to %_undefined. If this is not desired, use conditionals.
Macro expansions can recurse up to 64 levels.
Shell expansion¶
Shell expansion can be performed using %(shell command). shell_command is expanded before executing it with /bin/sh, whose output becomes the expansion of the macro. The trailing newline is deleted.
Example:
%(echo aa-bb-cc | tr '-' '.')
Conditional expansion¶
The macro processor supports testing whether a macro is defined or not.
%{?NAME:VALUE}
%{!?NAME:VALUE}
%{?NAME}
For more complex tests, use Expression expansion or Lua expansion. Note that %if, %ifarch and the like are not macros, they are spec directives and only usable in that context.
Note that in RPM >= 4.17, conditionals on built-in macros simply test for existence of that built-in, just like with any other macros. In older versions, the behavior of conditionals on built-ins is undefined.
Expression expansion¶
Expression expansion can be performed using %[EXPRESSION]. An expression consists of terms that can be combined using operators.
RPM supports three kinds of terms:
- numbers made up from digits
- strings enclosed in double quotes (e.g "somestring")
- versions enclosed in double quotes preceded by v (e.g v"3:1.2-1")
RPM will expand macros when evaluating terms.
You can use the standard operators to combine terms:
- logical operators &&, ||, !
- relational operators !=, ==, <, >, <=, >=
- arithmetic operators +, -, /, *,
- the ternary operator ? :
- parentheses
For example, %[ 3 + 4 * (1 + %two) ] will expand to 15 if %two expands to 2. Version terms are compared using RPM version ([epoch:]version[-release]) comparison algorithm, rather than regular string comparison.
Note that the %[EXPRESSION] expansion is different to the %{expr:EXPRESSION} macro. With the latter, the macros in the expression are expanded first and then the expression is evaluated (without re-expanding the terms). Thus
rpm --define 'foo 1 + 2' --eval '%{expr:%foo}'
will print 3. Using %[%foo] instead will result in the error that "1 + 2" is not a number.
Doing the macro expansion when evaluating the terms has two advantages. First, it allows RPM to do correct short-circuit processing when evaluating logical operators. Second, the expansion result does not influence the expression parsing, e.g. %["%file"] will even work if the %file macro expands to a string that contains a double quote.
Added: 4.16.0
Lua expansion¶
The most powerful of the macro expansion methods is using RPM's embedded Lua interpreter:
%{lua:LUA-CODE}
See rpm-lua(7) for the details.
PARAMETRIC MACROS¶
Parametric macros are a powerful mechanism that allows building function-like utility macros with option processing and accepting a variable number of arguments, much like common shell tools.
The syntax for defining parametric macros is:
If present, the OPTIONS (i.e. the string between parentheses) are passed exactly as is to getopt(3) for argc/argv processing at the beginning of a macro invocation. Only short options are supported.
- as the sole OPTIONS field disables RPM's option processing. This allows macros to fully decide how to handle their input, e.g. if the arguments of the macro only/mostly consist of items starting with -, the default processing only gets in the way.
Automatic macros¶
While a parameterized macro is being expanded, the following shell-like automatic macros are available:
| Macro | Description |
| %0 | the name of the macro being invoked |
| %* | all arguments (unlike shell, not including any processed flags) |
| %** | all arguments (including any processed flags) |
| %# | the number of arguments |
| %{-f} | if present at invocation, the last occurence of flag f (flag and argument) |
| %{-f*} | if present at invocation, the argument to the last occurence of flag f |
| %1, %2, ... | the arguments themselves (after getopt(3) processing) |
If the built-in option processing was disabled with - as the OPTIONS field, only the following automatic macros are available:
| Macro | Description |
| %0 | the name of the macro being invoked |
| %*, %** | all arguments |
| %# | the number of arguments |
| %1, %2, ... | the arguments themselves |
Automatic macros are automatically defined and undefined on parametric macro entry and exit.
Accessing options¶
Within the body of a parametric macro, there are several constructs that permit testing for the presence of optional parameters. The simplest construct is %{-f} which expands (literally) to -f if -f was mentioned when the macro was invoked. There are also provisions for including text if a flag was present using %{-f:X}. This macro expands to (the expansion of) X if the flag was present. The negative form, %{!-f:Y}, expanding to (the expansion of) Y if -f was not present, is also supported.
Scope and visibility¶
In general, macros have a global scope, regardless of where and how they were defined. However, macros defined inside parametric macros have non-global scope as follows:
- automatic macros have local scope, ie. are only visible on the call-level of the macro itself
- user-defined local macros have nested scope, ie. are visible on the call-level of the macro itself and deeper
That is, a parametric macro cannot see the options or arguments of another one, but a user-defined local macro in a calling macro can be accessed in the callee(s).
To define a global macro inside a parametric macro, you must use %global instead of %define. Also note that because such a macro may be referring to other macros only visible in the current scope, %global expands the macro body once at the time of definition.
Calling convention¶
When a parametric macro is expanded, the following calling convention is used:
- 1.
- any arguments to the macro are expanded on the call-level of the callee
- 2.
- any options to the macro are processed
- 3.
- automatic macros are set up for the options and the arguments
- 4.
- the macro body is recursively expanded
- 5.
- all macros defined on this call-level are discarded
BUILT-IN MACROS¶
RPM supports the following built-in macros for various operations. Built-in macros cannot be undefined or overridden.
Note: The %{name:arg} style is used here as it's the most backwards compatible and does not require quoting for whitespace, but it can generally be replaced with the other expansion forms too. Built-ins taking multiple arguments must use other styles, as indicated below.
Macro manipulation¶
The macro primitives are used for macro manipulation in spec files and other macros. Note that all these operate on the macro name without the preceding %-character.
%define NAME[([OPTIONS])] BODY
Example:
%define mypath /usr/bin/mine
%global NAME[([OPTIONS])] BODY
The second difference is that the BODY is expanded once at the time of definition and the expansion becomes the actual macro body. Thus, arbitrary code execution and side-effects may occur when %global is used, depending on the contents and the other macros used in BODY. The latter can be handy for avoiding redundant, possibly expensive macro expansions if the value does not change, but be aware of the side-effects.
Note that while %global technically accepts an OPTIONS field, it is ill-suited for defining parametric macros because of the BODY expansion behavior.
Example:
%global snapver 0-0.48.20240616git
%undefine NAME
Example:
%undefine mypath
%{load:FILE}
Macro expansion¶
%{expand:BODY}
Example:
%{expand:%{foo_prefix}%{foo_suffix}}
%{expr:EXPRESSION}
Example:
%{expr:5*1024}
%{lua:LUA-CODE}
Example:
%{lua:for i=65,90 do print(string.char(i)) end}
%{macrobody:NAME}
Example:
%{macrobody:_libdir}
String operations¶
%dnl
Example:
%dnl This is a comment on %{mymacro} behavior
%{gsub STRING, PATTERN, REPL [,N]}
Added: 4.19.0
Example:
%{gsub aabbaacc aa dd 1}
%{len:STRING}
Example:
%{len:9bf7da058a7c582878310e75be3d56a5a8b67f95}
%{lower:STRING}
Example:
%{lower:CamelCase}'
%{quote:STRING}
Example:
%myzip -x %{quote:empty spaces.zip}
%{rep STRING, N [,SEP]}
Added: 4.19.0
Example:
%{rep a 5}
%{reverse:STRING}
Example:
%{reverse:tac}
%{shescape:STRING}
Example:
%{shescape:foo's}
%{shrink:STRING}
Example:
%{shrink:aa bb ccc }
%{span:STRING}
Example:
%{span:
%one thing
%another thing
}
%{sub STRING, I, [,J]}
Added: 4.19.0
Example:
*%{sub myfile.zip 3 6}*
%{upper:STRING}
Example:
%{upper:CamelCase}'
File and path operations¶
%{basename:PATH}
%{dirname:PATH}
%{exists:PATH}
Example:
%{exists:%{builddir}/myflag.txt}
%{suffix:PATH}
Example:
%{suffix:myfile.zip}
%{url2path:URL}
Example:
%{uncompress:PATH}
Example:
%{uncompress /my/source.tar.gz}
%{xdg:KIND}
- cache: user-specific non-essential (cached) data
- config: user-specific configuration files
- data: user-specific data files
- state: user-specific state data
Added: 6.0.0
Example:
%{xdg config}
Environment info¶
%getncpus
%{getncpus:KIND}
- total: total number of available CPUs (same as %getncpus)
- proc: number of available CPUs for processes
- thread: number of available CPUs for threads
proc and thread account for available memory, including address space limitations for threads.
Added: 4.19.0.
Example:
%{getncpus proc}
%getconfdir
%{getenv:NAME}
%rpmversion
Output¶
%{echo:STRING}
Example:
%{echo:Building with foo}
%{warn:STRING}
Example:
%{warning:Foo is deprecated}
%{error:STRING}
Example:
%{error:Invalid argument}
%verbose
%{verbose:STRING}
Example:
%{verbose:-x}
Spec specific macros¶
%{S:NUMBER}
%{P:NUMBER}
Diagnostics¶
%trace
%dump
%__file_name
%__file_lineno
EXAMPLES¶
Example 1. Define a simple macro¶
Define macro mylib to a path relative to %{_libdir} macro in a spec:
%define mylib %{_libdir}/mine
Example 2. Define a parametric macro¶
Define parametric macro myhelper which executes the program specified by %myprog with it's first argument and always passing the option --some-opt to it, and additionally the --xtra option if it received the -x option itself:
%define myhelper(x) %{myprog} --some-opt %{?-x:--xtra} %{1}
Example 3. Define a macro utilizing shell expansion¶
Define macro %today that expands to the current date in YYMMDD format by calling the date(1) shell utility. Note the 2nd % needed to escape the arguments to date(1):
%define today %(date +%%y%%m%%d)
Example 4. Define a macro conditionally¶
Define macro mypath if it wasn't previously defined:
%{!?mypath: %define mypath /some/where}
Example 5. Conditional expansion¶
Expands to 1 if use_foo is defined and 0 otherwise:
%{?use_foo:1}%{!?use_foo:0}
Example 6. Expressions¶
Calculate 5 * 1024:
%[5 * 1024]
Expand to literal true or false depending on a condition:
%[1 < 2 ? "true" : "false"]
Compare versions, expanding to 1 or 0 on true/false:
%[ v"3.1.0-1" < v"1.0~alpha-2" ? 1 : 0]
Expands to 1 if %aa expands to 5, otherwise expands to 2:
%[ "%{aa}" == "5" ? 1 : 2]
DEBUGGING¶
Some useful tools for working with and troubleshooting macros:
rpm --eval "VALUE"
rpm --define "aa 11" --eval "%aa"
rpm --eval "%global unamer %(uname -r)" --eval "%{macrobody:unamer}"
rpm --eval "%define unamer %(uname -r)" --eval "%{macrobody:unamer}"
rpmlua
rpmlua -e 'print(macros.defined("_libdir"))'
rpmspec --shell
rpmspec --shell telnet.spec
SEE ALSO¶
rpm(8) rpm-common(8) rpm-macrofile(5) rpm-config(5) rpm-lua(7) rpmspec(1) rpmlua(1)
| 2025-11-07 | RPM 6.0.0 |