BSD-games & Solaris fun.

I was getting bored with a stock Solaris 2.4 system, so I decided to load up some basic BSD games. Since I like the torture of it, I went to build them from source.

OH MY GOD.

I don’t mean to complain too much, but holy crap, the configuration for the BSD games package is INSANE.

After answering what feels like 100+ questions (it very well may be) you can eventually try to build BSD-games… but much to my dismay the 2.x series all hinges on you basically having a GNU environment, and well… I didn’t want to spend that much time just to run robots & fortune.

So thanks to this great page, there is some hints on building BSD=games 1.5 for Solaris… But where on earth to find something this old?! This is the weird thing, all of this older free software is being destroyed wholesale… I know right now people just don’t care, but there most certainly is this ‘digital’ divide that is coming, where most of our current history will be lost forever… Hell if nukes fell tomorrow, good luck to anyone decoding a DVD… And god help them if they succeeded. It certainly wouldn’t be worth the effort.

Anyways, with a bunch of searching I found a site in Germany with the goods.

Now the real fun starts…

I’m using gcc 2.8.1, because that is what was in the GNAT package. Anyways for some programs I was encountering errors like this:

gcc extern.o init_field.o main.o make_level.o move.o move_robs.o play_level.o query.o rnd_pos.o score.o flush_in.o -lncurses -lnsl -lsocket -L/usr/ucblib -R/usr/ucblib -lucb -o robots
Undefined first referenced
symbol in file
_tty main.o
_pfast main.o
_echoit main.o
_tty_ch main.o
_rawmode main.o
ld: fatal: Symbol referencing errors. No output written to robots
make: *** [robots] Error 1

I know.. .WTF?! So after building & rebuilding ncurses, I found on some obscure Fortran list that the linker in Solaris is… weird. So to save anyone the hell, here is the “correct” string in this instance.

gcc extern.o init_field.o main.o make_level.o move.o move_robs.o play_level.o query.o rnd_pos.o score.o flush_in.o -L/usr/ucblib -R/usr/ucblib -lcurses -ltermcap -lucb -lncurses -o robots

Notice the difference? Yeah, the big one, is that now it linked. The position of the -L & -R really matters to the SUN linker.

Another error I was getting (in this example from tetris) was this:

In file included from screen.c:59:
screen.h:62: parse error before `__P’
screen.h:63: parse error before `__P’
screen.h:64: parse error before `__P’
screen.h:65: parse error before `__P’
screen.h:66: parse error before `__P’
screen.h:67: parse error before `__P’
screen.h:68: parse error before `__P’

I assume in the future (or was it the past?) that this __P macro would be standard with GCC? Maybe it’s a linux-isim? I don’t know. What I do know is this block

#undef __P
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif

Will fix it.

Another weird error revolves around setjmp.h . Now I know in Solaris some headers have to be included in a certain order or all hell will break loose, or the part you are looking for just won’t be included. But I just mined out the relevant parts to get what I wanted…

In file included from /usr/ucbinclude/setjmp.h:44,
from screen.c:47:
/usr/include/sys/ucontext.h:24: parse error before `sigset_t’
/usr/include/sys/ucontext.h:24: warning: no semicolon at end of struct or union
/usr/include/sys/ucontext.h:25: warning: data definition has no type or storage class
/usr/include/sys/ucontext.h:28: parse error before `}’
/usr/include/sys/ucontext.h:28: warning: data definition has no type or storage class

So I just removed the reference to setjmp.h & instead put in this:

#define _JBLEN 10 /* ABI value */
typedef int jmp_buf[_JBLEN];

And it was happy. Now I know this is a HORRIBLE “FIX” but heh, sometimes you just want the dammed thing to compile!

Next I was getting these weird sigset_t errors…

screen.c: In function `stopset’:
screen.c:238: `sigset_t’ undeclared (first use in this function)
screen.c:238: (Each undeclared identifier is reported only once
screen.c:238: for each function it appears in.)
screen.c:238: parse error before `sigset’
screen.c:242: `sigset’ undeclared (first use in this function)
screen.c:244: parse error before `)’

And again I just mashed in the definition of:

typedef struct { /* signal set type */
unsigned long __sigbits[4];
} sigset_t;

Lastly was another error revolving around sig_t … So just inserting this:

typedef void (*sig_t) (int);

Into the code, got it to stop complaining.

So the upshot is that after manually linking a bunch of these programs, and manually installing the binaries & datafiles (Solaris 2.4’s install doesn’t work the way BSD-games 1.5 expects…) I finally could do this:

UNIX(r) System V Release 4.0 (solaris24)

login: rootb
Password:
Last login: Sat Dec 12 19:01:49 from qemunat
bash# fortune
There can be no twisted thought without a twisted molecule.
— R. W. Gerard
bash#

Now the big question…. Was it worth it?

Yeah sure, I learned a valuable lesson about the linker. The rest, not so valuable.

3 thoughts on “BSD-games & Solaris fun.

  1. Great job! I actually never played in BSD games, (well except for wargame), but the linker research is really important.

    I'm also was surprised that the most of the old free stuff has disappeared just like this. Spent something like an hour till I could download the last(!) version of Debian(!) which supported sun4m machines. Never expected problems with it as Debian is known for its over-conservatism.

    And the pre-2000 stuff is much harder to find.

    Maybe we should start a museum project? (Do you have a connections in .gov to get it funded? 😉 )

    As for BSD games, just hold on a few days more and you'll be able to run them under SunOS 4.1.x (which was a BSD-based and had a bundled C compiler).

Leave a Reply