7.12. Macros

Macros are a powerful feature of specfiles. A macro is a memorized text fragment. Every occurence of the macro's name, in the specfile, is replaced by the memorized text fragment. lpbuild defines a number of macros before it begins reading the specfile. The specfile can use these macros; it can also define and use new macros.

7.12.1. Defining macros

%define name text

%define must appear on a line by itself. %define creates a new macro called name, which contains text. text is a single line of text. There's no explicit upper limit to its maximum size. A very large text may be split across multiple physical lines (for readability) by terminating the first line with a blackslash character (which must be the very last character on the line). The "\", the newline character, and all leading whitespace on the second line are replaced by a single space character, and the remaining contents of the second line are included in text. Repeat this again to join the third line's contents to text.

At the end of the process, text is always a single line, because all embedded newlines (and the preceding backslashes) are replaced by spaces; additionally all leading and trailing whitespace in text is trimmed off.

If the macro name is already defined, its contents are destroyed and replaced by the new text.

7.12.2. Referencing macros

If name is a name of a defined macro, then every occurence of "%name" is replaced by macro's text:

%define DEBUG echo

%DEBUG "Hello world"

This example, from a build script, results in a shell script that contains: echo "Hello world".

As suggested by this example, macros can be referenced anywhere (with few exceptions that will be described later). They may be defined and referenced in the build header, in package declarations, in build scripts, and in package manifests. It's important to understand that lpbuild resolves macro references in build scripts before the build scripts are executed by the shell interpreter (which does its own variable, command, and other substitutions).

Macro definitions may contain references to other macros. These references are not processed when the macro is defined, but whenever it is used. Example:

%define DEBUG echo "%debugmessage"

%define debugmessage Hello world

   %DEBUG

This example also executes the echo "Hello world" command. The debugmessage macro does not exist when lpbuild reads %define DEBUG. lpbuild does not process macro references when defining macros. lpbuild sets the text of the new DEBUG macro to "echo "%debugmessage"", literally.

lpbuild reads "%DEBUG", and this gets initially replaced by the macro's contents: echo "%debugmessage". The debugmessage macro exists now, so the reference to this macro gets processed, forming the final shell script command.

7.12.3. Removing macros

%undef name

%undef must appear on a line by itself. %undef removes the definition of the macro called name.

7.12.4. Predefined macros

lpbuild defines several macros before processing the specfile. The following macros are available for use in the specfile:

%__arch

The hardware architecture the application is being built for. The default setting for %__arch is same as %__platform, but may be overriden by "BuildArch:". On specfiles that specify a multiple platform build (see Section 7.13 for more information), %__arch gets reset at the beginning of each build pass.

%__builddir

A temporary work directory, initially empty. Each %begin build script runs with the current directory set to %__builddir. The shell variable $__builddir is automatically set to %__builddir's contents. The application's source code is usually unpackaged and compiled in this work directory.

%__chbuilddir

A macro used in a %build script to change the current directory to the default work directory. This originally defaults to %__builddir. The first %setup macro changes the default work directory to be the subdirectory where the source code was extracted to.

%configure

This is a convenience macro used by build scripts. This macro runs the %__chbuilddir macro, then the "./configure" command, which is expected to be an autoconf-generated configuration script. %configure specifies all autoconf options according to the ontents of their equivalent macros, described in Section 7.12.4.1.

%__cpu

The name of the CPU lpbuild is running on. For example: %__cpu is set to "i686" on modern Pentium II systems.

%__create_debugpackage

This macro specifies whether the "debuginfo" subpackage should be created. See Section 7.3.2 for more information. If not set, its default value is "1", which creates the subpackage. This macro must be explicitly set to "0" in order to suppress the creation of the "debuginfo" subpackage.

%__defaultRootdir

This macro specifies where lpbuild creates the temporary work directory, and the installation image directory. The default value is /var/tmp/pkgtmp-%{__name}-%{__version}-%{__release}-%{__cpu}. So, building a specfile for gizmowidget version 1.0 release 0.1, on an Opteron system will use /var/tmp/pkgtmp-gizmowidget-1.0-0.1-x86_64. The same version and release of an application cannot be simultaneously built, at the same time, more than once.

