HPUX and the Quest for a Modern Desktop

Over the years, there have been a good number of decent RISC workstations: DEC, IBM, SGI, Sun and HP all had their time. Nowadays there's hardly any left - pretty much all of the large UNIX manufacturers' workstations have been discontinued. I still have mine though, and I like them too much to let go already.

Open source software offers a way to get decent, modern applications on an older machine: if you have the source, you can build it. But building every bit of software from source, tracking down dependencies, takes a lot of effort and time... or does it? Here's where pkgsrc comes into play. New quest unlocked: turn HPUX 11.11 in a desktop that is usable for day-to-day tasks.

The NetBSD Packages Collection (pkgsrc) is a framework for building third-party software on NetBSD and other UNIX-like systems, currently containing over 8000 packages. It is used to enable freely available software to be configured and built easily on supported platforms. Now, supported and easy are terms that will be filled in differently depending on whom you ask, but... why not give it a shot?

This is the machine I've been using:

It's a HP C8000 workstation, sporting two dual-core PA8900 "Shortfin" CPUs at 1.1GHz, 4GB RAM, four U320 SCSI disks and three gigabit ethernet ports. It is configured with HPUX 11.11, patched to the last goldpak release (12/2009). Graphics have been setup, and CDE is working on it (ahhh, CDE nostalgia...). Both OS and data disks are in a mirrored LVM setup, so both performance and safety should be okay.

First I downloaded and unpacked the gcc compiler, conveniently prebuilt for HPUX, which you can find here - many thanks to Tobias Nygren for making this possible! After unpacking gcc, one has to run the mkheaders script:

$ /usr/local/gcc4/libexec/gcc/hppa2.0w-hp-hpux11.11/4.2.3/install-tools/mkheaders 

Add /usr/local/gcc4/bin to your $PATH, and make sure that your $CC is set to gcc. If your OS has the needed bundles to do development - HP C/aC++ Developer's Bundle comes to mind; if you're reading this article, you're probably familiar with getting HPUX in development-ready shape - you should be good to go. Next was downloading pkgsrc itself. I picked the most recent "stable" release at the time of writing, which was pkgsrc-2010Q4. Beware; untarring this can be problematic. Standard UNIX tar cannot handle the length of paths inside the tarball, so you may want to untar on a machine that has GNU tar (like Linux, BSD, ...). I created a dedicated LV of 8GB for this pkgsrc tree, mounted it on /mnt/alverware-2010q4, and created a symlink:

$ ln -s /mnt/alverware-2010q4 /alverware 

This will allow me to easily switch between different (stable, development, ...) pkgsrc releases; all it takes is changing that symlink. The newly unpacked pkgsrc tree was put under /alverware/pkgsrc. I'll keep my own structure throughout this article; it speaks for itself that you can put it wherever you like.

Bootstrapping pkgsrc turned out to have a small glitch: the unit-tests for bmake don't like HPUX much (or don't like *my* HPUX much... can anyone confirm?). Quick and dirty solution is to edit the Makefile.in to exclude unit-tests altogether.

$ vi /alverware/pkgsrc/devel/bmake/files/Makefile.in 

Comment out the last line (starting with "cd ${.CURDIR}/unit-tests"). Next, you can bootstrap pkgsrc for HPUX, using gcc as default compiler and with a 32bit ABI. Don't use a 64bit ABI; it'll work partially, but subtle errors will appear (python, for an example, will not function at all). You'll also notice the --unprivileged option: this allows pkgsrc to run the "bmake install" phase as nonroot user, which I prefer a lot over giving the root password every five minutes. All files will be built under /alverware/pkg.

$ cd /alverware/pkgsrc/bootstrap 
$ ./bootstrap --prefix /alverware/pkg --pkgdbdir /alverware/pkg/var/db/pkg --sysconfdir /alverware/pkg/etc --compiler gcc --abi 32 --unprivileged 

After roughly 10 minutes (on my machine), the bootstrap will have completed succesfully, and you will be back at the prompt. Update the vulnerabilities database:

$ /alverware/pkg/sbin/pkg_admin -K /alverware/pkg/var/db/pkg fetch-pkg-vulnerabilities 

You can now start to tweak your mk.conf - the master configuration file for pkgsrc - to take advantage of your hardware, and add a few extra options:

.ifdef BSD_PKG_MK               # begin pkgsrc settings

ABI=                            32 
PKGSRC_COMPILER=                gcc
USE_NATIVE_GCC=                 yes
MAKE_JOBS=                      8 
UNPRIVILEGED=                   yes
PKG_DBDIR=                      /alverware/pkg/var/db/pkg
LOCALBASE=                      /alverware/pkg
VARBASE=                        /alverware/pkg/var
PKG_TOOLS_BIN=                  /alverware/pkg/sbin
PKGMANDIR=                      man
PYPACKAGE=                      python26
PASSIVE_FETCH=                  0  
TOOLS_PLATFORM.install?=        /alverware/pkg/bin/install-sh
TOOLS_PLATFORM.awk?=            /alverware/pkg/bin/nawk
TOOLS_PLATFORM.sed?=            /alverware/pkg/bin/nbsed
.endif                          # end pkgsrc settings

Notice the USE_NATIVE_GCC which prevents pkgsrc software from pulling in pkgsrc' own gcc as a dependency, and the biggest time saver of all: MAKE_JOBS. I have it set to 8 (as in make -j8); two jobs per cpu core seems to give decent results here. Next on the list is building GNU tar (didn't you wish you had that before?):

$ cd /alverware/pkgsrc/archivers/gtar
$ bmake && bmake install && bmake clean && bmake clean-depends

This should take quite a while - it will pull in a gigantic heap of dependencies of all kinds. It should complete without problems, after which you can add the following line to mk.conf:

TOOLS_PLATFORM.tar?= /alverware/pkg/bin/gtar 

Once this is done you can start building as you wish. I'll document my own building track here, including various problems encountered while building, and a fix if available. Do note that I am NOT a developer, and my fixes may be quicker and dirtier than you'd like. A proper developer might be able to figure out the actual root cause (if I couldn't), and create a proper patch for upstream (which I can't).

Following the fixes documented below, I'm now working happily from my HPUX desktop. The following packages are installed on my system (and new ones are being added daily):

