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.