lpbuild sets up %__builddir and %__installdir as subdirectories of %__defaultRootdir.

%__distribution

This is the assigned label of the system distribution lpbuild is running on.

%__installdir

The installation image directory, initially empty. The build scripts are expected to create the application's installation image in this directory. After the build scripts run succesfully to an end, lpbuild turns the installation image into the various package files. The shell variable $__installdir is automatically set to %__installdir's contents. See Section 7.7 for more information on installation images.

%__home

The home directory of the user that's running LPMtool.

%__ldconfig

This macro is set to "/sbin/ldconfig", the shared library link update utility. /sbin/ldconfig is typically invoked from %post and %postun scripts, like:

%post
%__ldconfig

Or, a better example:

%post -p %__ldconfig

LPMtool quietly detects when /sbin/ldconfig gets passed as the interpreter, via the -p flag (for the empty %post and %postun script), and performs some value-added processing. In addition to listing "/sbin/ldconfig" as a required package dependency, LPMtool will also do the following:

  • The default arguments to the script are suppressed.

  • When multiple packages are installed and uninstalled, multiple consecutive invocations of "/sbin/ldconfig" are quietly combined into a single invocation of "/sbin/ldconfig".

%__name

The application's name.

%patch

This is a convenience macro used by build scripts. This macro expands to a shell script that applies the patch file specified by the "Patch:" header. This script doesn't really do much except run the patch utility, after the file specified by the "Patch:" header is un-bzipped, un-gzipped, or un-zipped, if its filename's extension indicates so.

The macro %patch2 is initialized to a similar script that applies the patch file specified by the "Patch2:" build header, if one exists. If the specfile contains "Patch3:" there will be a %patch3 macro, and so on.

Any options that follow "%patch" will be passed along, verbatim, to the patch utility.

%PATCH, %PATCH2...

The absolute pathnames to the corresponding patch files, from the build header. Use these macros if there's some reason to apply the patches manually, instead of using the %patch macros.

%__platform

The hardware platform lpbuild is running on. The default setting for %__platform is "i386" on any 32-bit platform Intel CPU system.

%__release

The application's release.

%setup

This is a convenience macro used by build scripts. This macro runs a script that unpacks the source code archive specified by the "Source:" build header. The filename's extension is examined, and the archive is un-bzipped, un-gzipped, un-zipped, un-tarred, and/or un-cpioed, as necessary.

The macro %setup2 is initialized to a similar script that unpacks the source code archive specified by the "Source2:" build header, if one exists. If the specfile contains "Source3:" there will be a %setup3 macro, and so on.

The source code for most applications, though, is packed into a single tarball and most specfiles will have only one %setup macro.

The first %setup macro in the build script changes the current directory to the top of the build directory, like %begin, before unpacking the source code archive. If the %setup macro is preceded by a shell script fragment that changes the current directory, %setup includes a cd command back to the top of the build directory, from which the source code archive gets unpacked.

Most source code archives extract the source code into a subdirectory, and not the current directory, so a subdirectory gets created in the work directory where the actual source code extracted. By convention, packages built with the GNU toolchain will extract the source to into a subdirectory called "name-release". As an example: the archive for version 2.1 of "gizmoutil" extracts all files in the gizmoutil-2.1 subdirectory, (such as gizmoutil-2.1/Makefile, gizmoutil-2.1/configure, et al).

After the %setup macro is processed, this subdirectory becomes the new default directory. All following %build scripts will begin execution from this default directory. Additionally the -f option to %files is interpreted relative to the new default subdirectory, instead of the start of the build directory (see Section 7.11). Also, the filenames specified by %doc (see Section 7.10) will also be relative to the new default subdirectory.

NOTE:

The default subdirectory is reset only by the first %setup macro (and the default work directory remains the start of the build directory if the %setup macro is never used). If there are more than one %setup macro, the remaining source code archives are unpacked starting from the new default subdirectory, which remains unchanged.

Use the following options to the %setup macro with a source code archive does not follow the default layout:

%setup -n subdirname

Use the -n option when the files in the source code archive are extracted to a non-standard subdirectory. The -n option overrides the default subdirectory name of"name-release". All other side effects remain the same: the indicated subdirectory becomes the new default work directory.