$ ls /alverware/pkg/var/db/pkg
aalib-                libart-2.3.21                   mkfontdir-1.0.5
aterm-1.0.0nb8                  libast-0.7nb3                   mkfontscale-1.0.7
atk-1.32.0                      libaudiofile-0.2.7              mng-1.0.10nb2
autoconf-2.68                   libcfg+-0.6.2nb3                monafonts-ttf-2.90
automake-1.11.1nb1              libcroco-0.6.2                  mplayer-1.0rc20100913nb2
autoswc-1.6                     libdvdnav-4.1.3                 mplayer-fonts-20030714nb1
babl-0.1.2                      libdvdread-4.1.3                mplayer-share-1.0rc20100913
bash-4.1nb1                     libdv-1.0.0                     ms-ttf-20020306nb5
bdftopcf-1.0.2                  libexif-0.6.20                  p5-gettext-1.05nb5
bigreqsproto-1.1.0              libffi-3.0.9                    p5-XML-Parser-2.40
bison-2.4.3                     libfontenc-1.0.5                pango-1.28.3
bmake-20100808                  libgcrypt-1.4.6                 pax-20080110
bootstrap-mk-files-20090807nb2  libgetopt-1.4.4                 pcre-8.11
bzip2-1.0.6                     libgpg-error-1.10               perl-5.12.2nb1
cabextract-1.3                  libICE-1.0.6                    pidgin-2.7.3nb2
cairo-1.10.2                    libiconv-1.13.1                 pixman-0.18.4
compat_headers-0.2              libidn-1.19                     pkgdb.byfile.db
compositeproto-0.4.1            libmad-0.15.1bnb1               pkg-config-0.25nb1
db4-4.8.30                      libogg-1.2.1nb1                 pkg-vulnerabilities
dejavu-ttf-2.32                 libpaper-1.1.24                 pkg_install-20101212
desktop-file-utils-0.15         libpurple-2.7.3nb2              pkg_install-info-4.5nb3
digest-20080510                 librsvg-2.32.1nb1               png-1.4.5
encodings-1.0.3                 libSM-1.1.1nb1                  popt-1.16
esound-0.2.41                   libtasn1-2.9                    pornview-0.2.0pre1nb7
eterm-0.9.5nb3                  libtheora-1.1.1nb1              printproto-1.0.4
expat-2.0.1nb2                  libtool-base-2.2.6bnb4          psutils-1.17nb2
gawk-3.1.8                      libungif-4.1.4nb1               py26-expat-0nb4
gdb-5.3nb5                      libvorbis-1.3.2                 py26-xcbgen-1.6nb1
gdk-pixbuf2-2.22.1              libwmf-               python26-2.6.6nb5
gegl-0.1.2nb3                   libX11-1.3.5                    randrproto-1.3.1
gettext-lib-0.14.6              libXau-1.0.6                    readline-6.1
gettext-tools-0.14.6nb1         libXaw-1.0.7                    renderproto-0.11
ghostscript-8.71nb6             libxcb-1.7                      resourceproto-1.1.0
ghostscript-fonts-8.11nb3       libXcomposite-0.4.2             screen-4.0.3nb4
gimp-2.6.11nb2                  libXcursor-1.1.10               scrnsaverproto-1.2.0
glib2-2.26.1nb1                 libXdmcp-1.0.3                  SDL-1.2.14nb1
glu-7.4.4nb2                    libXext-1.1.1                   shared-mime-info-0.90
gmake-3.82nb1                   libXfixes-4.0.5                 startup-notification-0.10
gmplayer-1.0rc20100913nb2       libXfont-1.4.2                  tiff-3.9.4nb1
gnutls-2.10.4                   libXft-2.1.14                   tnftp-20070806
gperf-3.0.4                     libXinerama-1.1                 unzip-6.0
groff-1.20.1nb2                 libXi-1.3.2                     vera-ttf-1.10nb4
gtar-1.25                       libxml2-2.7.8nb2                videoproto-2.3.1
gtar-base-1.25nb3               libXmu-1.0.5                    vim-7.2.446
gtar-info-1.25                  libXpm-3.5.8                    vim-share-7.2.446
gtexinfo-4.13                   libXp-1.0.0                     watch-3.2.6nb1
gtk2+-2.22.1                    libXrandr-1.3.0                 xcb-proto-1.6
ilmbase-1.0.2nb1                libXrender-0.9.6                xcb-util-0.3.6
imake-1.0.3                     libXres-1.0.4                   xcmiscproto-1.2.0
imlib2-1.4.2nb5                 libXScrnSaver-1.2.0             xextproto-7.1.2
inputproto-2.0                  libxslt-1.1.26                  xf86bigfontproto-1.2.0
install-sh-20100824             libXt-1.0.8                     xf86dgaproto-2.1
intltool-0.40.6                 libXvMC-1.0.6                   xf86vidmodeproto-2.3
jasper-1.900.1nb5               libXv-1.0.5                     xineramaproto-1.2
ja-sazanami-ttf-20040629nb1     libXxf86dga-1.1.1               xmlcatmgr-2.2nb1
jpeg-8b                         libXxf86vm-1.1.0                xorg-cf-files-1.0.3
kbproto-1.0.5                   lzo-2.04                        xproto-7.0.18
kochi-ttf-20030809nb5           m4-1.4.15                       xtrans-1.2.5
lcms-1.19                       makedepend-1.0.3                zlib-1.2.3
less-418                        MesaLib-7.4.4nb3

You'll notice that there is NO FIREFOX there. First of all, building firefox is a very, very difficult task, and one I'm not capable of doing. Second, HP is offering a prebuilt depot of Firefox 3.5.9 for HPUX. Their version will undoubtedly be a magnitude faster and more stable than anything I could hack together, so... I don't touch it.

