.\" Generated by scdoc 1.11.4 .\" Complete documentation for this program is not available as a GNU info page .ie \n(.g .ds Aq \(aq .el .ds Aq ' .nh .ad l .\" Begin generated content: .TH "RPM-MACROS" "7" "2026-01-08" "RPM 6.0.1" .PP .SH NAME rpm-macros - RPM macro processor .PP .SH SYNOPSIS .SS Defining \fB%\fR\fINAME\fR \fIBODY\fR .PP \fB%\fR\fINAME\fR\fB(\fR[\fIOPTIONS\fR]\fB)\fR \fIBODY\fR .PP .SS Expanding \fB%\fR\fINAME\fR .PP \fB%\fR\fINAME\fR [\fIOPTIONS\fR] [\fIARGUMENTS\fR] .PP \fB%{\fR\fINAME\fR\fB}\fR .PP \fB%{\fR\fINAME\fR [\fIOPTIONS\fR] \fIARGUMENTS\fR\fB}\fR .PP \fB%{\fR\fINAME\fR\fB:\fR\fIARGUMENT\fR\fB}\fR .PP \fB%{?\&\fR\fINAME\fR\fB}\fR .PP \fB%{?\&\fR\fINAME\fR\fB:\fR\fIVALUE-IF-DEFINED\fR\fB}\fR .PP \fB%{!\&?\&\fR\fINAME\fR\fB:\fR\fIVALUE-IF-NOT-DEFINED\fR\fB}\fR .PP \fB%(\fR\fISHELL-COMMAND\fR\fB)\fR .PP \fB%[\fR\fIEXPRESSION\fR\fB]\fR .PP \fB%[\fR\fIEXPRESSION\fR \fB?\&\fR \fIVALUE-IF-TRUE\fR \fB:\fR \fIVALUE-IF-FALSE\fR\fB]\fR .PP \fB%{lua:\fR\fILUA-CODE\fR\fB}\fR .PP .SH DESCRIPTION .PP 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.\& .PP In addition to simple text substitution, the macro processor supports the following facilities: .PD 0 .IP \(bu 4 function-like \fBPARAMETRIC MACROS\fR with options and arguments processing and locally scoped automatic and user-defined macros .IP \(bu 4 \fBShell expansion\fR .IP \(bu 4 \fBExpression expansion\fR .IP \(bu 4 \fBLua expansion\fR for embedded Lua processing .IP \(bu 4 various \fBBUILT-IN MACROS\fR for string processing and OS interaction .PD .PP The syntax for defining simple macros is: .PP .RS 4 \fINAME\fR \fIBODY\fR .PP .RE All whitespace surrounding \fIBODY\fR is removed.\& \fINAME\fR may be composed of alphanumeric characters and the underscore (\fB_\fR), 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.\& .PP See \fBPARAMETRIC MACROS\fR for the more advanced macro variant with options and arguments processing.\& .PP Macros can be defined via \fBrpm-macrofile\fR(5) files, and fully managed with macro primitives \fB%define\fR, \fB%global\fR and \fB%undefine\fR, RPM command-line described in \fBrpm-common\fR(8) and the API (C, Python, Lua).\& .PP Except for those defined inside parametric macros, macros are always global in scope.\& .PP 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.\& .PP 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 \fBrpm-macrofile\fR(5) files that will not be covered here.\& .PP .SH EXPANSION To expand a macro, place \fB%\fR in front of it.\& Several forms are supported: .PP \fB%\fR\fINAME\fR .RS 4 Expand the macro \fINAME\fR.\& .PP .RE \fB%{\fR\fINAME\fR\fB}\fR .RS 4 Expand the macro \fINAME\fR, allowing placement adjacent to other text (similar to \fB${ENV}\fR in shell).\& .PP .RE \fB%\fR\fINAME\fR [\fIOPTIONS\fR] [\fIARGUMENTS\fR] .RS 4 Expand the parametric/built-in macro \fINAME\fR, using options and arguments parsed up to the string end or next newline.\& .PP \fB--\fR can be used to separate options from arguments.\& .PP .RE \fB%{\fR\fINAME\fR [\fIOPTIONS\fR] [\fIARGUMENTS\fR]\fB}\fR .RS 4 Expand the parametric/built-in macro \fINAME\fR, using options and arguments parsed up to the closing \fB}\fR.\& Allows usage adjacent to other text.\& .PP .RE \fB%{\fR\fINAME\fR\fB:\fR\fIARGUMENT\fR\fB}\fR .RS 4 Expand the parametric/built-in macro \fINAME\fR, using the string after \fB:\fR as the sole argument.\& Allows usage adjacent to other text.\& .PP .RE Note: The syntaxes for calling parametric and built-in macros are generally interchangeable now, but prior to 4.\&18, the \fB%{\fR\fINAME\fR\fB:\fR\fIARGUMENT\fR\fB}\fR syntax was exclusive to built-in macros.\& .PP Macro expansion can be escaped by placing a second \fB%\fR in front of the macro, for example \fB%%{name}\fR would be expanded to \fB%{name}\fR.\& .PP Attempting to expand an undefined macro expands to the literal invocation, e.\&g.\& \fB%_undefined\fR expands to \fB%_undefined\fR.\& If this is not desired, use conditionals.\& .PP Macro expansions can recurse up to 64 levels.\& .PP .SS Shell expansion Shell expansion can be performed using \fB%(\fR\fIshell command\fR\fB)\fR.\& \fIshell_command\fR is expanded before executing it with \fI/bin/sh\fR, whose output becomes the expansion of the macro.\& The trailing newline is deleted.\& .PP Example: .nf .RS 4 %(echo aa-bb-cc | tr \&'-\&' \&'\&.\&') .fi .RE .PP .SS Conditional expansion The macro processor supports testing whether a macro is defined or not.\& .PP \fB%{?\&\fR\fINAME\fR\fB:\fR\fIVALUE\fR\fB}\fR .RS 4 Expands to the expansion of \fIVALUE\fR if \fINAME\fR is defined, otherwise to an empty string.\& .PP .RE \fB%{!\&?\&\fR\fINAME\fR\fB:\fR\fIVALUE\fR\fB}\fR .RS 4 Expands to the expansion of \fIVALUE\fR if \fINAME\fR is \fInot\fR defined, otherwise it expands to an empty string.\& .PP .RE \fB%{?\&\fR\fINAME\fR\fB}\fR .RS 4 Shorthand for \fB%{?\&\fR\fINAME\fR\fB:%{\fR\fINAME\fR\fB}}\fR.\& .PP .RE For more complex tests, use \fBExpression expansion\fR or \fBLua expansion\fR.\& Note that \fB%if\fR, \fB%ifarch\fR and the like are not macros, they are spec directives and only usable in that context.\& .PP 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.\& .PP .SS Expression expansion Expression expansion can be performed using \fB%[\fR\fIEXPRESSION\fR\fB]\fR.\& An expression consists of terms that can be combined using operators.\& .PP RPM supports three kinds of terms: .PD 0 .IP \(bu 4 numbers made up from digits .IP \(bu 4 strings enclosed in double quotes (e.\&g \fB"somestring"\fR) .IP \(bu 4 versions enclosed in double quotes preceded by \fBv\fR (e.\&g \fBv"3:1.\&2-1"\fR) .PD .PP RPM will expand macros when evaluating terms.\& .PP You can use the standard operators to combine terms: .PD 0 .IP \(bu 4 logical operators \fB&&\fR, \fB||\fR, \fB!\&\fR .IP \(bu 4 relational operators \fB!\&=\fR, \fB==\fR, \fB<\fR, \fB>\fR, \fB<=\fR, \fB>=\fR .IP \(bu 4 arithmetic operators \fB+\fR, \fB-\fR, \fB/\fR, \fB*\fR, .IP \(bu 4 the ternary operator \fB?\& :\fR .IP \(bu 4 parentheses .PD .PP For example, \fB%[ 3 + 4 * (1 + %two) ]\fR will expand to \fB15\fR if \fB%two\fR expands to \fB2\fR.\& Version terms are compared using RPM version ([\fIepoch\fR:]\fIversion\fR[-\fIrelease\fR]) comparison algorithm, rather than regular string comparison.\& .PP Note that the \fB%[\fR\fIEXPRESSION\fR\fB]\fR expansion is different to the \fB%{expr:\fR\fIEXPRESSION\fR\fB}\fR macro.\& With the latter, the macros in the expression are expanded first and then the expression is evaluated (without re-expanding the terms).\& Thus .PP .nf .RS 4 rpm --define \&'foo 1 + 2\&' --eval \&'%{expr:%foo}\&' .fi .RE .PP will print \fB3\fR.\& Using \fB%[%foo]\fR instead will result in the error that "1 + 2" is not a number.\& .PP 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.\& \fB%["%file"]\fR will even work if the \fB%file\fR macro expands to a string that contains a double quote.\& .PP Added: 4.\&16.\&0 .PP .SS Lua expansion The most powerful of the macro expansion methods is using RPM'\&s embedded Lua interpreter: .PP \fB%{lua:\fR\fILUA-CODE\fR\fB}\fR .RS 4 Execute \fILUA-CODE\fR using RPM'\&s embedded Lua interpreter, expanding to the code'\&s \fBprint()\fR'\&ed output.\& .PP .RE See \fBrpm-lua\fR(7) for the details.\& .PP .SH 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.\& .PP The syntax for defining parametric macros is: .PP .RS 4 \fINAME\fR([\fIOPTIONS\fR]) \fIBODY\fR .PP .RE If present, the \fIOPTIONS\fR (i.\&e.\& the string between parentheses) are passed exactly as is to \fBgetopt\fR(3) for argc/argv processing at the beginning of a macro invocation.\& Only short options are supported.\& .PP \fB-\fR as the sole \fIOPTIONS\fR 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 \fB-\fR, the default processing only gets in the way.\& .PP .SS Automatic macros While a parameterized macro is being expanded, the following shell-like automatic macros are available: .PP .TS allbox;l lx l lx l lx l lx l lx l lx l lx l lx. T{ \fBMacro\fR T} T{ \fBDescription\fR T} T{ \fB%0\fR T} T{ the name of the macro being invoked T} T{ \fB%*\fR T} T{ all arguments (unlike shell, not including any processed flags) T} T{ \fB%**\fR T} T{ all arguments (including any processed flags) T} T{ \fB%#\fR T} T{ the number of arguments T} T{ \fB%{-f}\fR T} T{ if present at invocation, the last occurrence of flag \fBf\fR (flag and argument) T} T{ \fB%{-f*}\fR T} T{ if present at invocation, the argument to the last occurrence of flag \fBf\fR T} T{ \fB%1\fR, \fB%2\fR, .\&.\&.\& T} T{ the arguments themselves (after \fBgetopt\fR(3) processing) T} .TE .sp 1 If the built-in option processing was disabled with \fB-\fR as the \fIOPTIONS\fR field, only the following automatic macros are available: .PP .TS allbox;l lx l lx l lx l lx l lx. T{ \fBMacro\fR T} T{ \fBDescription\fR T} T{ \fB%0\fR T} T{ the name of the macro being invoked T} T{ \fB%*\fR, \fB%**\fR T} T{ all arguments T} T{ \fB%#\fR T} T{ the number of arguments T} T{ \fB%1\fR, \fB%2\fR, .\&.\&.\& T} T{ the arguments themselves T} .TE .sp 1 Automatic macros are automatically defined and undefined on parametric macro entry and exit.\& .PP .SS 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 \fB%{-f}\fR which expands (literally) to \fB-f\fR if \fB-f\fR was mentioned when the macro was invoked.\& There are also provisions for including text if a flag was present using \fB%{-f:X}\fR.\& This macro expands to (the expansion of) \fBX\fR if the flag was present.\& The negative form, \fB%{!\&-f:Y}\fR, expanding to (the expansion of)\fB Y\fR if \fB-f\fR was \fBnot\fR present, is also supported.\& .PP .SS 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: .PD 0 .IP \(bu 4 automatic macros have local scope, ie.\& are only visible on the call-level of the macro itself .IP \(bu 4 user-defined local macros have nested scope, ie.\& are visible on the call-level of the macro itself and deeper .PD .PP 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).\& .PP To define a global macro inside a parametric macro, you \fImust\fR use \fB%global\fR instead of \fB%define\fR.\& Also note that because such a macro may be referring to other macros only visible in the current scope, \fB%global\fR \fIexpands the macro body once at the time of definition\fR.\& .PP .SS Calling convention When a parametric macro is expanded, the following calling convention is used: .PD 0 .IP 1. 4 any arguments to the macro are expanded on the call-level of the callee .IP 2. 4 any options to the macro are processed .IP 3. 4 automatic macros are set up for the options and the arguments .IP 4. 4 the macro body is recursively expanded .IP 5. 4 all macros defined on this call-level are discarded .PD .PP .SH BUILT-IN MACROS RPM supports the following built-in macros for various operations.\& Built-in macros cannot be undefined or overridden.\& .PP Note: The \fB%{name:arg}\fR 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.\& .PP .SS 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 \fIwithout\fR the preceding \fB%\fR-character.\& .PP \fB%define\fR \fINAME\fR[([\fIOPTIONS\fR])] \fIBODY\fR .RS 4 This is the primary way to define macros.\& A \fB%define\fR is always fully declarative: no macro expansion takes place, and it has no side-effects.\& Macros defined with it are in global scope, unless the definition occurs inside a parametric macro.\& .PP Example: .nf .RS 4 %define mypath /usr/bin/mine .fi .RE .PP .RE \fB%global\fR \fINAME\fR[([\fIOPTIONS\fR])] \fIBODY\fR .RS 4 The \fB%global\fR primitive is identical in syntax to \fB%define\fR, but has two critically important behavioral differences: as it'\&s name suggests, a macro defined with \fB%global\fR always has a global scope regardless of where it'\&s used.\& .PP The second difference is that the \fIBODY\fR 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 \fB%global\fR is used, depending on the contents and the other macros used in \fIBODY\fR.\& 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.\& .PP Note that while \fB%global\fR technically accepts an \fIOPTIONS\fR field, it is ill-suited for defining parametric macros because of the \fIBODY\fR expansion behavior.\& .PP Example: .nf .RS 4 %global snapver 0-0\&.48\&.20240616git .fi .RE .PP .RE \fB%undefine\fR \fINAME\fR .RS 4 Note that \fB%undefine\fR only pops a macro definition from the stack, so using it does \fInot\fR guarantee that \fINAME\fR is undefined after calling \fB%undefine\fR on it.\& Automatic macros and built-in macros cannot be undefined.\& .PP Example: .nf .RS 4 %undefine mypath .fi .RE .PP .RE \fB%{load:\fR\fIFILE\fR\fB}\fR .RS 4 Load an \fBrpm-macrofile\fR(5) file.\& (Added: 4.\&12.\&0) .PP Example: .nf .RS 4 %{load:/some/dir/macros\&.foo} .fi .RE .PP .RE .SS Macro expansion \fB%{expand:\fR\fIBODY\fR\fB}\fR .RS 4 Expand \fIBODY\fR as if it were a macro body.\& Useful for increased indirection, such as to expand a macro name constructed from two or more macros.\& .PP Example: .nf .RS 4 %{expand:%{foo_prefix}%{foo_suffix}} .fi .RE .PP .RE \fB%{expr:\fR\fIEXPRESSION\fR} .RS 4 Expand \fIEXPRESSION\fR.\& See \fBExpression expansion\fR.\& (Added: 4.\&15.\&0) .PP Example: .nf .RS 4 %{expr:5*1024} .fi .RE .PP .RE \fB%{lua:\fR\fILUA-CODE\fR\fB}\fR .RS 4 Expand to output of \fILUA-CODE\fR using the embedded Lua interpreter.\& See \fBLua expansion\fR.\& .PP Example: .nf .RS 4 %{lua:for i=65,90 do print(string\&.char(i)) end} .fi .RE .PP .RE \fB%{macrobody:\fR\fINAME\fR\fB}\fR .RS 4 Expand to the literal body of the macro \fINAME\fR.\& (Added: 4.\&16.\&0) .PP Example: .nf .RS 4 %{macrobody:_libdir} .fi .RE .PP .RE .SS String operations \fB%dnl\fR .RS 4 Discard to next line (without expanding anything).\& \fB%dnl\fR is the recommended way to comment out things in spec files because it works everywhere and disables macro processing for that line.\& (Added: 4.\&15.\&0) .PP Example: .nf .RS 4 %dnl This is a comment on %{mymacro} behavior .fi .RE .PP .RE \fB%{gsub \fR\fISTRING\fR, \fIPATTERN\fR, \fIREPL\fR [,\fIN\fR]\fB}\fR .RS 4 Replace all (or \fIN\fR first if given) occurrences of \fIPATTERN\fR in \fISTRING\fR by \fIREPL\fR.\& .PP Added: 4.\&19.\&0 .PP Example: .nf .RS 4 %{gsub aabbaacc aa dd 1} .fi .RE .PP .RE \fB%{len:\fR\fISTRING\fR\fB}\fR .RS 4 Expand to length of \fISTRING\fR.\& (Added: 4.\&19.\&0) .PP Example: .nf .RS 4 %{len:9bf7da058a7c582878310e75be3d56a5a8b67f95} .fi .RE .PP .RE \fB%{lower:\fR\fISTRING\fR\fB}\fR .RS 4 Expand to lowercase \fISTRING\fR.\& (Added: 4.\&19.\&0) .PP Example: .nf .RS 4 %{lower:CamelCase}\&' .fi .RE .PP .RE \fB%{quote:\fR\fISTRING\fR\fB}\fR .RS 4 Quote arguments for passing empty strings and strings with embedded whitespace as parametric macro arguments.\& (Added: 4.\&14.\&0) .PP Example: .nf .RS 4 %myzip -x %{quote:empty spaces\&.zip} .fi .RE .PP .RE \fB%{rep \fR\fISTRING\fR, \fIN\fR [,\fISEP\fR]\fB}\fR .RS 4 Expand to a string that is the concatenation of \fIN\fR copies of \fISTRING\fR, separated by \fISEP\fR (if specified).\& .PP Added: 4.\&19.\&0 .PP Example: .nf .RS 4 %{rep a 5} .fi .RE .PP .PP .RE \fB%{reverse:\fR\fISTRING\fR\fB}\fR .RS 4 Reverse a string.\& (Added: 4.\&19.\&0) .PP Example: .nf .RS 4 %{reverse:tac} .fi .RE .PP .RE \fB%{shescape:\fR\fISTRING\fR\fB}\fR .RS 4 Single quote \fISTRING\fR with escapes for use in shell.\& (Added: 4.\&18.\&0) .PP Example: .nf .RS 4 %{shescape:foo\&'s} .fi .RE .PP .RE \fB%{shrink:\fR\fISTRING\fR\fB}\fR .RS 4 Trim leading and trailing whitespace from \fISTRING\fR, reduce intermediate whitespace to a single space.\& (Added: 4.\&14.\&0) .PP Example: .nf .RS 4 %{shrink:aa bb ccc } .fi .RE .PP .RE \fB%{span:\fR\fISTRING\fR\fB}\fR .RS 4 As-is string, handy for wrapping multiline macros.\& (Added: 6.\&0.\&0) .PP Example: .nf .RS 4 %{span: %one thing %another thing } .fi .RE .PP .RE \fB%{sub \fR\fISTRING\fR, \fII\fR, [,\fIJ\fR]\fB}\fR .RS 4 Expand to substring of \fISTRING\fR that starts at \fBI\fR and continues until \fBJ\fR.\& \fBI\fR and \fBJ\fR can be negative to index from the string'\&s end.\& If \fBJ\fR is absent, then it is assumed to be equal to \fB-1\fR (ie.\& string end).\& .PP Added: 4.\&19.\&0 .PP Example: .nf .RS 4 *%{sub myfile\&.zip 3 6}* .fi .RE .PP .RE \fB%{upper:\fR\fISTRING\fR\fB}\fR .RS 4 Expand to uppercase \fISTRING\fR.\& (Added: 4.\&19.\&0) .PP Example: .nf .RS 4 %{upper:CamelCase}\&' .fi .RE .PP .RE .SS File and path operations \fB%{basename:\fR\fIPATH\fR\fB}\fR .RS 4 \fBbasename\fR(1) macro analogue.\& .PP Example: .nf .RS 4 %{basename:/some/dir/file\&.suf} .fi .RE .PP .RE \fB%{dirname:\fR\fIPATH\fR\fB}\fR .RS 4 \fBdirname\fR(1) macro analogue.\& .PP Example: .nf .RS 4 %{dirname:/some/dir/file\&.suf} .fi .RE .PP .RE \fB%{exists:\fR\fIPATH\fR\fB}\fR .RS 4 Test file existence, expands to 1/0.\& (Added: 4.\&18.\&0) .PP Example: .nf .RS 4 %{exists:%{builddir}/myflag\&.txt} .fi .RE .PP .RE \fB%{suffix:\fR\fIPATH\fR\fB}\fR .RS 4 Expand to suffix part of a filename.\& .PP Example: .nf .RS 4 %{suffix:myfile\&.zip} .fi .RE .PP .RE \fB%{url2path:\fR\fIURL\fR\fB}\fR .RS 4 Convert url to a local path.\& .PP Example: .nf .RS 4 %{url2path:http://rpm\&.org/not/there} .fi .RE .PP .RE \fB%{uncompress:\fR\fIPATH\fR\fB}\fR .RS 4 Expand to a command for outputting argument \fIPATH\fR to standard output, uncompressing as needed.\& .PP Example: .nf .RS 4 %{uncompress /my/source\&.tar\&.gz} .fi .RE .PP .RE \fB%{xdg:\fR\fIKIND\fR\fB}\fR .RS 4 Expand to XDG base directory paths.\& Supported values for \fIKIND\fR are: .PD 0 .IP \(bu 4 \fBcache\fR: user-specific non-essential (cached) data .IP \(bu 4 \fBconfig\fR: user-specific configuration files .IP \(bu 4 \fBdata\fR: user-specific data files .IP \(bu 4 \fBstate\fR: user-specific state data .PD .PP Added: 6.\&0.\&0 .PP Example: .nf .RS 4 %{xdg config} .fi .RE .PP .RE .SS Environment info \fB%getncpus\fR .RS 4 Expand to the number of available CPUs.\& (Added: 4.\&15.\&0) .PP .RE \fB%{getncpus:\fR\fIKIND\fR\fB}\fR .RS 4 Expand to the number of available CPUs, supported valued for \fIKIND\fR are .PD 0 .IP \(bu 4 \fBtotal\fR: total number of available CPUs (same as \fB%getncpus\fR) .IP \(bu 4 \fBproc\fR: number of available CPUs for processes .IP \(bu 4 \fBthread\fR: number of available CPUs for threads .PD .PP \fBproc\fR and \fBthread\fR account for available memory, including address space limitations for threads.\& .PP Added: 4.\&19.\&0.\& .PP Example: .nf .RS 4 %{getncpus proc} .fi .RE .PP .RE \fB%getconfdir\fR .RS 4 Expand to RPM "home" directory (typically /usr/lib/rpm).\& .PP .RE \fB%{getenv:\fR\fINAME\fR\fB}\fR .RS 4 \fBgetenv\fR(3) macro analogue.\& .PP Example: .nf .RS 4 %{getenv:HOME} .fi .RE .PP .RE \fB%rpmversion\fR .RS 4 Expand to running RPM version.\& .PP .RE .SS Output \fB%{echo:\fR\fISTRING\fR\fB}\fR .RS 4 Print \fISTRING\fR to process standard output.\& .PP Example: .nf .RS 4 %{echo:Building with foo} .fi .RE .PP .RE \fB%{warn:\fR\fISTRING\fR\fB}\fR .RS 4 Print \fISTRING\fR prefixed with "warning: " to process standard error.\& .PP Example: .nf .RS 4 %{warning:Foo is deprecated} .fi .RE .PP .RE \fB%{error:\fR\fISTRING\fR\fB}\fR .RS 4 Print \fISTRING\fR prefixed with "error: " to process standard error and flag an error in the macro processor.\& .PP Example: .nf .RS 4 %{error:Invalid argument} .fi .RE .PP .RE \fB%verbose\fR .RS 4 Expand to 1/0 whether RPM is in verbose mode or not.\& (Added: 4.\&17.\&1) .PP .RE \fB%{verbose:\fR\fISTRING\fR\fB}\fR .RS 4 Expand to \fISTRING\fR if RPM is in verbose mode, the empty string if not.\& (Added: 4.\&17.\&1) .PP Example: .nf .RS 4 %{verbose:-x} .fi .RE .PP .RE .SS Spec specific macros \fB%{S:\fR\fINUMBER\fR\fB}\fR .RS 4 Expand to the filename of the specified Source \fINUMBER\fR.\& \fB%{S:n}\fR is equivalent to \fB%{SOURCEn}\fR.\& .PP .RE \fB%{P:\fR\fINUMBER\fR\fB}\fR .RS 4 Expand to the filename of the specified Patch \fINUMBER\fR.\& \fB%{P:n}\fR is equivalent to \fB%{PATCHn}\fR.\& .PP .RE .SS Diagnostics \fB%trace\fR .RS 4 Toggle print of debugging information before/after expansion.\& .PP .RE \fB%dump\fR .RS 4 Print the active (i.\&e.\& non-covered) macro table.\& .PP .RE \fB%__file_name\fR .RS 4 Expand to current filename (if parsing a file).\& (Added: 4.\&15) .PP .RE \fB%__file_lineno\fR .RS 4 Expand to current line number in current file (if parsing a file).\& (Added: 4.\&15) .PP .RE .SH EXAMPLES .SS Example 1. Define a simple macro Define macro \fBmylib\fR to a path relative to \fB%{_libdir}\fR macro in a spec: .PP .nf .RS 4 %define mylib %{_libdir}/mine .fi .RE .PP .SS Example 2. Define a parametric macro Define parametric macro \fBmyhelper\fR which executes the program specified by \fB%myprog\fR with it'\&s first argument and always passing the option \fB--some-opt\fR to it, and additionally the \fB--xtra\fR option if it received the \fB-x\fR option itself: .PP .nf .RS 4 %define myhelper(x) %{myprog} --some-opt %{?-x:--xtra} %{1} .fi .RE .PP .SS Example 3. Define a macro utilizing shell expansion Define macro \fB%today\fR that expands to the current date in \fIYYMMDD\fR format by calling the \fBdate\fR(1) shell utility.\& Note the 2nd \fB%\fR needed to escape the arguments to \fBdate\fR(1): .PP .nf .RS 4 %define today %(date +%%y%%m%%d) .fi .RE .PP .SS Example 4. Define a macro conditionally Define macro \fBmypath\fR if it wasn'\&t previously defined: .PP .nf .RS 4 %{!?mypath: %define mypath /some/where} .fi .RE .PP .SS Example 5. Conditional expansion Expands to \fB1\fR if \fBuse_foo\fR is defined and \fB0\fR otherwise: .PP .nf .RS 4 %{?use_foo:1}%{!?use_foo:0} .fi .RE .PP .SS Example 6. Expressions Calculate 5 * 1024: .PP .nf .RS 4 %[5 * 1024] .fi .RE .PP Expand to literal \fBtrue\fR or \fBfalse\fR depending on a condition: .PP .nf .RS 4 %[1 < 2 ? "true" : "false"] .fi .RE .PP Compare versions, expanding to \fB1\fR or \fB0\fR on true/false: .PP .nf .RS 4 %[ v"3\&.1\&.0-1" < v"1\&.0~alpha-2" ? 1 : 0] .fi .RE .PP Expands to \fB1\fR if \fB%aa\fR expands to \fB5\fR, otherwise expands to \fB2\fR: .PP .nf .RS 4 %[ "%{aa}" == "5" ? 1 : 2] .fi .RE .PP .SH DEBUGGING Some useful tools for working with and troubleshooting macros: .PP \fBrpm --eval "\fR\fIVALUE\fR\fB"\fR .RS 4 Expand \fIVALUE\fR on the command line.\& .PP .RE \fBrpm --define "aa 11" --eval "%aa"\fR .RS 4 Define and evaluate a macro on the command line.\& .PP .RE \fBrpm --eval "%global unamer %(uname -r)" --eval "%{macrobody:unamer}"\fR .RS 4 Define and examine macro body using \fB%global\fR on the command line.\& .PP .RE \fBrpm --eval "%define unamer %(uname -r)" --eval "%{macrobody:unamer}"\fR .RS 4 Define and examine macro body using \fB%define\fR on the command line.\& .PP .RE \fBrpmlua\fR .RS 4 Run an interactive shell in the embedded Lua environment.\& .PP .RE \fBrpmlua -e '\&print(macros.\&defined("_libdir"))'\&\fR .RS 4 Using the embedded Lua interpreter in standalone form, print print 1/0 whether macro \fB_libdir\fR is defined or not.\& .PP .RE \fBrpmspec --shell\fR .RS 4 Run an interactive shell in the macro environment.\& .PP .RE \fBrpmspec --shell telnet.\&spec\fR .RS 4 Run an interactive shell in the macro environment after parsing \fBtelnet.\&spec\fR.\& .PP .RE .SH SEE ALSO \fBrpm\fR(8) \fBrpm-common\fR(8) \fBrpm-macrofile\fR(5) \fBrpm-config\fR(5) \fBrpm-lua\fR(7) \fBrpmspec\fR(1) \fBrpmlua\fR(1)