How to make a Solaris package, alternate method

This page assumes you want to package up an existing clump of software, that has a somewhat complex install tree. If you are starting out with a smaller package, you may prefer my original pkg instructions.

Here's the mindeless proceedure to make a larger job easier.

  1. Decide what the instance name of the pkg will be. 8-letter max, like 'GNUyacc'

  2. Get the package to install other than its normal path. This makes generating the list of files and permissions a lot easier.

    For well-written software, you can look in the Makefile for something like DESTDIR, or INSTALL_DIR, etc. Once you find the magic var, you can usually do "make DESTDIR=/tmp/pkg-staging install"

  3. Generate a "prototype" file based on the 'staging directory' tree. The "easy" way, is to use pkgproto, with
    (echo 'i pkginfo'; pkgproto /tmp/pkg-staging=/ ) >prototype

  4. Make a "pkginfo" file with the following info
     PKG=$PKGNAME
     NAME=purpose of package (255 chars max, ideally less than 40)
     VERSION=X.y.z
     CATEGORY=(normally either 'system' or 'application')
    
    Optional additional entries:
      DESC=extra info beyond NAME (255 chars max)
      ARCH=i386 or sparc. Gets automatically filled to current arch otherwise.
      VENDOR=http://where.you.got.it
      EMAIL=maybe your email address?
    
  5. pkgmk -o # -o is for 'overwrite and prior attempts'

    This looks at pkginfo and prototype in current directory, and then 'spools' all files mentioned into a directory based package, in /var/spool/pkg/$PKGNAME

  6. pkgtrans -s /var/spool/pkg /tmp/$PKGNAME.pkg $PKGNAME

You now have a file /tmp/$PKGNAME.pkg suitable for use with
pkgadd -d $PKGNAME.pkg
in Solaris.

Dont forget to clean up;
rm -r /var/spool/pkg/$PKGNAME /tmp/pkg-staging

Alternative prototype file generation

If the package wont let you use "make DESTDIR=xxx", then you can still generate a prototype file fairly easily, with the following steps:
# (As root!)
touch /tmp/proto.timestamp
echo 'i pkginfo' >prototype
sleep 5  #(paranoia about making the timestamp clear to the system)
make ginstall
# Then, assuming you are installing to /usr/local
find /usr/local -newer /tmp/proto.timestamp |pkgproto >> prototype
The only gotcha with this method is that you have to be 100% sure it doesnt install stuff to any other funny location, or you'll miss stuff in your package.


Package dependencies

If you want to make this package dependant on another package, you have to add a "depend" file into the mix. "man depend" will tell you the format of it. You then have to add an entry to your prototype file, before running pkgtrans, along the lines of
i depend
or
i depend=/current/path/to/dependfile


Relocatable Packages

Lets say the application normally installs in /usr/local, but you'd like the package installer to be able to choose another base to install to, like /opt/local. You can allow that by making the prototype file generate relative paths, instead of absolute ones.

Step 3, above, then becomes,

    (echo 'i pkginfo'; pkgproto /tmp/pkg-staging/usr/local= ) >prototype

pkgadd will now always ask the user where they want the 'package base directory' to be.
If you wish to provide a default, add a line to pkginfo before running pkgmk:

  BASEDIR=/usr/local


Written by: Philip Brown
Solaris Top