%setup -c

The -c explicitly creates the subdirectory. Use this option with source code archives that extract files to the current directory. The -c option can be used together with -n to override the default subdirectory name.

NOTE:

If the %setup does not have either of these two options, then after the %setup macro finishes the current directory for the build script remains the top of the work directory, because that's where the tar, or the cpio, or the unzip command was run from. However the default work directory now becomes the newly created subdirectory. Use the %__chbuilddir macro to reset the current directory. The %__chbuilddir macro is included in the %configure macro, so explicitly running %__chbuilddir is not required when a %configure immediately follows a %setup. This happens to be the case for the overwhelming majority of applications.

%SOURCE, %SOURCE2...

The absolute pathnames to the corresponding source files, from the build header. Use these macros if the listed source files are not conventional source code tarballs, and require custom processing.

%__user

The username that's running LPMtool.

%__version

The application's version.

7.12.4.1. Default autoconf settings

lpbuild defines the following macros to specify the default settings for the accordingly-named options used by autoconf-generated build scripts. These macros may be used in build scripts and package file manifests to correctly specify the same locations of installed files that what configure uses. If a specfile uses the %configure macro, and refers to the following macros in its package file manifests, then the default installation locations for the various files can be changed from their defaults just by redefining the macro. Redefining the macro automatically resets its corresponding option to the configure script, and updates the file manifest references. Of course, this works only as long as the application correctly pays heed to the options passed to the configure script.

The macros are: %_prefix, %_exec_prefix, %_bindir, %_sbindir, %_sysconfdir, %_datadir, %_includedir, %_libdir, %_libexecdir, %_localstatedir, %_sharedstatedir, %_mandir, and %_infodir.

Additionally, %_docdir is set to the default documentation directory. The %doc modifier, in the package file manifest section, copies the documentation files to %_docdir.

NOTE:

Do not manually create %_docdir, attempt to install documentation files in there, or list %_docdir in a %files section. The %doc modifier will take care of everything.

It is permissible, however, to redefine %_docdir away from its original default value.

7.12.4.2. Compression macros

lpbuild run the following macros after the last build scripts finishes, and the installation image is presumably created. These macros remove debugging information from installed files, and compress documentation files and manual pages.

%__strip_binaries

Remove debugging and symbol data from binaries.

%__strip_shared

Remove debugging data from shared libraries.

%__strip_static

Remove debugging data from static archive libraries.

%__strip_comment

Remove ELF version control section, and platform-specific note section.

%__compress_man_pages

This script looks for any "man/man*" directory in the installation image. If found, the "man" directory is expected to hold manual pages. This script compresses all files in this directory.

%__compress_info_files

This script finds all directories named "info" in the installation image. If found, the "info" directory is expected to hold texinfo documentation files. This script compresses all files in this directory.

Most applications experience no side effects as a result of running these scripts, except for smaller file sizes. Special-purpose packages can selectively disable these scripts by redefining them as a no-op, in their specfiles:

%define __strip_shared /bin/true

NOTE:

Compressed manual pages and info files are renamed to files with ".gz" extension. For that reason, %files should use wildcards to specify manual pages:

%files
%{_mandir}/man1/flashoffice.1*

Even though the application's "make install" ends up installing %{_mandir}/man1/flashoffice.1, the compression script will compress it and rename it as flashoffice.1.gz. It's possible to explicitly put flashoffice.1.gz in the %files section. It's better to use wildcards, though, in case the default compression for manual pages gets changed.

7.12.5. Advanced macro references

A macro's name must begin with an English letter, or the underscore character, "_" and can contain English letters, decimal digits, and underscores. It's possible to include most common punctutation characters in %define-ed name. When referencing the macro, put the name inside braces:

%define DEBUG echo "Hello world"

   %{DEBUG}

The braces are only optional here, because "DEBUG" contains only English letters. The braces may be required if name contained punctuations. The following punctuation characters are prohibited even when braces are used: parenthesis, square brackets, braces, quotes and apostrophes.

%(command)

command is a shell command. The shell runs command, and "%(command)" is replaced by its output. Any newlines in the output are replaced by spaces, and the leading and trailing whitespace in the command output is trimmed off.