• x11/libX11:

The default options for libX11 have changed since the last pkgsrc release, causing all X11 applications to fail on HPUX' libc poll(). This can be fixed by doing the following edit:

    Replace CONFIGURE_ARGS+= --with-xcb by CONFIGURE_ARGS+= --without-xcb 
After this, I tend to build libX11, which pulls in a lot of X11 dependencies as well.


• devel/gtexinfo:

Dependency for graphics/netpbm → print/ghostscript → devel/ncurses. Ncurses are good; you want them. gtexinfo fails to build with the linker complaining about missing symbols BC, PC and ospeed. Edit the failing code:

$ vi work/*/info/terminal.c 
Search for ospeed; you'll notice the three mentioned symbols are defined inside an #ifdef block. Move the definitions out - HPUX hasn't got those symbols, and the code fails to detect that, causing the ifdefs to skip the defines. After this hack, it builds and installs just fine.


• graphics/netpbm:

Dependency for print/ghostscript → devel/ncurses. Before you start the build, edit the top level Makefile, and comment out the following line:

USE_FEATURES= snprintf 
This suffices for netpbm to build.


• print/ghostscript:

This piece of software has some ugly problems. First, start the build, and wait until it fails miserably. It's unclear to me why, but somehow the build system doesn't pick up the basic facts that

  1. HPUX does not use .so for its shared libraries, like Linux does, but .sl
  2. HP's own linker does not follow the same syntax as GNU ld, causing ugly files named "name=libgs.so" to be created in the totally wrong place.

To force-override these two vital details, change the following things in this specific file:

  GS_SOEXT=so needs to become GS_SOEXT=sl 
  LDFLAGS_SO=-shared -Wl,-soname=$(GS_SONAME_MAJOR) needs to become LDFLAGS_SO=-shared -Wl,+h,$(GS_SONAME_MAJOR) 
Once you have done these two edits, it will complete succesfully.


• devel/ncurses:

If you have built the problematic dependencies mentioned above, ncurses should install without a problem. Make sure to clean everything afterwards.

 $ bmake && bmake install && bmake clean && bmake clean-depends 
Once it's done, you can add another semi-crucial line to your mk.conf:


• editors/vim:

The only real editor in the world! This doesn't require any fixes, except you need to accept the license in mk.conf by adding the following line:

At this point, I also included a big default options selection:
 PKG_DEFAULT_OPTIONS= -hal -fam -daap -evolution -dbus -avahi -farsight -gstreamer -gnome -gtkspell -arts -pulseaudio -nas -x264 ncurses 
This enables or disables all dependencies mentioned above for all applications to be built, supposing an application offers the option of enabling/disabling it.


• multimedia/libdvdnav:

Dependency for multimedia/mplayer. This will fail during configure due to an obscure pthreads detection bug which seems to have haunted OSX as well. Pthreads shouldn't be an issue, so we'll force configure to continue, regardless of what it says:

    Search for the following code: return pthreads_create(); return 0; 
    Replace by: return 0; 
Dirty? Yes. But it'll continue and finish building.


• devel/SDL:

Dependency for multimedia/mplayer. Start the build with bmake, and wait for it to fail, then edit:

 work/*/include/SDL_stdinc.h: remove the "strings.h" include 
Restart the build. Fixed.


• multimedia/mplayer:

Start the build with bmake, and wait for it to fail. Edit:

work/*/config.h: add the following lines: 
    #define lrintf(x) ((int)(rint(x)) 
    #define __open64 open 
    #define SIZE_MAX ((size_t)-1) 
    #define atoll(x) strtoll(x, (char **)NULL, 10) 
    #define ldexpf(x, y) (float)ldexp(x, y) 
work/*/libavutil/libm.h: comment out the following function entirely: 
    static av_always_inline av_const long int lrintf(float x) 
After these edits, it'll build. And it works too:


