> 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 package names 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 likely 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
- This files details build-time dependencies. Because this file doesn't
end up in the package, it's a simple list of package
names. The
depinstalled
script checks these are present, and more tooling ought to. - build_incompatible
- Similar to build_require, this file details any packages that must not
be present at build-time. One reason for using this is if configure detects
something installed that it shouldn't use, and it isn't possible to control
with some
--enable
or--disable
arguments to the configure script. Or sometimes, having something installed will break the build entirely. - 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 inarch.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 definitely 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
orpyproject.toml
, or is only available as a wheel. Thepygen
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 be prtable and 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