How to make a Solaris package (pkg format)

There are now various other guides to make Solaris packages out there. But here's the simplest one I know, cause I wrote it to be that way :-)

This assumes you are kind of starting out early in your package. On the other hand, if you want to pkg up a larger preexisting package, you probably want to look at larger package building.

The advantage to the method in this page, is that it avoids doing an extra "make install" step. Additionally, you do not have to be root to build it, because you specify the owner and file permissions by hand in the "prototype" rather than "make install" needing to be root to do chown, etc.

Put the following in a Makefile, and replace "BOLTpget", with the name of YOUR package, and any other appropriate substitutions

PKG=BOLTpget
#possible ARCH values are i386, sparc, all
ARCH=all
PKGFILE=$(PKG)-$(ARCH).pkg

pkg:
        pkgmk -o -d /tmp -a $(ARCH)
        touch $(PKGFILE)
        pkgtrans -s /tmp $(PKGFILE) $(PKG) 
        rm -r /tmp/$(PKG)
        @echo check current directory for .pkg files

Remember, those big spaces at the start of lines represent a TAB!

Then, create two files in the current directory: pkginfo, and prototype.
Here are some examples for you. First is 'pkginfo'

CLASSES=none
BASEDIR=/usr/local
TZ=PST
PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin
PKG=BOLTpget
NAME=pkg-get
VERSION=1.0
CATEGORY=system
DESC=A convinient way to automate package install from sunfreeware.com
VENDOR=Philip Brown, Bolthole Software
EMAIL=phil@bolthole.com
PKGSAV=/var/sadm/pkg/BOLTpget/save

Next is the 'prototype' file.

i pkginfo
!default 0755 root bin
d none bin ? ? ?
f none bin/pkg-get=pkg-get
d none share ? ? ?
d none share/man ? ? ?
d none share/man/man1m ? ? ?
f none share/man/man1m/pkg-get.1m=pkg-get.1m

d means "directory"
i means "information"
f means "file"
The idea for the "file" entry being that you put where you want the file to go on the left of the '=' sign, and where it is currently, on the right side. Also, there is an implied $BASEDIR in front of the destination dir.

So, if you had a file in the current directory called help.proto, and you wanted it installed in /usr/local/lib/myprog.proto, you could have as an entry,

f none $BASEDIR/lib/myprog.proto=helpproto
although as I mentioned, the $BASEDIR/ is implied, and takes whatever value is set for BASEDIR in pkginfo. Which is why it is always nice to set something reasonable for BASEDIR in pkginfo, instead of BASEDIR=/

-- Go! --

So now, if you have all your binaries, etc listed in the prototype file, all you have to do is type
make pkg
and very soon you will have a shiney new .pkg file in your curent directory!
Suitable for "pkgadd -d name.pkg" to add it. Or use pkgchk -d name.pkg with various options, to examine your new package.

Package dependancies

If you want your package to depend on another package, you need to create a 'depend' file (man depend) and add
i depend
to the prototype file.


Tip on changing package BASEDIRS: If you want to install a package in a BASEDIR other than it's default, try "pkgadd -a none -d pkgfile". Or, if you want to make it permenent (or want to do some safetychecks on it first), use my pkgreloc.ksh script

For more grungy details, you can try "man prototype", "man -s4 pkginfo", or go to Sun's Application Packaging Developer's Guide pages


Written by: Philip Brown
Solaris Top