view Docs/manual.md @ 799:f64e3c84b3ae

text/aspell: initial import, closes #1773
author David Demelier <markand@malikania.fr>
date Thu, 15 Aug 2019 08:59:54 +0200
parents 6b4ba668a43c
children c5cbe07af6a9
line wrap: on
line source

Getting started
===============

This documentation explains how to write a package file from scratch.

Synopsis
========

Each package lives under a dedicated directory broken down into several
categories. A package consists of the following files:

- NAME.sh: a pure POSIX shell that process the build and contains some
  metadata required for installation.
- NAME.sha1: contains the checksums for individual source files (Optional).
- NAME-post.sh: a script to be executed before/after the installation
  (Optional).

In the listing above, replace NAME with the actual package name. For example the
package *zlib* contains the following files:

- compression/zlib/zlib.sh
- compression/zlib/zlib.sha1

The build script
================

The build script (NAME.sh) is a pure POSIX shell that defines various
information about the package and how to build it. To be included within the
official Vanilla Linux repository it must be licensed under the terms of the ISC
license.

Several templates are already available for most build systems in the Templates
directory.

Metadata
--------

A package requires several information to be installed, the following variables
must be present:

- PKGNAME: the package name (same as the directory).
- PKGVERSION: the package upstream version.
- PKGREVISION: the initial revision (starts at 1).
- PKGLICENSE: a space separated list of licenses (see licenses.md file).
- PKGSUMMARY: a short summary.

The following variables are optional

- PKGDEPENDS: a space separated list of packages required to build (see below). 
- PKGDOWNLOAD: a space separated list of files to download from the web, if the
  package does not need to download anything don't set it.
- PKGUIDS: a space separated list of uid to create (see below)
- PKGGIDS: a space separated list of gid to create (see below)
- PKGPROTECT: a space separated list of relative path to files to preserve on
  installation (e.g. etc/nginx/nginx.conf)
- PKGOPTIONS: a space separated list of CAPITALIZED options.

Build
-----

To build the package, you need to define a build function that install the
package into the $DESTDIR variable.

Usually, the build function does:

1. Clean the build directory in case the previous build failed.
2. Extract distribution files.
3. Process build and installs into $DESTDIR.
4. Clean up again the build directory.

Package naming
==============

The following prefixes must be used for those packages:

- py-: for python modules.
- py2-: for python modules (only for exceptional cases).
- ruby-: for native ruby modules.
- rubygem-: for rubygems modules.
- p5-: for perl 5 modules.
- hs-: for haskell modules.
- font-: for fonts (of any kind).

When a package is available with different versions (e.g. Gtk, Qt) we add the
major number as suffix to the PKGNAME to *old* versions. Example, if Qt 5 is the
current major version and Qt 4 is also shipped then, the package *qt* refers to
version 5 while *qt4* to version 4.

Handling dependencies
=====================

The variable *PKGDEPENDS* is filled up with package origins, thus you need to
write *lib/zlib* NOT *zlib*.

Also, the following selectors may be appended to the dependency to alter the
meaning:

- `:build` the dependency is only required for building,
- `:optional` the dependency is optional and not strictly required.
- `:recommended` same as optional but installed by default.

Example:

	PKGDEPENDS="dev/cmake:build graphics/qt5:recommended lib/zlib"

Protected files
===============

Configuration files (usually everything under /etc) must be marked as well in
*PKGPROTECT* variables. This prevents `vpk` for overriding user configurations.

Note: if the package ships a init script file, it must be marked as well.

Example:

	PKGPROTECT="etc/nginx.conf etc/rc.d/nginx"

In this case, `vpk` will rename the file to *etc/nginx.conf.vpk* and
*/etc/rc.d/nginx.vpk* in the archive and only be renamed if they are not present
on the disk or not manually modified.

Uids / Gids
===========

If the package requires UNIX users and groups, adapt the *PKGUIDS* and *PKGGIDS*
variables as a space separated list. You can assign a default numeric id using
the syntax `:number`.

