Conditional Builds

Rpmbuild supports conditional package builds with the command line switches --with and --without.

Here is an example of how to enable gnutls and disable openssl support:

$ rpmbuild -ba newpackage.spec --with gnutls --without openssl

Creating build conditionals

Using %bcond (new in rpm 4.17.1)

To create a build conditional in a spec file, use the %bcond macro at the beginning of the file, specifying the name of the conditional and its default value:

# Create a "gnutls" build conditional, enabled by default:
%bcond gnutls 1
# Create a "bootstrap" build conditional, disabled by default:
%bcond bootstrap 0

The default can be any numeric expression. To pass a complex expression as a single argument, you can enclose it in %[...] .

# Create `--with openssl` and `--without openssl` cli options, with the default
# being the inverse of the gnutls setting:
%bcond openssl %{without gnutls}

# Create `extra_tests` bcond, enabled by default if both of the other
# conditinals # are enabled:
%bcond extra_tests %[%{with gnutls} && %{with sqlite}]

Using %bcond_with and %bcond_without

Build conditionals can also be created using the macros %bcond_with and %bcond_without. These macros create command line options. When you add an option to build with feature X, it implies that the default is to build without.

These macros have historically confused a lot of people (which is why %bcond was added) but are not hard to use once you think in terms of adding command line switches:

# Create an option to build with gnutls (`--with gnutls`), thus default to
# building without it
%bcond_with gnutls
# Create an option to build without openssl (`--without openssl`), thus default
# building with it
%bcond_without openssl

To change the default, change the command line switch from with to without or vice versa. The remainder of the spec file can be left unchanged.

Check whether an option is enabled or disabled

To make parts of the spec file conditional depending on the command-line switch, you can use the %{with foo} macro or its counterpart, %{without foo}:

%if %{with gnutls}
BuildRequires:  gnutls-devel
%endif
%if %{with openssl}
BuildRequires:  openssl-devel
%endif

Alternatively, you can test the presence (or lack thereof) of %with_foo macros which is nicer in other situations, e.g.:

%configure \
   %{?with_static:--enable-static} \
   %{!?with_static:--disable-static}

Always test for the with-condition, not the without-counterpart!

Overriding Defaults

For distributions it can be useful to override the build conditionals on a global scale. To not interfere with the users ability to overwrite the conditionals on the command line there is an option to override the default value independently of the one chosen in the spec file.

To do this one can define a %bcond_override_default_NAME macro as one or zero or use the %{bcond_override_default NAME VALUE} macro. Distributions can put the former into a global macro file that is installed during local builds to propagate these changed defaults outside their build system. Using different versions of the macro file allows building the same set of packages in different ways - e.g. against different libraries - without altering all the spec files.

E.g. add this in the macros file to disable support for zstd assuming this is a common conditional in the distribution:

%bcond_override_default_zstd 0

All packages with a zstd bcond will now build as if the bcond was defined as %bcond zstd 0. I.e. unless --with zstd is used, the bcond will be disabled.

References