//drivel.com/jlick/cgi-bin/follow
SYNOPSIS:
Distributing software in pkg format on Solaris systems is a convenient
way that allows systems administer to easily both install and remove a
piece of software in a consistent manner. While there are several easy
tutorials on making traditional packages, they do not cover more
advanced usages of the pkg format. One such use is making a package
which contains binaries for more than one platform type, such as for
both sparc and i386 systems. This would allow you to distribute one
package which would install the appropriate version on any system. This
document will show how to create such a package.
PREREQUISITES:
This document assumes a general familiarity with creating packages. If
you are not familiar with this process, consult one of the following:
BACKGROUND:
After learning the basics of building packages, I wanted to make packages
of some of the software I normally install on several systems. Since I
have both sparc and i386 type Solaris systems, it would have been a lot
more convenient to be able to make a single package which could install
on both. And I knew it was possible, because Sun packages such as
Solstice Disksuite came this way. I came up with this method by poring
not guaranteed to be 100% correct, but it has worked for me so far. This
will walk you through how to create a sample Multi-Platform Package. After
creating this simple package you should be able to create other
Multi-Platform Packages on your own.
STARTING OUT:
The package we will make will be called JLmultpkg. In a convenient location,
do a "mkdir -p multipkg/JLmultpkg-proto" and go into that directory. The
rest of this document will use paths relative to this directory unless
otherwise noted. Create a "copyright" file as normal. Then create a basic
pkginfo file.
In pkginfo there are a few differences from the typical entries. For ARCH, instead of just "sparc" for example, you would list "sparc,i386" if you have both Sparc and i386 binaries. You can also set this to "all" but that would pose problems if for example a user tried to install this on a PowerPC system and the requisite binaries were not available. If you want to support other systems besides Sparc and i386, just list the architectures for each system. "uname -p" will tell you the right processor name to use. Avoid using the kernel architecture names (sun4m, sun4c, sun4d, etc.) unless your package is really limited to that kernel. The next time a new architecture comes out (e.g. sun4u), your package would no longer install on those new systems.
You also need to add a CLASSES setting to tell it which classes (the second field in prototype or third field in pkgmap) to install by default. Set this to "none" By default pkgadd will attempt to add all available classes, but we are going to use the class field to tell pkgadd which files to install for each architecture. Setting this to "none" will tell pkgadd to add at error because it will find multiple copies of things to install and get confused.
Finally you need to set I386LOC and SPARCLOC to /. These will be expanded into variables later. These variable names will be embedded into pathnames in the package layout and the prototype file, and are simply ways to have two sets of binaries side by side in seperate directories. Since the variable gets expanded to / it is a nullop and puts the binaries in the same place at the end of everything.
A simple pkginfo file would thus look like this:
PKG="JLmultpkg" NAME="Multi-Platform Package Test" VERSION=1.0.0 CATEGORY=system CLASSES=none ARCH=sparc,i386 VENDOR="James Lick" BASEDIR=/ I386LOC=/ SPARCLOC=/
LAYING OUT FILES:
This package will install two files on any system, a platform independent
shell script, installed as /usr/sbin/systype, and a platform specific
data file, installed as /etc/mytype. Since we are supporting two system
types, we will need three files: One copy of systype and two copies of
do something like this, but this is just a silly example to show how to
have both platform independent and specific files in the same package.
A more typical example is where binaries and libraries would be platform
specific and manual pages and header files would be platform independent.
No sense in having these files duplicated more than once!
% mkdir -p usr/sbin % cat > usr/sbin/systype echo "This system type is `cat /etc/mytype`." ^D % chmod 555 usr/sbin/systype
them in different subdirectories depending on the architecture:
% mkdir -p etc/\$I386LOC % echo "i386" > etc/\$I386LOC/mytype % mkdir -p etc/\$SPARCLOC % echo "sparc" > etc/\$SPARCLOC/mytype
Then setup the basic prototype file:
% find usr etc -print | pkgproto > prototype
Edit prototype to add in the required files and get rid of the shared the ownership and permissions, etc.:
i pkginfo i copyright f none usr/sbin/systype 0555 bin bin f none etc/$I386LOC/mytype 0444 bin bin f none etc/$SPARCLOC/mytype 0444 bin bin
THE MAGIC:
Now comes the magic that makes the Multi-Platform stuff really work. First
we need to create a script which will add the platform specific type to
the CLASSES setting. This script is called request and will be run by
the pkgadd program. The output file is read to set or reset variables.
In our case we want to add the "uname -p" to CLASSES. Edit "request" and
insert the following:
cat >$1 <<EOF CLASSES="${CLASSES} `uname -p`" export CLASSES EOF
Then you need to add request as an install item to prototype, and change the class to sparc or i386 for the two platform specific files. Your prototype file would then look like:
i request i pkginfo i copyright f none usr/sbin/systype 0555 bin bin f i386 etc/$I386LOC/mytype 0444 bin bin f sparc etc/$SPARCLOC/mytype 0444 bin bin
FINISHING UP:
setup to an actual package:
% pkgmk -o -r `pwd` -d .. WARNING: missing directory entry for <etc> WARNING: missing directory entry for <etc/$I386LOC> WARNING: missing directory entry for <etc/$SPARCLOC> WARNING: missing directory entry for <usr> WARNING: missing directory entry for <usr/sbin> WARNING: parameter <PSTAMP> set to "hacienda.shoreside.com970322020250" WARNING: unreferenced class <i386> in prototype file WARNING: unreferenced class <sparc> in prototype file part 1 -- 28 blocks, 14 entries /home/jlick/multipkg/JLmultpkg/pkgmap /home/jlick/multipkg/JLmultpkg/pkginfo /home/jlick/multipkg/JLmultpkg/install/copyright /home/jlick/multipkg/JLmultpkg/reloc/etc/$I386LOC/mytype /home/jlick/multipkg/JLmultpkg/reloc/etc/$SPARCLOC/mytype /home/jlick/multipkg/JLmultpkg/install/request /home/jlick/multipkg/JLmultpkg/reloc/usr/sbin/systype %
This will create the finished package and place it in the ".." directory.
TRYING IT OUT:
Try installing it on different systems and test it out:
% cd .. % su Password: Processing package instance <JLmultpkg> from </home/jlick/multipkg> Multi-Platform Package Test (sparc,i386) 1.0.0 Copyright (C) 1997 by James Lick Using </> as the package base directory. Installing Multi-Platform Package Test as <JLmultpkg> /usr/sbin/systype [ verifying class <none> ] /etc/mytype [ verifying class <sparc> ] Installation of <JLmultpkg> was successful. This system type is sparc. The following package is currently installed: JLmultpkg Multi-Platform Package Test (sparc,i386) 1.0.0 Do you want to remove this package? y /etc/mytype /usr/sbin/systype Removal of <JLmultpkg> was successful.
Try adding the package to both a sparc and i386 system and /usr/sbin/systype will show the appropriate architecture when run. Check /etc/mytype to see that it really did install a different file on each system type.
SHORTCUTS FOR THE LAZY:
to do all the above work and can just download a tarball with all the
prototypes and the finished package as
multipkg.tar.gz.