openSUSE:Build Service prjconf

Jump to: navigation, search


The prjconf denotes the (build) configuration of a project. The main part of this file (/usr/lib/build/configs/$distro.conf) is the definition of the build environment. For simple projects, it may well be empty. But everything that normally needs a user decision (like packages providing the same stuff) or special macros/packages/flags in the build environment is defined here.

The syntax is basically the same as in rpm spec files, just the tags are different. Conditionals like %if, %ifarch etc also work.

From web interface you can go on the tab advanced and then project config. Using OSC you can do a:

osc meta prjconf <projectname>

A very similar listing can be seen with

osc buildconfig <projectname> <reponame>

Have a look at project config of the openSUSE:Factory project to get an impression about what is possible. See osc help meta for detailed other usage patterns.

The default package list for a build environment is:
Preinstall + Required + Support + Packages from dependency expansion.

Supported Tags


If pkg A provides pkg1 pkg2 pkg3, for example for bootstrapping, if you set Prefer: pkg1, pkg1 will be installed before pkg, but because pkg2 is needed, pkg will be installed and it will conflict with pk1. The solution would have been to install from the beginning pkg until pk1, pkg2, pkg3 are fully built. This is not yet supported by the OBS solver. As a workaround you can explicitly define the conflict.

 Conflict:<pkg>  <pkg1>  ...


The packages that need to be unpacked for build environment setup. This is basically everything that is needed to get rpm/dpkg running, i.e. glibc and the like.

Preinstall: filesystem fillup glibc

"Install" the filesystem package in the chroot environment, so rpm/dpkg can work. If you prefix a package name with a ! it will deselect a package from Preinstall: and prevent its installation.


A subset of the preinstall packages. It describes which packages need to have their postinstall scripts run.

Runscripts: aaa_base


These are the packages that make the "normal" build environment, i.e. stuff like gcc, autoconf, automake and the like.

Required: autoconf automake binutils

Install autoconf in the build environment - this is done via the normal packagemanager (rpm/dpkg).


Convenience packages, like "vim" or "strace". The difference to "Required" is that the automatic rebuild detection does not look at support packages, i.e. you don't get an automatic rebuild if "strace" is changed.

