> Creating a package

While illumos forms the foundation for Tribblix, most of the applications come from other sources.

In some ways, building a package for a third-party piece of software is easier than building illumos, as it's generally much smaller and self contained. On the flip side, there's a lot more variety in the quality and portability of third-party software, leading to a whole set of new problems to solve.

There are some assumptions in the build process based on my personal environment, namely that lots of stuff is present under the directory /packages/localsrc/Tribblix which I have as an environment variable THOME. You'll need THOME set for much of the following to work.

Initial setup

You'll most likely need to have the develop overlay installed:

zap install-overlay develop

You'll definitely need a copy of the build repo, which contains the existing packages and helper scripts.

cd $THOME
git clone https://github.com/tribblix/build

Naming

Naming is naturally one of the hardest problems in computing. Tribblix uses SVR4 packaging, so native packages start with the string TRIB (it's not a stock ticker, but Tribblix doesn't have a stock ticker anyway).

Standalone packages tend to simply take the name of the software and put it together with the prefix. So the foo software would be in the TRIBfoo package.

There are special conventions for modules for runtimes, such as perl and python. In the case of perl, the prefix is TRIBlib-perl-5- with the module name added on, dash-separated. In the case of python modules, the bar module would be TRIBbar-python-XX, where XX is the python version. (For these runtime modules, though, there are pygen and perlgen scripts that will do most of the work for you.)

Some packages have names that look unusual. These tend to be historical - usually there was a prior version of the package (perhaps sourced from elsewhere) and I've kept the package name unchanged to ensure that updates run smoothly.

Structure

Once you have a package name, then create a directory with that name in the build repo and start to populate it. There are a number of files you may need to create.

alias
The alias file is a list of other names this package is known by. This is the friendly name - so that a user can type zap install foo. If it's unlikely that the package will never be added manually (and remember that the intention is that overlays are the primary form of software management) then you don't need an alias. Sometimes you'll have different versions of a package, in which case there will be an alias with the version number, and an unversioned alias for the default or preferred version. (In that case, try and make sure that the default alias matches up with the version that would be installed via any overlays).
depend
This file is an SVR4 depend file, so it's a list of other packages this package depends on at runtime, one to a line, with a leading P to show it's a prerequisite. Package construction will attempt to divine runtime dependencies from shared objects, but that isn't always reliable. But if the package build tells you the actual dependencies differ from what was expected, it's time to take a closer look.
build_require/build_incompatible
These files detail build-time dependencies. Because they don't end up in the package, they're simple lists of package names. The depinstalled script checks against these, and more tooling ought to.
pkginfo
This is the key fragment of an SVR4 pkginfo file. It must contain entries for PKG, NAME, and VERSION. If possible, it ought to contain a ZAP_URL entry, which is where the package comes from.
pkginfo.arch/arch.txt
Normally, when you build a package it will embed the architecture of the build host into the package. If you want to build one package that will install on multiple architectures (for example, groovy is cross-platform), list the architectures in pkginfo.arch. If you know the package won't ever work on multiple architectures (for example, go isn't supported on sparc) then put the working architecture in arch.txt - this won't affect the build, but there are tools that look to see whether a package ought to be built or not.
build.sh
This is the main build script. Sometimes it really is a shell script, but it's also a simple record of the commands you would type. There are standard forms for the most common types of build. Note that it's also intended that the contents of the build.sh script can be run by hand, one at a time, for debugging in case of problems, so that use of advanced or shell-specific constructs should be avoided.
fixinstall
This is run after install, in the source directory. So if a simple make install doesn't quite work, you can fix it up here. Note that for 64-bit builds, fixinstall.64 is used instead.
fixit
This is a script run after install, in the temporary install directory. This is where you can delete any things that shouldn't be present, or move things around if they got put in the wrong place. There are a standard set of fixit rules for common issues (for example, we don't ship info files, static libraries, or libtool archives by default).

Canned helpers

There are a number of canned helper scripts.

dobuild
This is the main driver script. It assumes the common configure/make/make install workflow, and has a fair few options.
cmbuild
This is a variant of dobuild for software that uses CMake.
mesonbuild
This is a variant of dobuild for software that uses meson.
imakebuild
This is a variant of dobuild for software that uses legacy imake.
unpack
A convenient way to unpack a source tarball; it understands a variety of compression schemes and archive formats. Will also apply any patches (see below).
genpkg
Having built the software, this script will install it to a temporary location and build a package. It's the partner to dobuild et al.
create_pkg
This is a subset of genpkg, that assumes you've created a simple staging area yourself (if, for instance, a vanilla make install doesn't do the right thing).
pkg_tarball
In some cases, all you want is a downloaded archive converted into an installable package. This is a script to do just that.
pkg_setup_py/pkg_pep518/pkg_wheel
These know how to create a python package that uses setup.py or pyproject.toml, or is only available as a wheel. The pygen script will create a valid build.sh script that calls these, so for a python module usually the only thing you have to do is get the depend file right.

Patches

Well written software should build unchanged. But it's often necessary to apply patches. These go in the patches directory. Then you need a .pls (patch list) file, that lists the patches on individual lines with the strip prefix prepended (it's usually -p1). The name of the .pls files is the root name of the archive being built with .pls appended, so if there is one it will need to be renamed if a new version is being built. Look at some of the existing .pls files for examples. The patches will be applied by the unpack script, so you can run that by hand to see that the patches apply correctly.

It's sometimes necessary to run commands as part of the build. For this purpose there are .preconf and .postconf scripts, named after the archive the same way as the patch lists. These can do anything, and are respectively run before and after the configuration step of the build. For example, for dobuild the .preconf script will run before ./configure and the .postconf script will be run after ./configure. (There's one sufficiently common case, of running autogen.sh before ./configure, perhaps to create it, that dobuild has a -A flag to avoid needing to create an extra script.)

Obtaining the source

The build system assumes that the source tarballs have already been downloaded. They need to end up in the directory ${THOME}/tarballs.

This is a weakness, in that it normally requires manual intervention by the user to find and download a source archive.

In the build repo there's a file checksums.txt which contains the sha256 checksums of source archives. When building from a new source, the checksum will be added to the end of the file. If there's an independent record of what the checksum is, you can manually verify that what you've just used matches. And if you build something that's been built before and the checksum doesn't match, the build will fail.

Running a build

To run a build, you can simply run the build script:

${THOME}/build.TRIBfoo/build.sh

If successful, a fully populated package will end up in the /tmp/pct directory.

You can install the package (as root) to test it:

cd /tmp/pct
zap d TRIBfoo
pkgadd -d TRIBfoo.x.y.z.pkg

Index | Previous Section | Next Section


tribblix@gmail.com :: GitHub :: Privacy