Building multiple packages with RPM


In my previous blog post, I described how to build a basic RPM package. This article picks up where we left off, by showing how to create multiple packages using one spec file – which allows us to split a program into multiple packages – and how to handle potential conflicts.

If you're wondering as to why one would want to split a program into different packages, there are a couple factors to consider:

Now that we've listed some possible reasons for splitting a package, let's get to work.

Defining subpackages

To define a subpackage, we need to use the %package macro. It takes a single argument, which is the name of the subpackage we want to create. This will get appended to the main package name, in a main-sub format. Should we want to override this, we can use the %package -n fullname form. Probably the most common use case for this is Python packaging, where it's usual to see %package -n python2-blah, followed by %package -n python3-blah.

%package data Summary: Data files for %{name} BuildArch: noarch

Traditionally, after defining a subpackage, we write any tags that we want to specify. The version and release number, together with the licence, are inherited from the main package, so we don't need to repeat them if they're the same. The only tag that is required to be present for each subpackage is the Summary: tag, but if we want, we can provide separate architecture settings, dependencies, provides, and others.

You may be wondering about the BuildArch: tag. The way it's used in the example above is probably the most common – being used to mark a package as noarch, which means no architecture, or putting it differently – architecture-independent. As stated before, this can be used to package non-executable resources like game assets, but is also used for packaging programs written in interpreted languages – like shell, Perl, Python, or PHP.

Apart from the summary, we also need to provide the description and list of files to be used by our subpackage.

%desciption data Data files (graphics, music, sounds, et cetera) required to play %{name}.   %build make   %install make install DESTDIR=%{buildroot}   %files %{_bindir}/%{name}   %files data %{_datadir}/%{name}

An important thing to note is that the only sections that should be repeated for each subpackage are the desciption and the list of files. The %prep, %build, %install and %check sections can appear only once, which means that we cannot have separate build / install scripts for each of the subpackages and must do it all in one go. Of course, if need be, we can just use comments to say "we finished installing main package files, now copying -data".

Handling conflicting files

There may be times where your packages will conflict with each other by providing a different version of the same file. An example might be an application compiled using different GUI widget kits, that's built in a way which makes allowing the two (or more) versions to co-exist difficult. To solve duplicate file conflicts, we can use the postfixes removal feature.

%package gtk3 RemovePathPostfixes: .gtk3   %package qt RemovePathPostfixes: .qt   %files gtk3 %{_bindir}/%{name}.gtk3   %files qt5 %{_bindir}/%{name}.qt5

As demonstrated by the example above, we need to specify the RemovePathPostfixes: tag; its value should be a list of space-separated postfixes to remove from files during packaging. Though you can use any string as the postfix, it's common to begin these with a dot or a hyphen.

Omitting the main package

One issue that may come up in specific circumstances is that you may not want to build the main package – say, when you're building python2-mylibrary and python3-mylibrary, it probably won't make sense to have a mylibrary package. If you want to omit the main package, just leave its %files section empty – but don't remove it! Otherwise, rpmbuild will complain that the section is missing.


Share with friends

e-mail Google+ Hacker News LinkedIn Reddit Tumblr VKontakte Wykop Xing


Do you have some interesting thoughts to share? You can comment by sending an e-mail to