This list also includes some "-devel" packages and other subpackages of the "Required" packages to keep the Required list small. (I.e. we don't need both "zlib" and "zlib-devel" in Required because both are built from the same source).

Support: vim strace glibc-devel

To remove a support package from an inherited config (e.g. openSUSE:11.3), use

Support: !build-compare


We really need those packages. Normally, subpackages of the package that we want to build don't get installed. But even if we want to build the "patch" package, we need a working patch program to apply patches from the specfile. So we have "Keep: patch". The preinstalled packages are automatically added to this list.

Keep: gdbm glibc-devel glibc-locale


This information is used to break ambiguities.

Ignoring a package (that has an 'have choice' issue):

Prefer: -suse-build-key

Choosing a package:

Prefer: openSUSE-build-key 

This can also be done on package level:

Prefer: tomboy:gconf-sharp

For the dependency coming from binary package tomboy, choose gconf-sharp. The following example error message tells you that this comes from the binary package tomboy: have choice for gconf needed by tomboy: gconf gconf-sharp gconf-blunt; similar error messages, but without the 'needed by ...' part indicate that the issue came from your specfile instead.

This can also be done on package level in specfile via "BuildRequires" / "#!BuildIgnore":
BuildRequires: openSUSE-Build-key
#!BuildIgnore: suse-build-key

A BuildRequires: java-devel >= 1.7.0 can also trigger the have-choice-error (e.g. between java-1_7_0-openjdk-devel and java-1_7_0-ibm-devel). This can be solved with a project wide

Prefer: java-1_7_0-openjdk-devel

but cannot be solved with

Prefer: PACKAGENAME:java-1_7_0-openjdk-devel

For a package-specific solution, you must refine the BuildRequires: in the specfile itself.


Packages get renamed or are named different for different distributions. You can specify per repository dependency rewrite rules.

%if 0%{?fedora_version}
Substitute: pwdutils shadow-utils

A bare Substitutes like that will strip any version detail, so for a "Requires: libkde4-devel >= 4.4" line to translate into "Requires: kdelibs-devel >= 4.4", a trailing equals sign needs to be specified for the replacement package:

%if 0%{?suse_version}
Substitute: libkde4-devel kdelibs-devel=
%if 0%{?fedora_version}
Substitute: kdelibs-devel libkde4-devel=

On openSUSE, the package is named "libkde4-devel", so replace all requirements for "kdelibs-devel" to "libkde4-devel" — and vice versa for Fedora.

If "Substitute" is used with just a single argument, dependencies on the given package or feature are completely ignored:

Substitute: glibc-devel-32bit


This breaks dependencies for the package expansion step. Means that we don't need an installed package if another package normally needs (Requires) it.

Ignore: portmap:syslogd

We don't need an installed syslogd if we have to install the portmap package.

This is also possible on package level: by adding "#!BuildIgnore" lines to the specfile:
#!BuildIgnore: syslogd


Copy build binary package from one arch to another. This is mostly needed for packages only available on one architecture, but needed on other archs which can at least emulate the package arch.

ExportFilter: ^wine.*\.i586.rpm$ . x86_64

Copies the built wine package to the i586 and x86_64. The dot means the 'current' architecture where it was built for. By default, packages will always be copied to at least their own architecture, that is:

ExportFilter: .+ .

is implicitly in effect unless overriden by ExportFilter lines. Specifying no targets after the regex has the effect of not making files available to the worker at all, such as with:

ExportFilter: -debuginfo-.*\.rpm$  
ExportFilter: -debugsource-.*\.rpm$


Similar to ExportFilter, PublishFilter controls the copying of built packages into the repo space (e.g. /srv/obs/repos).


Some distributions might have problems during the chroot-setup when a cyclic dependency is found, eg A depends on B which depends on A. In this case the installer cannot know which to install first and manual intervention is needed. With this "Order"-Tag, you can specify an installation order.

You may see a message like:

 cycle: libgtk2.0-0 -> libgtk2.0-bin
 breaking dependency libgtk2.0-0 -> libgtk2.0-bin

If there is an error installing libgtk2.0-bin before libgtk2.0-0 then

 Order: libgtk2.0-0:libgtk2.0-bin

will cause libgtk2.0-0 to be installed before libgtk2.0-bin

Note that cycles can be longer A->B->C->D->A and you may need to say

 Order C:D A B
 Order D:A B

This says that D, A and B depend on C but it doesn't say what order A and B should be installed in. That needs another rule.

Another example:

Order: libopenssl0_9_8:openssl-certs

If openssl-certs needs to be installed, install libopenssl0_9_8 first.


Like Support: add these packages if you're "building" in a virtual machine.

VMinstall: util-linux perl-base libdb-4_5 libvolume_id1 libsepol1


Default compiler flags. (Can be overwritten by specfile.)

Optflags: i586 -march=i586 -mtune=i686 -fmessage-length=0


The BuildService sets the Release tag in spec files automatically. The format of the Release tag an be defined in the prjconf. Two magic strings are recognized:

  1. CI_CNT is the number of commits
  2. B_CNT is the number of rebuilds (when the rebuild is triggered).

The default setting is

Release: <CI_CNT>.<B_CNT>

Suppose the the rpm macro %{release_prefix} is defined in the spec file a custom format could look like this:

Release: %%{?release_prefix}.<CI_CNT>.<B_CNT>

The same syntax can also directly be used from within your spec file. To insert a hard coded release-prefix 'j123', you can say

Release: j123.<CI_CNT>.<B_CNT>


The build service ignores rpm file dependencies for performance reasons. Since this may break some packages it's possible to manually add file provides via prjconf.

Example: To make the build service believe that '/usr/bin/perl' is provided by the package 'camel' use the following line:

  FileProvides: /usr/bin/perl camel


Macros are defined at the end of the prjconf to avoid misinterpretation (or in the Macros section between the Macros tag)

Two options of Macro definitions are possible in the prjconf file:

  1. Macro definition lines starting with %define are used inside the prjconf itself and for calculating the build dependencies of spec files. They are not available inside the build root.
  2. Macro definitions after the Macros: are exported into the .rpmmacros file of the user used for building the package inside the build enviroment. Ie those are available for general use use in a spec file.

%define Tag

Use %define as usual with rpm, the user can define a variable and an associated value.
All the features provided by rpm syntax are supported except :

  • cannot define a functions.
  • No call to an external command.
%define _with_pulseaudio 1

Defines a Macro %{_with_pulseaudio} with value 1. Useful for example to enable pulseaudio in your project. In that case you need to test the value of variable in your script.


if the .spec file uses the following construct to enable conditional build:

 %bcond_with pulseaudio
 %if %{with pulseaudio}
 BuildRequires: pulseaudio-devel

then you can enable the option by putting this into prjconf:

 %_with_pulseaudio 1

To achieve the opposite, do not set this to 0. Instead:

 %_without_pulseaudio 1

WARNING: The option is enabled because the variable is defined and this independently of what ever is its value. %define _with_pulseaudio 0 does not disable the build option.

Macros after the Macros:-Tag

Macros defined in the Macros section or at the end of the prjconf are evaluated during the build process by opposition to the macros defined with %defined which are used by the OBS to calculate dependences before rpm build.


... some macros ...


in Macros sections and/or at the end of the prjconf contain a blocks macro definitions that are exported into the build environment. You can basically define anything here, including macros that are functions or call external commands since those macros are actually evaluated by rpmbuild. The define statement is not needed here, so just start with %macroname.

To stay with the simple example above, to not only tell the build service to install the pulseaudio-devel package but also have rpmbuild know to build with pulseaudio the following definition needs to be in the macro block as well:

%_with_pulseaudio 1


rpm should follow common agreed rules which does not test the value of a given variable but the existence of the variable. I advise to prefer the same value that would be created by a %bcond and the rpm command line value.
I would also add command as setting a variable to "0", "no" or "--without-xxx" would still activate the option.

# To deactivate that option comment the following line (changing variable value will have no effect) 
%_with_pulseaudio --with-pulseaudio
Currently, those macro definitions can only be added at the end of the prjconf.