Dragora GNU/Linux-Libre

Introduction

To create a package we need to understand "What's a package?", besides the basic needed skills in a Unix-like system: managing and editing files, directories, permissions, the concept of source code, compilation process, etc. Some of the mentioned skills won't be explained and we'll assume that the user is already familiar with them.

Questions

Below, there will be a series of questions and answers. There also will be some explanations and things to take into account.

Source code or binary?

The source code is a collection of instructions given by programmers through a computer language that can be read and written by people. Computers are capable of understanding this code or list of instructions if it is "interpreted", so they can use it directly. The way to interpret code by computers is to translate or "compile" the source code into a "binary" they can understand.

What is a package?

It is a piece of software that gets packed, distributed and it is then ready to be used. Usually software is packaged in binary form, distributed in a specific format according to the operating system or the GNU/Linux distribution.

In Dragora GNU/Linux-Libre the format of the packages is a simple tar archive compressed with lzip. Just a standard, portable compressed archive (according to the usage tools).

Why use or create a package?

Simply, because it allows easier distribution. It allows the tools of the package manager to install, uninstall and upgrade as well as keep track of what files are in the system.

Let's get to it!

Let's suppose we have downloaded the sources of the application "foo" and we would like to create the package (after compiling, of course). To do that, we decompress the source:

# tar xvf foo-1.2.3.tar.gz

We enter the directory of the decompressed source so we can later configure and install it:

# cd foo-1.2.3

It is necessary to fix or correct the permissions of the files, group and sub-directories for our package, since many sources come with different owner, group and permissions:

# chown -R 0:0 .
# chmod -R u+w,go-w,a+rX-s .

Configuring the sources

Now we shall use the configure application of the source to prepare and configure the package according to our needs.

We need to clarify that configure may have many flags that are beyond the scope of this guide. The idea is to point out the more common flags:

--prefix=/usr

This flag tells configure in which directory we want to install the program, usually in /usr.

--sysconfdir=/etc

This flag tells configure in which directory we want to put the configuration files of the program, traditionally /etc.

--infodir=/usr/info

With this flag we configure where we want to install the info documents.

--mandir=/usr/man

With this flag we configure where we want to install the manuals.

For a detailed description of the options we can type:

# ./configure --help

In the end, we have something like this:

# ./configure --prefix=/usr --sysconfdir=/etc --infodir=/usr/info --mandir=/usr/man

Building the source

The next step is building / compiling the program itself with make(1):

# make

The next step is installing the binary program(s) generated by make.

By tradition, that is accomplished by make install, but that would install the files on the root of the file system, making it impossible to create the package. Instead, what we do is fake the path and install on a different directory that we shall create for this:

Package's temporary directory:

# mkdir -p /tmp/sources/package-foo

Now we install the application:

# make install DESTDIR=/tmp/sources/package-foo

Enter the directory and list the files to see the resulting structure:

# cd /tmp/sources/package-foo
# ls -l

Aditional steps

Removing debugging information in binaries:

Removing this information might be useful because we would obtain a leaner binary. Identify in which directories are the binaries.

The strip command is going to help us with this:

# strip --strip-unneeded usr/bin/* usr/lib/*.so*

A variation by Matias A. Fonzo that uses scalable awk and combines find, file, cut, and strip for scan files removing debugging symbols, from programs and libraries:

# find . -type f | xargs file | awk '/ELF/ && /executable/ || /shared object/' | \
   cut -f 1 -d : | xargs strip --strip-unneeded

GNU information documents:

We remove a redundancy:

# rm -f usr/info/dir

We compress with the best compression method (-9), maintaining the original date and time:

# gzip -9N usr/info/*

Man pages:

# gzip -9N usr/man/*/*.?

The info documents and the man pages are only a part of the documentation of the program. It is important to identify and include the rest of the documentation:

Creating the directory to copy the documents to

# mkdir -p usr/doc/foo-1.2.3

We enter the directory and we decompress the source to copy the documents to the directory of the future package:

# cp -a AUTHORS COPYING README TODO FAQ /tmp/sources/package-foo/usr/doc/foo-1.2.3

The description file:

By default Dragora provides two description files: en and es. Each prefix corresponds to a language, in this case: English / Spanish.

The next step is create the "description" directory where the description file will be saved:

# cd /tmp/sources/package-foo
# mkdir description

Using a text editor, we create the file that will contain the description of the program. For example, for the English description:

# moe description/en

The file is composed as:

	program_name - Brief description.

	Description.
	<new line>

An example looks like:

	udev - Dynamic device management.

	Udev is the device manager for the Linux 2.6 kernel series.
	Its primary function is managing device nodes in /dev.

	It is the successor of devfs and hotplug, which means that
	it handles the /dev directory and all user space actions
	when adding/removing devices, including firmware load.

Building the package

From within the temporary directory of the package we type:

# makepkg -l /tmp/foo-1.2.3-i486-1.tlz

Package naming scheme

Let's analyze how to name a package:

name-version-architecture-build.extension
Section Description
name The application's name
version The version of the program
architecture The architecture of the program. It might not be required to specify it, in which case it is noarch.
build It represents the build number. If in the future you modify the package adding any significant change then you increment the build number
extension Extension supported by makepkg.

Try to keep the name lower-case.

Summary of the steps

1. tar xvf foo-1.2.3.tar.gz
2. cd foo-1.2.3
3. chown -R 0:0 .
4. chmod -R u+w,go-w,a+rX-s .
5. ./configure --prefix=/usr --sysconfdir=/etc --infodir=/usr/info --mandir=/usr/man
6. make
7. mkdir -p /tmp/sources/package-foo
8. make install DESTDIR=/tmp/sources/package-foo
9. cd /tmp/sources/package-foo
10. ls -l
11. strip --strip-unneeded usr/bin/* usr/lib/*.so*
12. rm -f usr/info/dir
13. gzip -9N usr/info/*
14. gzip -9N usr/man/*/*.?
15. mkdir -p usr/doc/foo-1.2.3
16. cd /directory-where-source-was-decompressed/foo-1.2.3
17. cp -a AUTHORS COPYING README TODO FAQ /tmp/sources/package-foo/usr/doc/foo-1.2.3
18. cd /tmp/sources/package-foo
19. mkdir description
20. moe description/en
21. makepkg -l /tmp/foo-1.2.3-i486-1.tlz

Final notes

It is worth noting that the flags explained here and the steps followed in this guide are a general explanation and they may or may not be present. It would depend on the sources you are dealing with since some do not have info files or man pages or configuration files, etc. Thus, it is the decision of the user how to handle those things.