pkgsrc under Solaris

pkgsrc under Solaris has been officially supported for a long time now. The pkgsrc guide gives instructions and valuable hints, how to bootstrap and use the pkgsrc framework with Sun's operating system. Yet, the novice user still faces a number of choices. Unfortunately, the consequences of each single choice may become obvious only several days, weeks or months later, after wasting time and burning CPU cycles to find a single software package, that refuses to be built with the chosen setup.

This guide documents several of these choices and tries to give hints, which options may lead to success, and which ones cause trouble. They are the result of my own experiments to work with pkgsrc under Solaris 10 and OpenSolaris, on Sparc and x86 machines.

Degrees of Freedom

Among the choices one can make, these are the most important ones:

As we will see below, some of these choices are mutually dependent.

Choosing a compiler

Given the abundance of compilers to choose from, this may be the toughest and most crucial decision. Some of the features to ponder are

Choosing between 32-bit and 64-bit environment

For a discussion of the pros and cons of 64 bit compared to 32 bit, this Wikipedia article seems to be a good start.

Solaris allows the parallel execution of 32-bit and 64-bit binaries. To support this, every system library comes in two versions: 32-bit libraries are stored in /usr/lib, 64-bit libraries in /usr/lib/64.

Withing pkgsrc, mixing the two ABIs is not possible. You have to choose an environment, and all programs and libraries are either built for 32 bit or 64 bit. You may select to use the 64-bit ABI when bootstrapping pkgsrc, but then you are bound to this choice.

Most packages can be compiled for a 64-bit ABI. But some packages don't play nice, and you may end up with 32 bit objects in a 64 bit world. If a package will only compile in 32-bit mode and then tries to link against a library from another pkgsrc package that was built for a 64 bit ABI, it will fail.

Unless you really have a need for 64-bit binaries and you are willing to go through some extra trouble, I suggest sticking to the 32 bit ABI.

Choosing the X11 implementation

Solaris comes with a complete X11 distribution, including additions like OpenGL and Motif. Most packages from pkgsrc can be built against these libraries. But sooner or later you may find a package that causes problems. Sun uses pragmas within its header files, which are not understood by GCC. Normally, they would be ignored, but if a package applies very strict rules for the handling of compiler warnings (-Werror), pulling in these header files will be fatal.

The alternative is to use X11 libraries provided by pkgsrc (using a newer, "modular" distribution of X.org). It seems to be a waste of time and space to duplicate software that is already provided by Solaris, but in the long run it causes far less trouble.

Choosing other native software

Over the years, Solaris incorporated more and more free software, that previously had to be installed separately. It is possible to tell pkgsrc to use this software, instead of building its own version. Unfortunately, this is not supported by all packages. Sometimes it may work, sometimes not. Similar to the choice of X11 implementation above: Sticking to pkgsrc will cause less problems, because you have a coordinated, self-contained collection of packages.

Even if you are tempted to use some of Solaris' software, there are some packages that should never be substituted. The most prominent one is libiconv. Although Solaris provides its own libiconv, this implementation is not compatible to the GNU version found in converters/libiconv. If a package relies on features found only in the GNU version and is forced to use the Solaris implementation instead, it will fail.

Bootstrapping pkgsrc

The bootstrap process is described in the pkgsrc guide, so I won't repeat the instructions here. The general idea is to unpack pkgsrc, go to the directory bootstrap and execute

$ ./bootstrap --prefix=PKGSRCDIR

Instead of PKGSRCDIR, use the actual root directory of your installation, e.g. /opt/pkg. There is no need to build pkgsrc as superuser. In that case, you have to add the option --unprivileged.

When using the Sun Studio compiler, set the environment variable CC to cc before starting bootstrap, otherwise (as of this writing) one of the targets (pdksh) will insist on using GCC.

Fixing man-pages

When bootstrap has finished, you have a basic set of scripts and binaries for building more packages from pkgsrc. These tools come with man-pages, but unfortunately, they are not compatible to Solaris' way of handling documentation. They use a different macro set, which is unknown to Solaris. A thorough fix is described at the end of this page. An alternative, less intrusive method is to go to PKGSRCDIR/man and run this command:

$ find . -name '*.0' | sed 's/.\/cat\(.\)\/\(.*\)\.0$/\2.0 cat\1\/\2\.\1/' | xargs -L1 ln -s

pkgsrc installs pre-formated man-pages, that Solaris can use. But they have the wrong suffix. The command above creates symbolic links with names suitable for Solaris' man command. The downside of this approach is, that only the man-pages installed by bootstrap are fixed. Most packages in pkgsrc come with man-pages Solaris can use, so those are no problem. Only packages in the directory pkgtools use BSD style man-pages, which are not caught by this method.

Optional: Switching to pkgsrc's GCC

If the bootstrap compiler is not the compiler you intend to use for building packages, you should install a version of GCC from the lang subdirectory of pkgsrc. lang/gcc34 is the latest GCC currently available in pkgsrc.

If you have used the Sun Studio compiler for bootstrapping, don't forget to change the definition of CC in PKGSRCDIR/etc/mk.conf after installing GCC.

As a prerequisite to GCC, pkgsrc will install the package devel/libtool-base. This package contains definitions and flags for running compiler, assembler and linker. As it is built still with the bootstrap compiler, these rules and definitions have to be adjusted. The easiest method is to re-install the package, using the "real" compiler. First install the package pkgtools/pkg_tarup, then do a bmake replace of package devel/libtool-base.

If you are on an x86 machine, apply this patch to the freshly installed gcc. Otherwise, the package security/openssl will build, but not work. You may find this out only much later, when a program that uses libcrypto mysteriously crashes.

If you have used the GCC from /usr/sfw so far, the packages built in advance of GCC contain references to /usr/sfw/lib/libgcc_s.so. Among these packages are libiconv and gettext. As a consequence, every subsequent package you compile with the pkgsrc GCC that uses these libraries may contain references to this libgcc and the one from the pgksrc GCC. This is ugly at best, but may cause real trouble at worst. To remove all traces of the wrong libgcc, reinstall (i.e. bmake replace) the packages converter/libiconv, devel/gettext-lib and devel/gettext-tools.

Configuring pkgsrc

Before starting to install packages, you should tune your pkgsrc environment. This is done by adding definitions to the file PKGSRCDIR/etc/mk.conf.

If you continue to use the Sun Studio compiler, add these lines:

SUNWSPROBASE=/opt/SUNWspro
CC=cc
CXX=CC
CPP=cc -E
CXXCPP=CC -E

Adjust SUNWSPROBASE to wherever you installed the Sun Studio compiler.

If you want to use modular X11, add this line:

X11_TYPE=modular

If you are using Sparc and x86 machines, and want to do simultaneous builds from a shared pkgsrc tree, this definition is handy:

OBJHOSTNAME=defined

It allows you to use the same pkgsrc tree from different hosts, and concurrent builds of the same package won't collide.

Conclusion

In general, pkgsrc works very well under Solaris. There are packages, that need some fixing, but usually, the changes are not that hard. Be sure to report such changes to back to pkgsrc.

My own, very personal opinion on the currently best, least troublesome way to use pksrc under Solaris is: