portrait

ðÏÉÓË



[software] [catdoc] [tcl] [geography] [old things]

Solaris pkg tools

When I've tried to package some our software for Solaris, I've found out that most widely known Solaris free software repositories such as sunfreeware or blastwave cannot be relyed upon as source of packaged binary libraries.

First of all packages on sites can disappear any day and be replaced by newer, better, but incompatible version. It is OK if you just have one machine and want to use software. But if you want to develop program and distribute it as binary Solaris package, it can cause much pain.

Second, at least on sunfreeware people don't bother to specify dependencies on other packages correctly. So you have to read download page carefuly, pkgadd wouldn't tell you if something neccessary is missing on your system. Blastwave people work around this problem by creating their own dependency resolution tool pkg-get. But it don't take core solaris packages into account.

Third, there are a lot of useful packages in the Solaris (especially recent) distribution, and Software Companion CD-ROM. I don't understand why people build for instance, custom expat package and rely on it, while operating system provides quite usable one.

So, to distribute our commercial software as binary Solaris packages, I have to build these packages such way that most of dependencies are satisfied by operating system distribution, and rest I have to package myself, to ensure that these packages would still be around as long as our software which depends on it, is being distributed.

To simplify this task I've developed few helper scripts which can be downloaded from this site.

My package building scheme

To build Solaris package one has to prepare tree of files which contain all files to be included in the package, and few metainformation files, and than run pkgmk on it. Following files are mandatory:
  • pkginfo(4) contain important metainformation
  • prototype(4) contain list of files, information of their ownership and permissions, and their role in the package. If some file is special script to be executed upon installation/deinstallation it should be marked as such.
Following files are optional:
  • depend(4) contain list of dependencies on other packages.
  • preinstall, postinstall, preremove, postremove - script which are executed upon package installation/removal by pkgadd/pkgdel
  • copyright text file with package licensing information
  • checkinstall script that checks whether user-editable files (marked 'e' in the prototype) are modified.
  • There can be others, which I haven't encounter yet. Check /var/sadm/pkg/*/install directories on your Solaris system if you are curious.

Personally I consider depend file mandatory.

Most of source distributions of open source packages provide way to install compiled package into temporary tree. For instance make install of GNU autoconf-based packages accepts DESTDIR=path parameter. So it is easy to write makefile which would download source tarball, unpack it, configure, compile and install into temporary tree. Here my script come into the game.

First, you run mkpkginfo script, passing it via command line some important information about package. It would collect information about the architecture, use current date as PSTAMP and write pkginfo file.

Then, you run mkdepend. It would scan every executable and shared library in the temporary installation tree, find out shared library dependencies and script interpreters specified via #! notation, and check which package this libraries and interpreters belongs to.

You can also feed it by template dependency file where you can write dependencies on packages or just files (which you know you are using in the shell scripts), and it would write correct depend file.

Then you run mkproto script. It would run Solaris pkgproto command and fine-tune its output. First, it would check if any directory which should be included into package belongs to some other package on your current system (and, hence is so-called "shared pathname"). If so, it would adjust ownership and permission to match existing one. And if you would install resulting package, pkgadd wouldn't complain that directory confilcts with directory owned by other package (attribute change only). Second, it would automatically process abovementioned special files. Third, you can specify in the command line (i.e directly in the package creation Makefile) that some files have to have some non-standard permissions or ownership.

Of course, nothing prevent you from postprocessing output of mkproto by some sed or awk script. It is why it outputs prototype to stdout, not into file with correct name as two other script do.

After creating prototype file you have just to run pkgmk.

Source distribution of my script has a GNU Makefile (GNU make from Solaris Companion CD is enough, no need to compile recent GNU make) which demonstrates creation of the package using these script.

Version compatibility

These scripts were tested (and are actually used) on solaris 8, 9 and 10 both i386 and sparc. Unfortunately, I was unable to provide single binary package to be installed on all these versions. First, some scripts are written in Perl, and Perl package is named differently on these versions, so I cannot provide depend file which would be satisfied by any perl. Second, I haven't find way to specify that this package is architecture independent in the pkginfo file.

Download

  • Source distribution
  • Binary packages:
    Solaris 8 sparc intel
    Solaris 9 sparc intel
    Solaris 10 sparc intel
    To install these binary packages, download approriate file, uncompress it with gzip and run
    pkgadd -d filename all.
    But you probably already know it if you are thinking about using my script.

    Packages use /usr/local as base, but are relocatable. See admin(4) if you want to change base directory.

Some packaging tips

  1. If you are packaging some library, split it into two packages - one with shared libraries, and other with header files and static libraries. First one would be installed on the production servers, and second would be needed on development machines only.
  2. If you are packaging software that have library and some binaries using this library, or even compiler which comes with set of runtime libraries (i.e. gcc), split shared libraries into separate package. Big problem with sunfreeware GCC is that libgcc.so.1, needed by most of other sunfreeware packages, is provided both by SMCgcc and SMClibgcc packages. If it would be included only in SMClibgcc, and SMCgcc depend on SMClibgcc, things would be much simplier for users who have to install compiler on machine which previously have lot of software compiled by this compiler installed.
  3. If you are packaging for Solaris 8 or 9 and can live with gcc 2.95 (unfortunately, it doesn't support 64-bit on sparc platform) use gcc from Software Companion CD - programs produced with it wouldn't depend on extra shared libraries.
  4. If you compiling for Solaris 10 intel, use gcc from SUNWgcc package. It supports 64-bit on amd64, but I was unable to build GCC from upstream sources which would support -m64 on Solaris intel.
  5. If you are include manual pages into your package, write postinstall script which would run catman(1) on these pages, at least with -w options. User would thank you if whatis and apropos commands would work on your documentation. (but this would require SUNWdoc in the dependencies list).