Example:

	PKGUIDS="messagebus" # vpk will assign an id
	PKGUIDS="gdm:55"     # vpk will use 55

Warning: if you need to change file permissions, do it *ONLY* in a post install
script as users may have set different numeric id than the package defaults.

Once you need a new UID/GID, edit the file UIDS.md in this directory as well.

Options
=======

...

Example with network/wget:

	# cd network/wget
	# SSL=openssl NLS=no vpk build

Add the desired options in *PKGOPTIONS* variable and don't forget to set default
values.

Example with NLS

	PKGOPTIONS="NLS"

	: ${NLS:=yes}

	if [ "$NLS" = "yes" ]; then
		PKGDEPENDS="core/gettext $PKGDEPENDS"
		with_nls="--enable-nls"
	else
		with_nls="--disable-nls"
	fi

Then at configure step:

	./configure $with_nls

Proper handling of options is done by explicitly disabling/enabling options.
Most programs will try to enable/disable features depending on what is available
on the system thus, if the package finds a dependency and enable it you need to
adapt *PKGDEPENDS*. Always check what options are available in the package and
use their default as explicit knobs to avoid invisible dependencies.

See the file options.md for predefined options and proper naming.

Paths
=====

The package must ensure appropriate directories for installing files. This
includes:

- /etc/rc.d for service files
- /lib/pkgconfig: for .pc files
- /lib/cmake: for CMake config files
- /lib: for libraries (no lib64 suffix)
- /share/locale: for NLS files
- /share/man/man{1,2,3,4,5,6,7,8}: for man pages (in uncompressed form)
- /share/doc/PKGNAME (exact directory, no version)

Keep neutral
============

Do not make any modifications to the package. Keep it as close to upstream as
possible. Only minor tweaks are allowed including:

- adjusting pid/uid/gid in a default configuration file for easier deployment
  (but not on the original file example)
- disabling static libraries
- making sure paths are consolidated
- making sure system libraries are used rather than in-source bundles

Services
========

Services files must be installed in /etc/rc.d. You must use the following
conventions regarding messages the service will print.

The script must at least support start, stop and restart.

#### start (required)

Always add arguments with the invocation.

    Starting foo: /bin/foo -d

#### stop (required)

If the service is not running, don't write any message. Otherwise write:

    Stopping foo.

#### restart (required)

Basically, this command just calls stop and start.

    Stopping foo.
    Starting foo: /bin/foo -d

#### status

Depending on the status, write the following messages.

    foo is running with pid: 1234
    foo is not running

#### usage

If the script is invoked with invalid arguments or none, write the usage like
this through stderr and exit 1. Also keep all subcommands sorted.

    usage: foo restart|start|status|stop

If your script may support additional operations, messages and usage are up to
the maintainer discretion.

See also the template file in Templates/rc.

Libraries
=========

Do not ship static libraries and libtool files. Make sure your build script
suppress static builds if possible or delete the .a file.

Note: the C and C++ library are shipped for technical reasons though.

Post install scripts
====================

If you need to perform some custom steps after the installation of the binary
package in the target systems, you may create the NAME-post.sh script. This
script must be written also in pure POSIX shell language.

As unique argument, `vpk` will provide one of these to the post script:

- pre-install: before the extraction of the package.
- post-install: after the extraction of the package.
- pre-uninstall: before removing the package.
- post-uninstall: after the removal of the package.

Note: if the package wants to call a binary from an other package, it is usually
a good idea to check it's presence first.

Example:

	#!/bin/sh

	if [ -x /bin/gtk-update-icon-cache ]; then
		gtk-update-icon-cache -vf /share/icons/hicolor
	fi

Desktop files
=============

We usually never add .desktop files for any package that doesn't provide one by
itself. This also includes terminal based applications.

If a .desktop is provided by the package, make sure though that it is valid and
specifies the appropriate category (i.e. it does not appear in multiple menus at
once).

See [desktop entry specification][] for more information.

[desktop entry specification]: https://specifications.freedesktop.org/desktop-entry-spec/latest