initCommon(); $template->displayHeader(); ?>

10.6. Defining Conditional Builds

With the ability to define macros inside spec files, and also to use macros defined elsewhere, you gain a lot of control over how your package gets built. You can go further, though, and use special directives to perform only certain commands based on certain conditions. This adds a powerful capability to your spec files, and also makes it much easier to do things like build for multiple versions of Linux or other operating systems, as well as handle various backwards-compatibility issues.

To define conditional build commands, you need to create conditional constructs in your package’s spec file. In addition, you need to define macros that the conditional constructs use to determine whether or not to execute a set of spec file directives.

Cross Reference

See Chapter 21 for more on macro file locations, and Chapters 19 and 20 for more on using RPM on other versions of Linux and other operating systems, respectively.

RPM supports a number of ways to make parts of your spec file enabled or disabled based on certain conditions. These include conditional macros, conditional blocks, and special directives based on the system architecture.

10.6.1. Defining conditional macros

You can use a special syntax to test for the existence of macros. For example:

%{?macro_to_test: expression}

This syntax tells RPM to expand the expression if the macro macro_to_test exists. If the macro macro_to_test does not exist, nothing will be output. You can also reverse this test. A leading exclamation point, !, tests for the non-existence of a macro:

%{!?macro_to_test: expression}

In this example, if the macro_to_test macro does not exist, RPM will expand the expression.

If you want, you can omit the expression and just test for the existence of the macro. If it exists, RPM will use the value of the macro. If the macro does not exist, RPM will use nothing. For example:

%build

./configure %{?_with_ldap}

make

In this case, if the _with_ldap macro exists, the value of that macro will get passed on the command line to the configure script. If the _with_ldap macro does not exist, nothing extra will be passed on the command line to the configure script. This is very important when creating commands to build or install packages.

Cross Reference

Many of the macros you will test this way are set up with the --with command-line parameter. See Chapter 19 for details.

10.6.2. Using conditional blocks

The %if macro enables all the directives up to the %endif directive, if the condition is true. This is much like scripting languages. For example:

%if %{old_5x}

%define b5x 1

%undefine b6x

%endif

In this case, if the %old_5x macro has a value, the test will be true and all the directives inside the block will get executed.

A %else allows you to specify what to do if the test is not successful. For example:

%if %{old_5x}

%define b5x 1

%undefine b6x

%else

%define b6x 1

%undefine b5x

%endif

In this case, if the %old_5x macro has a value, then all the directives up to the %else will get executed. Otherwise, if the %old_5x macro has no value, the directives from the %else to the %endif will get executed.

Again, use an exclamation point to negate the test. For example:

%if ! %{old_5x}

%define b5x 1

%undefine b6x

%endif

You can use a && for an AND test. For example:

%if %{old_5x} && %{old_6x}

%{error: You cannot build for .5x and .6x at the same time}

%quit

%endif

10.6.3. Using architecture-based conditionals

In addition to the general-purpose %if conditional directive, you can use special directives that test for processor architecture and operating system.

The %ifarch directive enables all the directives up to the %endif directive, if the processor architecture matches the values you pass to the %ifarch directive. For example:

%ifarch sparc

%define b5x 1

%undefine b6x

%endif

This block will only get executed if the processor architecture is SPARC.

Cross Reference

Chapter 21 covers RPM architecture and operating system names.

You can pass more than one architecture name, separated by commas or spaces. For example:

%ifarch sparc alpha

%define b5x 1

%undefine b6x

%endif

This example tests if the processor architecture is SPARC or Alpha.

As with the %if directive, you can also use an %else, to cover all cases where the test is not true. For example:

%ifarch sparc alpha

%define b5x 1

%undefine b6x

%else

%define b6x 1

%undefine b5x

%endif

This example tests if the processor architecture is SPARC or Alpha. If so, the directives from the %ifarch to the %else are executed. If not, the directives from the %else to the %endif are executed.

The %ifnarch directive reverses the %ifarch test. That is, %ifnarch tests if the architecture is not one of the values listed. The following example tests if the processor architecture is not an i386 or an Alpha.

%ifnarch i386 alpha

%define b5x 1

%undefine b6x

%endif

The %ifos directive tests for the operating system. For example:

%ifos linux

%define b5x 1

%undefine b6x

%endif

This example tests if the operating system is Linux. You can reverse the test with the %ifnos directive. For example:

%ifnos irix

%define b5x 1

%undefine b6x

%endif

This example tests if the operating system is not Irix.

displayFooter('$Date: 2005/11/02 19:30:06 $'); ?>