Other languages Deutsch ; English ; Español ; Français |
Contents
Why packaging?
People write software. They often put it on their website and tell the users how to compile it. Later, they introduce more functionality, sometimes optional (which introduces more dependencies), and understanding how to compile it the way you like it becomes progressively harder. That's where Package Maintainers come in. In a binary distribution, we package the compiled program, sometimes split it in parts for optional functionalities, so that people just have to install the package and, assuming we've done our job correctly, it works.
Packaging isn't a simple job and the package sets the application up in a way that is acceptable to most users, often specifically for a particular GNU/Linux Distribution, which means it is always best to install packages created specifically for your distribution, if you can.
If you wish to know more about packaging and, perhaps how to package your own application, read on!
Understanding packaging
Broadly-speaking, packaging is the process of automating the compiling effort, with dependency linking and everything. Effectively, compiling an application and packaging it away along with installation scripts and other information required to install it on your system with no specialist software knowledge.
Specific jargon
In alphabetical order:
arch | processor architecture, ie: i586 (32bit) or x86_64 (64bit) |
build | the process of converting a source rpm (SRPM) package into an installable RPM package. |
buildrequires | spec file keyword to designate other packages required to build a package. e.g. gtk libraries for Gnome user programs |
dependencies | all packages required in order to build an RPM package (buildrequires), or to run an installed RPM package (requires) |
desktop file | a file format that defines menu items |
patch | a file that lists the changes to be applied to other file(s) in the SRPM, in order to fix problems or add new features |
provides | spec file keyword for functions provided by the RPM package, generally the name of another (often obsolete) RPM package. |
RPM | a package format (originally Redhat Package Manager, now RPM package manager). An RPM file contains everything needed to install a particular software. It has the suffix .rpm. |
requires | spec file keyword for other packages or functions required for an installed RPM package to function properly. |
spec | the .spec file in the SRPM contains instructions on how to build the one or more resulting RPM packages |
SRPM or src.rpm | source rpm package, which contains only sources + patches + the .spec file. It is used to generate (build) one or more installable RPM files |
suggests | spec file keyword to designate other packages that are suggested to be installed with a package |
tarball | an archive of sources. These were originally in 'tar' (tape archive) format |
upstream | the current (usually original) developers of the software you are packaging (or their website) |
What's in an RPM package?
Usually a library, and/or a program, some documentation, possibly manpages, etc...
e.g.
- /usr/lib64/libfoo.so
- /usr/bin/foo
- /usr/share/doc/foo/README
- /usr/share/man/man1/foo.1
What's in an SRPM package?
An SRPM is often a tarball, and a specfile, possibly patches, sometimes extra files (ie: desktop files or icons)
e.g.
- SPECS/foo.spec
- SOURCES/foo-2.3.5.tar.bz2
- SOURCES/foo-2.3.5-path-to-fix-specific-bug.patch
- SOURCES/foo.desktop
- SOURCES/foo.png
Quick & Dirty: How to go from SRPM to RPM
An SRPM is uncompiled source and arch independent, while RPMs are compiled binaries and mostly arch dependent.
rpmbuild --rebuild file.src.rpm
It doesn't install buildrequires, you'll need to install that manually.
Useful things to know
An RPM file looks often like this:
foo-2.3.5-2.mga1.x86_64.rpm
- name: foo
- version: 2.3.5
- release: 2
- disttag: mga
- distrelease: 1
- arch: x86_64
- extension: rpm
An SRPM file looks often like this:
foo-2.3.5-1.mga1.src.rpm
- name: foo
- version: 2.3.5
- release: 1
- disttag: mga
- distrelease: 1
- extension: src.rpm
(or you can think of it like arch == src)
A tarball from upstream often looks like this:
foo-2.3.5.tar.bz2
- name: foo
- version: 2.3.5
- extension: tar.bz2
As you can see, name and version come directly from the upstream, we do not modify this in any way. release is a number that starts at 1 and increases if we release an update within the same version.
An SRPM can produce more than one RPM
For instance, package foo-2.3.5-2.mga1.src.rpm could produce:
- foo-2.3.5-2.mga1.x86_64.rpm : a main package containing binary
- lib64foo2-2.3.5-2.mga1.x86_64.rpm : a package containing a required library
- foo-data-2.3.5-2.mga1.noarch.rpm : a package (architecture independent) that contains data files such as sample data for use with package foo
- foo-qt4-2.3.5-2.mga1.x86_64.rpm : an optional package for Qt4 (KDE) support
- foo-gtk-2.3.5-2.mga1.x86_64.rpm : an optional package for GTK (Gnome) support
- foo-devel-2.3.5-2.mga1.x86_64.rpm : a package containing items such as header files (often buildrequires of other packages could be included in this file)
- foo-debug-2.3.5-2.mga1.x86_64.rpm : an automatically generated debug package for foo
Example A: Build an environment and your first rpm
Well here's a proposal:
- just begin with an existing package on your current distribution (the latest Mageia for example).
- Let's take, for example, 'TeXworks' which is a LaTeX IDE.
From this section, you'll be able to:
- verify whether the software is already packaged
- obtain a working packaging environment
- create a package that builds
- gain some understanding of build dependencies and prerequisites (using rpm, urpmq and understanding directory structures)
- create a local environment on your current distribution to package software. The next step being getting it reviewed and submitted so that you can get access to the build-system later on
Preliminary tasks
Please follow this guide for some preliminary tasks.
Understand .rpm and src.rpm
From the application name "TeXworks" find the rpm name:
- either in rpmdrake (there's a search area)
- you should quickly find that the package name is texworks
- or using urpmq (or rpm if you've already installed it) to find packages with a similar name:
urpmq -a -y TeX
- If you find that returns a large list of packages or gives no result, try modifying the query to be a bit more precise or more comprehensive:
urpmq -a -y works
You should then be able to find the src.rpm file:
- either in rpmdrake if you have configured the src repository
- or by typing
urpmq -i texworks
into a terminal window. Using the command line is not as hard as it sounds and you can even cut-and-paste the commands in this howto to make things easier- let's assume you've found Source RPM : texworks-0.4.5-1.mga4.src.rpm
Create your packaging environment
If you are trying to rebuild a package written in c you will need to install the task-c-devel
package. If your package is written in c++ you will need to install the task-c++-devel
package. Installing these packages will cause a number of other packages to be installed.
Install the rpm-build
package:
[root@localhost ~]# urpmi rpm-build
This should pull in a bunch of dependencies, just answer "Y" and let it run.
You can also install bm
for a friendlier build manager.
Now create the directory structure:
mkdir -p ~/rpmbuild/{SRPMS,SOURCES,SPECS,tmp}
Later, when installing a source-package (.src.rpm) or building a package, some more directories will be create here like BUILD, BUILDROOT and RPM.
Understanding the directory structure
As you've got the name of the src.rpm you may download it from one of the repositories:
cd ~/rpmbuild/SRPMS wget ftp://ftp.mirrorservice.org/pub/mageia/distrib/cauldron/SRPMS/core/release/texworks-0.4.5-1.mga4.src.rpm urpmi texworks-0.4.5-1.mga4.src.rpm
Warning, it does not really install the binaries; it extracts the spec/tarball+patch into the appropriate directories.
Installing build dependencies
Most packages depend on other packages in some way. In order to compile a package you must have the necessary dependent packages installed. In most cases the dependent packages have the suffix -devel
which identifies them as the 'development' version of the package. If a required package is not installed when you (re)build the package you will see a failure message identifying the cause of the failure. In many cases this failure message will explicitly tell you which dependent package is missing, but sometimes the failure message can be quite cryptic. Fortunately it is quite easy to install all the required packages.
cd ~/rpmbuild/SPECS su urpmi texworks.spec exit
The 'su' command will make you root user, while 'urpmi packagename.spec' will install all the required dependencies for that package. The exit command returns you to your normal user.
(Re-)Build your src.rpm to create rpm for your arch
cd ~/rpmbuild/SPECS rpmbuild -ba texworks.spec
Check ~/rpmbuild/RPMS/i586 (or x86_64 depending on your arch): you will the created packages.
bm -l
will also rebuild your package if you are in its current directory.
Example B: Upgrade an existing RPM to the latest version
Finding latest version of software
Let's take the example above
- urpmq -i texworks # shows a line
URL : http://www.tug.org/texworks/
- check latest (stable) version available, website shows version 0.4.X?
Taking into account new version, building
From previous section, you already have
- a .spec
- a tarfile
- perhaps some patches (check that they are take into account upstream)
- (detail directories and content with some more explanation)
To go forward,
- just make appropriate changes (update the version number and package version in spec, replace the latest tarball in the SOURCES directory)
- and try to rebuild with latest version until no errors nor warnings are generated
- then update .spec then run
rpmbuild -ba texworks.spec
until the RPM file is created - do not forget to do a test install and make sure it works!