The gen on slashpackage

slashpackage is an idea for package management on Unix and Linux systems that was first proposed by Daniel J. Bernstein at the turn of the 21st century. Paul Jarc took the idea and ran with it with a scheme for making everything slashpackage-packaged. For a fair while until around 2014, Laurent Bercot's softwares followed this scheme.

The concept and its implications

The concept is fairly simple:

The consequences of the design are severalfold:

You may have come across many of these ideas in different forms.

The one major problem with slashpackage was that the central authority over the outer directory tree, the package groupings and the package basenames, was to most of the world some arbitrary stranger on another continent. That could have been ameliorated, though, by simply adopting (say) the NetBSD naming hierarchy or the FreeBSD naming hierarchy. (Ironically, that would still have been arbitrary strangers on another continent. It is just that the arbitrary strangers would have seemed more authoritative, ironically in part due to their largely faceless natures. Such is human psychology.)

Internal package structure

Standard and not-so-standard components

There are various standard components to a package, in well-known locations in every package's directory tree. Some were documented by M. Bernstein on xyr WWW pages; some others can be inferred from the structure of M. Bernstein's published slashpackage-format packages.

package/

The subdirectory that holds all of the files and directories dealing with building the package and package management.

package/compile

An executable (binary or script) that builds the binary form of the package from the source form. Usually this makes use of helper executables named package/prepare, package/make, and package/makeinstall; but these are less conventional and may not exist in these forms.

package/sharing

A text file for informing a package manager which parts of the package tree are shareable across a group of (identical) machines, universally shareable across any machines, or specific to a single machine.

package/versions

A text file for informing a package manager which versions of the package name are older than this, allowing arbitrary version suffix orderings.

package/upgrade

An executable (binary or script) that makes the versionless name point to this version of the package, that must only be run after the binary form has been built.

Further inferred components are less universal.

package/run

An executable (binary or script) that enables running whatever services the package comprises. Laurent Bercot recommended against this because "it is up to the system administrator to set up the services as he sees fit, and to know exactly what steps should be taken on his system for everything to work as expected". In fact, system administrators usually rely upon packages to provide exactly such utility scripts for dealing with services, user accounts, data directories, log directories, ACLs, and suchlike.

The problem with this is actually that it isn't a very good mechanism because it is woefully incomplete. Fully-fledged package management systems provide for a whole suite of scripts that set up and tear down the various things that a package needs, not just one script that sets things up and nothing at all for doing the reverse. They generally have mechanisms, so called "maintainer scripts" in Debian terminology, comprising both "before" and "after" scripts for installation, removal, and upgrade. Or (like the old BSD pkg system) they have descriptive "manifests" that declare things like lists of directories, services, and user accounts.

package/install

An executable (binary or script) equivalent to package/compile && package/upgrade.

package/files

A manifest of the source files in the package.

package/commands

A manifest of the commands in the package.

package/README

The "read me" text file for the package.

Other components

Locations for some other well-known components, not particularly standardized but generally good ideas nonetheless, are:

source/ (or src/)

The subdirectory that holds all of the source files and directories.

build/ (or compile/)

The subdirectory used by package/compile as a work area to build the package from source.

command/ (or bin/)

An output directory where package/compile places the built executable commands.

manual/ (or man/)

An output directory where package/compile places the built manual pages.

config/

An output directory where package/compile places the built configuration files and directories.

library/ (or lib/)

An output directory where package/compile places the built statically-linked and dynamically-linked function libraries.

include/

An output directory where package/compile places the built header files for a C, C++, Objective C, or Objective C++ language API.

package/clean

An executable (binary or script) that removes the build work area but leaves the built output areas.

package/distclean

An executable (binary or script) that removes the build work area and the built output areas.

Building packages

Building with package/compile

As mentioned, building the package is the task of the package/compile program. There are various guarantees required of the build process.

Adding operating-system-specific packaging on top

Once one has built a slashpackage package natively, with package/compile, one can of course convert it into one or more native binary packages for an operating system's package manager with ease. Most package managers work with the idea that packages are built from source into an output area, staged from that output area into a staging area that represents the final file and directory layout to be packaged up, and then packaged up into packages with accompanying manifests and control information. This matches the aforementioned slashpackage build system.

package/stage

A handy idea for this is a package/stage tool. This is an executable with the responsibility of taking the slashpackage output directories and copying (or linking) the files into a staging area with the final file and directory layouts for one or more binary packages. This is work that is largely independent of the actual package managers' build tools, as like package/compile it is a step in the process that is common to most package building procedures for most operating systems' package management mechanisms. (See the Staging chapter of the FreeBSD Porters' Handbook for example, or the package function of the Arch PKGBUILD system.)

The package/stage tool is independent of the package manager, but does have to vary by operating system. It usually has to incorporate operating system differences such as the locations of directories such as /sbin and /bin and whether operating systems prefer packages to install to /usr or to /usr/local. This can be done by checking the output of the uname utility or the contents of the /etc/os-release file in the well-known and usual ways, of course.

The package/debian convention

One handy convention in this regard is the package/debian convention. Debian packaging tools have the convention of placing the staging areas, intermediate, and control files into a debian/ subtree. Of course, the process of building a package fills this tree with all sorts of intermediate stuff, that is all mixed up with the initial, static, control and data files used in the packaging process.

The package/debian convention is that package/debian/ is a read-only image for debian/, used to initially populate it much like source/ is used to initially populate build/. An initial build step is thus to do an analogous task to that of package/prepare, symbolically linking or ordinarily linking the contents of package/debian/ into debian/.

Thus the contents of package/debian/ contain the conventional Debian control files mentioned in the Debian Policy Manual and the Debian Maintainers' Guide (and hence described only very briefly here).

package/debian/rules

A Debian rules file. This makes use of package/compile for its build action, and a package/stage (or similar) command for its binary action.

package/debian/copyright

Debian-standard machine-parseable copyright information.

package/debian/control

Debian-standard package meta-information.

package/debian/changelog

Debian-standard package change log, which can (only when hard linked as debian/changelog) be manipulated with Debian's dch utility.

One way to do this is with a program named package/debian/prepare. The build procedure for a Debian package thus is package/debian/prepare && dpkg-buildpackage -uc -b and the procedure for (say) incrementing the Debian version number is package/debian/prepare && dch -i.

Another way, if one is a Debian Maintainer, is to make a debian/ directory that is (as source packaged) a symbolic link farm pointing into package/debian/ as required and package that as the packagename_version.debian.tar.gz overlay archive that accompanies the source archive.

Arch PKGBUILD

Similar ideas can be employed for, say, the Arch PKGBUILD system. The prepare function runs package/arch/prepare, equivalent to package/debian/prepare; the build function runs package/compile and package/stage; and the package function (or package_name functions) set the metadata and run pax to image the staged files and directories.

The BSDs

One can even address the FreeBSD/TrueOS packaging system with a similar package/bsd/ subtree.


© Copyright 2018 Jonathan de Boyne Pollard. "Moral" rights asserted.
Permission is hereby granted to copy and to distribute this web page in its original, unmodified form as long as its last modification datestamp is preserved.