MUPPET SHOW ON HPUX! I bet that's a world first, right here.


• wm/fluxbox:

Fluxbox acts a bit weird when being built in an unicode shell on UX. No idea why, but I had to start with:

$ LC_ALL=C bmake 
Even then it fails on the polish translation, so I removed it, plus another quick hack to keep the UX linker happy:
    remove pl_PL from building (sorry, polish people) 

    change "LDADD = FbTk/libFbTk.a FbTk/LogicCommands.o defaults.$(OBJEXT)" to "LDADD = FbTk/libFbTk.a defaults.$(OBJEXT)" 
After these edits, rerun bmake and it'll be fine. Now, you might wonder, how do you get HPUX' login manager to start fluxbox instead of CDE? The trick is setting xdmMode in the dt configfile, then restart it, and having a good .xsession:
$ grep xdmMode /etc/dt/config/Xconfig Dtlogin*xdmMode: True 
$ /sbin/init.d/dtlogin.rc reset 
$ cat .xsession exec /alverware/pkg/bin/startfluxbox 
$ chmod 700 .xsession 
... and next time you login, you get a nice fluxbox desktop. Supposing you don't want to sit behind your HPUX screen all day (building pkgsrc takes some time after all), you can test your X11 desktop using Xnest from a Linux or BSD machine:
$ Xnest -depth 24 -geometry 1024x768 -name Bladnoch -query Bladnoch :1 
This will get you the HPUX desktop via XDMCP in a window, like the screenshot above.


• graphics/ilmbase:

Dependency for graphics/gegl → graphics/gimp. .This contains some lowlevel math routines, some of which depend on math.h functions that aren't available on PARISC HPUX (they apparently are on IA64, but that doesn't help us, does it?). Edit:

work/*/Imath/ImathMath.h: Find the function defines and change them to match this: 
    static float modf (float x, float *y) {return (float)::modf ((double)x, (double*)y);} 
    static float ceil (float x) {return (float)::ceil (x);} 
    static float floor (float x) {return (float)::floor (x);} 
    static float hypot (float x, float y) {return (float)::hypot (x, y);} 


• graphics/gimp:

Gimp builds fairly easy, although it'll take a while due to the whole of X11 libs and GTK2 being pulled in. The build will eventually fail in gimp itself with a linker error; symbol "finite" is unknown. Edit:

work/*/config.h: Add a new define: 
    #define finite(x) isfinite(x) 
Restart the build, and it'll succeed.



• x11/aterm:

Aterm has a hardcoded utmp reference in pkgsrc, which we have to remove in order to be able to build:

    remove the "--enable-utmp" reference
Just like with fluxbox, I had to start with:
$ LC_ALL=C bmake
After that you're all set.


• misc/watch:

Silly little tool, but I still like it. It'll fail when building, which you can fix easily:

work/*/watch.c: replace strtof(x) by (float)strtod(x) 


• security/libgcrypt:

Dependency for security/gnutls → chat/libpurple. It has a very subtle problem which, if you don't fix it upfront, will cause anything gnutls related to fail. Start the build, but stop during the configure phase, then edit:

/work/*/random/rndunix.c: add #include <assert.h>


• chat/libpurple:

Dependency for chat/pidgin and chat/finch. You'll have to explicitly enable gnutls to get SSL support, and perl for non-C plugins:

PKG_OPTIONS.libpurple= gnutls perl 
It builds cleanly except for one protocol:
    find the code block that defines int8_t; 
    expand the "#if !defined(__CYGWIN__) && !defined(__SunOS)" 
    with "&& !defined(_INCLUDE_HPUX_SOURCE)" 
Once this is done, you can continue building pidgin.



• chat/finch:

Something in pkgsrc and/or finch doesn't agree with wide character support. Getting finch to build on my machine demanded a very ugly hack:

     set --with-ncurses-headers=/alverware/pkg/include/ncursesw 

    add "typedef unsigned int wint_t;" 
Looking through the ncursesw code, it looks as if something went wrong - large and vital parts of the code are between "if 0" blocks, effectively eliminating them.


