Building RPM packages for Linux distributions 3/4: Platform-dependent package

Building RPM packages for Linux distributions 3/4: Platform-dependent package

Packaging platform-dependent (e.g. C/C++) software from source

In the natural paradigm

RPM build is initially mainly oriented towards C/C++ toolkit. Therefore the structure of a SPEC file is oriented around the following concepts:

  1. %prep macro: prepare the RPM_BUILD_DIR folder by extracting the sources archive(s) and adapting the filesystem layout.
  2. %build usually configuring the build (using configure or automake for example) and making the build (using make with various options) in RPM_BUILD_DIR
  3. %install installing the product (using make install) in the RPM_BUILD_ROOT

SPEC files already provide handy macros in order to make this kind of build very simple.

If you can build some software using a “configure, make, make install” flow (or equivalent), it will naturally fit in an RPM Spec file.

%prep section

In this section, one should just prepare for the %build and %install sections.
This usually is just about creating folder structure in the RPM_BUILD_DIR folder, and extracting the archives and putting files in the right place.

In addition to extracting original package’s sources, it is possible to apply patches to sources before build is done.

Patches are declared through specific Patchn (where n is an incremented number) next to the Sourcen tags. These patches can be public hot fixes for the original software, or distribution-specific patches. For example, Enterprise Linux distributions patch software based on specific security alerts/fixes, even for older less actively maintained releases when they’re in the scope of their support. This is one of their selling points.

Work in this section must be done in the $RPM_BUILD_DIR folder.

There are multiple helpers in order to help prepare this build folder.

For example the %setup macro

will expand in the %prep section to something like (this is merely an example and will depend on the version of rpmbuild you use):

Note that cdplayer and 1.0 are directly taken from the Name and Version tags.

For rpmbuild > 4.11, the %autosetup macro is also available and allows applying patches to the sources automatically (in the ascending order) at the same time:

%build section

This section should run any kind of available build tool.

For a platform-dependent build, it usually means we’re going to use autoconf/configure and make.

The configure helper macro runs autoconf configure script with platform specific directory structure (–prefix, –libdir etc) and compiler flags such as CFLAGS.

Work in this section must also be done in the $RPM_BUILD_DIR folder.

You may also use the _smp_mflags variable for make if available, in order to make full use of available processors to speed up the build.

For example:

If you want the target software to be installed in different paths, invoke configure directly with different parameters for the directory structure.

%install section

In this section files resulting from the build are going to be installed in the RPM_BUILD_ROOT.
The build root ($RPM_BUILD_ROOT or %{buildroot}) mimics the target file system structure from its root level.
If a file is copied in $RPM_BUILD_ROOT/opt/agilepartner/ it is therefore meant to be installed in /opt/agilepartner/ in the target system.

Work in this section must also be done in the $RPM_BUILD_ROOT folder.

For a platform-dependent build, this classically involves invoking make install with various options.

For example:

Specific configuration gotchas for repackaged software

All the macros which ease the work consider that the following elements match:

  • the name of the packaged software
  • the folder the sources archive are extracted into
  • the target package name

If for some reason you want to change the name of the target package, you need to tweak things a little bit.

As mentioned before, the expanded macros (%setup, %configure) are going to look for paths matching the package name and version.

So if you expand e.g. cdplayer-1.0.tar.gz to cdplayer-1.0/ and you want your target package to be named mycdplayer, you’ll need to move the folder after the macro’s execution, or remove the macro altogether and do the extraction yourself in the spec file.

Usually, if macros don’t work for you OOTB, it is best not relying on them at all, as what they expand to is likely to change in future versions of rpmbuild and affect your build’s stability.

To sum it up: whether you embrace the underlying standard and use the helper macros, or you don’t and you should get the work done without them.

Wrapping up:

In the previous blog entries, we saw:

  1. An introduction to RPM packaging.
  2. how to package a platform-independent software, (e.g. Java or Python-based) and specific gotchas

In the next blog entry, we’ll see:

  1. how to create a SPEC file which produces multiple different packages (and why it is useful)
Pierre-Antoine Grégoire
No Comments

Post a Comment