Solaris SVr4 packaging tools and recipes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Go to file
Patrick Georgi 0f265d8bd6
new package: mpc
9 years ago
archivers update package: star 15 years ago
batches gnustep/gcc, batches/gnustep, gnustep/gmp, gnustep/mpfr: update gnustep gcc. add gmp and mpfr to the gnustep batch 9 years ago
desktop screen: update filename in patch 9 years ago
devel update git 9 years ago
editors/vim vim: apply patches 7.0.209-7.0.224 16 years ago
emulator update package: scummvm 9 years ago
games lbreakout2: enable NLS, store data in /var/opt/$PREFIX instead of /opt/$PREFIX/var as per standard 16 years ago
gnustep update packages: gworkspace 9 years ago
graphics djvu: compileflag to avoid compiler tripping over assert 16 years ago
lang add tcl 8.6.1 9 years ago
library new package: mpc 9 years ago
multimedia update package: squeak 9 years ago
network new package: libdnet 9 years ago
security add daq 9 years ago
share Default to gcc 9 years ago
system update package: worker 16 years ago
textproc update package: mftrace 16 years ago
www update package: php5 9 years ago
.gitignore ignore files in git, not monotone 9 years ago
INSTALL name change 16 years ago
LICENSE add license text 18 years ago
README update documentation 16 years ago
TODO update TODO 9 years ago
USAGE update documentation 16 years ago update makedist script 16 years ago


0 Introduction

pmpkg is a tool to create Solaris packages (in SysV/.pkg format) from sources
it downloads, configures and builds according to instructions in a simple
text format.

This document covers six topics: First it will enumerate and detail security
issues that might come up when using pmpkg, but be aware that this list
might not be complete, though it will contain everything the author is
aware of.

The second section covers the directory structure of the pmpkg tree.

In the third section you will find a description of the work flow inside pmpkg.

After that comes a description of the simple text format mentioned above to
direct pmpkg to build packages.

The fifth section explains the various additional files that can be used to
tweak pmpkg's behaviour.

Finally, the sixth section describes various convenience routines that
automatically manage issues in packaging.

For a short intro on the pmpkg command line, see USAGE

I Security Considerations of using pmpkg
1. su/sudo execution
some parts of package building must be run as root to ensure that the
build completes successfully. this unfortunately includes the build
process itself, which is run by scripts that were downloaded from the
internet, usually from untrusted sources.
parts of pmpkg that run as privileged user:
- build: the build process itself is run as root to ensure that it
runs properly and that file attributes are kept correctly.
- package: pkgchk needs to lock a database, and several operations on
the install tree require privileges, as the build stage possibly
writes files and directories that are accessible by root only.
- install/uninstall: as they're just wrappers around pkgadd and pkgrm,
they have to run with the privileges they need.
- clean: to get rid of all files created on build
a long term goal could be to wrap the build in some LD_PRELOAD magic to
store file attributes (which are the biggest issue why I chose to let
the build run as root) in a format suitable for later merging with the
pkgmap file.
2. the usual "no warranty" for external code
I don't audit all the code that pmpkg downloads, runs and builds. there
were some nasty experiences in the debian environment where an upstream
maintainer customized the tarball to hide malicious "features" from the
package maintainer so debian would deliver those "features" to the users.
2b.of course, no warranty for pmpkg itself, either (see license)
3. pmpkg doesn't check the sources against any kind of trust value (eg. hash)

with that out of the way, let's take a look at the format and the
supporting files...

II directory tree layout
The pmpkg tree is relocatable, so you can uncompress and use it where ever
you want. However, the structure of the tree is less flexible.
pmpkg assumes a two-level hierarchy for packages, where the first level is
usually some broad categorization (eg. "devel") and the second level is
the package name itself. Inside that directory the file and supporting
scripts and other files are kept.
Additionally there is a directory "pkgs" which contains the built packages
and an index file for fast lookup of dependencies. The filename of the index
files and packages are chosen so that different architectures can coexist
within a single pmpkg directory.
Finally you will find a directory named "downloads" which contains all
sources and other files requested to be downloaded for package building.
downloads is a cache, so you can prune it whenever you feel like it, pmpkg
will refetch the files the next time it needs them.

In every package directory must be a file which provides fundamental
information on how to build the package. While building, pmpkg will create
pkg, install and work subdirectories that are temporary and will be cleaned
up on request (pmpkg clean).
A files subdirectory usually contains alternative build routines and other
data to influence the build process.

III How pmpkg creates packages
1. Fetch all requested source files ("fetch" stage)
2. Unpack the main sources ("unpack" stage)
3. Apply all included patches ("patch" stage)
4. Configure the tree ("configure" stage)
5. Build the tree, then install into a staging area ("build" stage)
6. Create a package from the data in the staging area ("package" stage)

You can run each single stage with "pmpkg $stagename" but they might fail
if the preceeding stages weren't run. After a successful run of a stage
a "work/stamp-$stagename" file is created for "unpack" and later stages
to allow resuming after stopping the build (because of a failure, or
user interruption).

fetch, unpack, patch, package have fixed behaviour that can't be overridden.
For configure and build there's default behaviour which should make
building autotools-style sources very easy. These default behaviours can
be changed in some aspects with parameters in or replaced entirely
by custom scripting. (see IV and V)

IV the format
the file gets shell-included by pmpkg, so any expression that's legal
for /bin/sh is legal for but beware: this is an implementation detail
and I am not too eager to keep it, so this behaviour could disappear at any

1. Variables
pmpkg is mostly driven by variables inside the file which are
listed here. If you want to pass values with spaces, don't forget to wrap
the value in "" or '' like you would with shell.