• textproc/rarian:

This build will error out on a duplicate definition of strrstr. Remove the one provided by rarian itself:

    comment out entire function "static char *strrstr (char *s, char *wanted)". 


• net/ORBit2:

This package uses IPv6 calls, but doesn't add the proper linker flag. Edit:

    add LDFLAGS+= -lipv6 
You do need the IPv6 bundle for this, naturally! You can get the bundle from HP for free at this page.


• sysutils/dbus:

Some things really do depend on dbus, so what the heck... just build it. Build will fail on missing symbol "vsyslog"; this is easily fixed:

    replace all invocations of "vsyslog" by "syslog" 


• multimedia/gstreamer-0.10:

I would have preferred not building this, but some things had hardcoded dependencies on it. Anyway, to get it to build, the following define is needed:

    add #define MSG_DONTWAIT 0 


• textproc/gnome-doc-utils:

It's fairly ironic, but the thing in gnome-doc-utils that fails is... the docs. I guess we can live without the docs for gnome-doc-utils, can't we?

    remove 'doc' from DIST_SUBDIRS and SUBDIRS variables 


• sysutils/eggdbus:

This package feeds bad GNU linker options to HP's ld. Won't work, of course...

    remove "-Wl,--as-needed" from LDFLAGS 

    remove "-Wl,--as-needed" from LDFLAGS 


• security/libgnome-keyring:

Not much to do here; one define for a differently named symbol:

    add #define MAP_ANON MAP_ANONYMOUS 


• textproc/enchant:

Even though size_t and gsize seem to have the same type, automatic casting doesn't work too well. Therefor a specific cast:

    164: size_t result = g_iconv(m_translate_in, &in, (gsize*)&len_in, &out, (gsize*)&len_out);
    190: size_t result = g_iconv(m_translate_in, &in, (gsize*)&len_in, &out, (gsize*)&len_out);
    206: if ((size_t)-1 == g_iconv(m_translate_out, &in, (gsize*)&len_in, &out, (gsize*)&len_out)) {


• editors/abiword:

To get abiword to build, quite a few fixes are needed. First of all, abiword defines a symbol which already exists in HPUX. We're not using this native symbol, so we undefine it first to allow it to be defined without error.

    add #undef m_unit 
The 'main' makefile contains a few references to a linker option that is not valid for HP's ld, only GNU. Remove it:
    remove all references to "--fno-undefined"
Another makefile has an issue with the plugins: we are not building any plugins, yet it wants to do a for-loop over them. Fails badly:
    remove all "for plugins in ... done" blocks 
Next, we get to apply the same size_t/gsize fix we had before:
work/*/src/af/util/xp/ut_iconv.cpp: line 314: 
    return g_iconv((GIConv)cd, (char **)inbuf, (gsize*)inbytesleft, outbuf, (gsize*)outbytesleft); 
Finally, we have one file that uses strtof, which we haven't got:
    replace all instances of "strtof" by "(float)strtod" 
EDIT: even though this builds, it doesn't actually run - it's lacking a symbol. Will look into it. For the time being it's not worth building this.


• net/libtorrent:

Libtorrent depends on a syscall mincore which indicates whether or not a specific page is in memory. This apparently strongly reduces page faults, boosting performance. HPUX hasn't got it, so we'll have to build without it.

    add --disable-mincore to CONFIGURE_ARGS 
Next, we run into another example of an application redefining a system macro:
    add #undef m_slot 


• net/rtorrent:

Some symbols are only defined if the proper compiler flag (_REENTRANT) is given on HPUX. At this point, I've added it to PKG_DEFAULT_OPTIONS (see above). Next, two symbols are missing on HPUX, and m_slot needs to be undefined again:

    #define AF_LOCAL AF_UNIX 
    #define PF_LOCAL PF_UNIX 

/work/*/rak/priority_queue_default.h, /work/*/src/option_parser.cc, /work/*/src/display/text_element_string.h: 
    #undef m_slot