NOTE:

Recall that macro references are not processed when a new macro is %defined, only when the new macro is referenced. Each time. Therefore:

%define timestamp  echo "The current time is %(date)"

   ...

   %timestamp

   ...

   %timestamp

Each reference to "%timestamp" causes "%(date)" to be replaced by the output of the "date" command, so if the build script runs for a while, and each reference to %timestamp echoes the current time.

Of course, the same thing can be done using backticks, in shell. This is just an example.

  %{expand: text}

This is an explicit macro dereference. Any macro references in text are explicitly expanded, and the whole thing is replaced by the result. Additionally, any occurence of "%%" in text is replaced by a single "%" (this does not occur outside of the "expand" construct). Explicit macro dereferencing occurs even on a %define line, where macro dereferencing normally does not happen:


%define timestamp  echo "%{expand: The current time is %(date)}"

   ...

   %timestamp

   ...

   %timestamp

This example has the same results as the previous example, except that the same time is always echoed: the time when the macro was defined.

NOTE:

When lpbuild reads "%(" it begins looking ahead for the matching ")". lpbuild does not have any idea about what shell commands look like. lpbuild's sole obligation is to invoke the shell interpeter to process the command; lpbuild's counts the parenthesis until they match up. All parenthesis in the shell command must be properly balanced, so that the closing ")" correctly terminates the shell command. The following example works as expected:

%(echo "foo()")

The first closing parenthesis is correctly matched up with the opening parenthesis in the shell command, and lpbuild continues to look for the closing parenthesis that matches the end of the shell command. The following example does not work, and results in an error:

%(echo "foo(";  )

lpbuild does not pay attention to quotes and apostrophes, so the closing parenthesis does not get matched up properly.

The situation is analogous with braces and "%{expand: text}".

  %{?name}
  %{!?name}

"%{?name}" is replaced by a literal "1" character if macro called name is defined, and "0" if not. "%{!?name}" is replaced by a literal "0" character if macro called name is defined, and "1" if not. Furthermore:

  %{?name: value}
  %{!?name: value}
  %{=name: value}
  %{!=name: value}

"%{?name: value}" is replaced by the expanded value of value if: macro called name is defined and is not "0"; and by empty text if it's not defined, or if the macro is defined as "0". "%{!?name: value}" is replaced by empty text if: the macro name is not defined, or is "0"; and by the expanded value otherwise.

"%{=name: value}" is replaced by a literal "1" character if the macro name exists and is set to value, and "0" character if not. "%{!=name: value}" is replaced by a literal "0" character if the macro name exists and value is its contents, and the "1" character if not. This works reliably only to test whether or not the macro name's text is a single word, or two.

7.12.6. Conditional text inclusion

%if value

...

%endif

lpbuild processes the text between "%if" and "%endif" only if value is not empty and is not "0". If value is empty, or is "0", the text between "%if" and "%endif" gets discarded, and not read.

%if value

...
%else
...

%endif

Either the text between "%if" and "%else", or "%ilse" and "%endif" gets processed by lpbuild, depending on value, and the other one gets discarded.

Here's a common way to use conditional text inclusion in a build script:

%if %{__arch: i386}

...
%else
...

%endif

In this example if the macro "%__arch" contains "i386" then the first text script gets included in the build script; otherwise the second text script gets included.

7.12.7. Macro processing order

It is very important to know the order in which macro references are processed. Here's a high level overview of how macros are processed by lpbuild (and the lpm command too):

  1. LPMtool reads one line of text from the specfile.

  2. The following macro directives are processed: "%{expand: value}", "%{?name: value}", "%{!?name: value}", "%{=name: value}", and "%{!=name: value}".

  3. After the previous directives are processed, the "%if", "%else", and "%endif" commands are processed. All further processing stops at this point if this text section is conditionally excluded.

  4. %define and %undef commands are processed.

  5. Finally, all references to "%macro" and "%(command)" are replaced with %macro's text or the output produced by executing "command".

NOTE:

When a large %define's text is split across multiple lines, conditional macro processing (see 2), occurs for all lines of text that are assembled into the final macro text.