PKG (mandantory) the package name without the PM prefix
DESCR (mandantory) a description text for the package
VERSION (mandantory) the version of the package
DLPATH (mandantory) the server directory to use for downloading sources
MAINTAINER (mandantory) "NAME <EMAIL>" formatted ID of the package maintainer

these 5 variables are mandantory, as they will end up in the package's
metadata. Also they implicitely define the full URL where pmpkg attempts to
find the sources (${DLPATH}/${PKG}-${VERSION}.tar.gz), the root directory
name within the package (${PKG}-${VERSION}), the package's name and the
filename of the package file.

In case the sources file's name does not match ${PKG}-${VERSION}.tar.gz
you can use SOURCEBASE to override the default. pmpkg automatically
discovers the file type if it's either gzipped tar, bzip2'd tar or
redhat's rpm.

If the root directory in the sources file doesn't match
${PKG}-${VERSION}, use SOURCEDIR to change the default.

defines which type of build system is used. By default, an "autotools"
configuration is chosen, which means configure && gmake && gmake install
(with appropriate flags). This default is implicitely overriden by
the presence of an executable file "files/", whose usage
is explained below.
currently supported values are:
- autotools: (see above)
- confbuild: (see above)
- python-setup: python packages that use

more files that have to be downloaded for the build. these must be
given as space separated list and consist of full URLs to the files
which will end up in the downloads directory for further use by a
customized build script

This variable can contain options to the configure script. by
default, only --prefix is given, to which this variable can add
more options. No effect if a script exists.

some configure scripts require a different shell than given in their
#! line. use this variable to define which shell should be used to
run the configure script.

While most build systems follow the de-facto standard of autotools,
some use different names for the DESTDIR functionality, which prefixes
file names on install with a given path. When changing DESTDIRNAME,
you instruct pmpkg to not do "gmake install DESTDIR=/foo", but
use the value of $DESTDIRNAME instead of DESTDIR

Some install routines don't provide a way to prefix install paths.
To work around this, it might be possible to set the overall prefix
(which usually defaults to /usr or /usr/local or sth. like that) on
install time. In this case, that prefix must consist of the DESTDIR
and the normal directory prefix. Setting DESTDIRINCLROOT to any value
tells pmpkg to do so. Usually used with DESTDIRNAME to change the
prefix variable instead of an unused DESTDIR variable.

This option is useful to manually tweak the suffix in the DESTDIR path.
It overrides DESTDIRINCLROOT and contains the root directory of the
installed tree in the final directory hierarchy.

pmpkg does its own discovery of dependencies. For this to work, it
needs a list of locations where to look for dynamic libraries. Use
this if pmpkg missed a dependency to a library because of weird paths.

Only used for documentation. can indicate that a package builds but
doesn't work right yet in some circumstances, and why.
To be used by aggregators (I think they're called mash-ups these days)
that want to provide package listings and the like.

the following variables are exported into the build environment and can be
changed in




V Additional configuration files
If pmpkg finds a files/ executable within the package directory,
it replaces its default actions for configure and build with this script.
The script is passed various environment variables, most notably TARGET
and PKGINSTROOT which define the install location of the package (/opt/PM
by default) and the location of the staging area for the package process.
pmpkg also passes the stage (configure or build) as first argument on the
command line.
The script is run in the root directory of the uncompressed sources.

2. patch-*
the patch stage applies all patches in files/ that match patch-* in
alphanumerical order. Per convention they're named patch-$YYYYMMDD-$NUM-$DESCR
with NUM being some way to order patches of the same day and DESCR giving a
hint about the purpose of the patch.

If this file exists in files/ and is executable, it's run by pmpkg at the end
of the build stage, which by default already runs gmake install. This file is
suitable for post-install fixups of the tree (deleting unwanted files, moving
stuff around, copying additional files from the pmpkg tree into the staging
area). It's run from within files/ and gets PKGINSTROOT and TARGET in the

4. deliveries/
Any file in files/deliveries gets copied into the package's root directory.
Of special importance are files called postinstall, postremove, preinstall,
or preremove, as these are run on package install/remove time.

5. depends
If files/depends exists, pmpkg assumes that every line is a SysV package name
without any further information (eg. description text) and add these to the
dependency list.

6. type-e-files
Files listed in files/type-e-files are changed to type e, class build - ie.
they're run on install time as a shell script.

7. digest
digest contains a list of source files with their associated SHA256 hashes.
If the file in downloads/ matches the given value, no download is attempted.
If the downloaded file doesn't match the digest, pmpkg doesn't exit at this
time, so it's no security facility!

Use "pmpkg digest" command to create a list of all hashes of the current
package after you downloaded the files. Its output can be piped directly
into the digest file.

VI Special cases in pmpkg
1. GNU info directory
GNU info has the misfeature of a "dir" file in every info/ dir. pmpkg
automatically replaces it with a script that rebuilds that file on
runtime, and adds the necessary dependencies to handle that case.
2. post/pre-install/remove scripts
pmpkg automatically adds the necessary pointers to those files if they
3. dependencies
pmpkg parses all executable files for #! lines or library dependencies
(ldd output) and resolves that to package names to add to the
dependency list.
4. gnome application menu
many sources install the gnome menu entries into the same location as the
application, pmpkg moves these files into the /usr/share/ hierarchy where
gnome-on-solaris is actually looking for them.
5. new directories
directory permissions inside packages are inherited from their original
directories in /opt/PM/* and where these don't exist yet, defaults to
0755 root:bin permissions and ownership.
6. symlinks
some install routines add symlinks in a way that they include the whole
path. where possible, symlinks are shortened as much as possible, usually
leading to symlinks that stay completely inside the package's directory tree
7. libintl alias files
libintl creates some alias files that generally contain the same data.
pmpkg marks them volatile, so that multiple packages can control their