Code Building Lab

Now we’ll try to build two packages that have different licenses.

Let’s take a look at the process of building a simple software package from the Free Software Foundation’s GNU Project. Going through the blurbs for all the official GNU packages, I come across something entitled “Gcal,” a program that can calculate and print calendars. Our current operating system, Fedora 23, does come installed with the standard cal program available on most Unix machines, but gcal has several extended features, including the ability to the calculate astronomical data such as the phases of the moon, which is information that can be used to plan the harvest season and to perform magick rituals—a must for any computer programmer. Let’s go ahead and download the gcal package.

In the downloads directory, we have now a file labeled gcal-4.tar.gz. The .tar extension indicates that it is a tarfile (“tar” being short for tape archive), that is, a group of files bundled together with the tar command; and the .gz extension indicates that it has been compressed with the gzip command. To build the package, first we must unpack the archive by using the tar command. Let’s run the following command:

tar -xzf gcal-4.tar.gz

The x option tells the tar command that we need to extract something, the z option tells it that we need to filter the archive through gzip, and the f option tells it that we are using a file, specifically the gcal-4.tar.gz file. Running the command creates and populates a new folder by the name of gcal-4. (This name, by the way, follows the naming convention common to most GNU packages: package_name-version.)

Inside the folder, there is an INSTALL file which tells us that the ‘configure’ shell script will try to find correct values for system-dependent variables that are to be used during compilation, and will create a ‘Makefile’ which we may then use to compile the package. Let’s go ahead and run the script.

./configure

Alas, we are accosted by an error:

configure: error: no acceptable C compiler found in $PATH

It seems our newly-installed operating system is missing a C compiler. It’s simple enough to install one:

sudo dnf install gcc

GCC is the GNU Compiler Collection; it should give us what we need. Let’s run the configure script again:

./configure

A long list of statements cascades across the terminal, each announcing that it has checked something. A few seconds pass and we are told that all the checks are done. We find now in the same folder a Makefile. We’ll invoke the make command, which will use the makefile to convert the source code of the package into executable binaries:

make

Another list of statements informs us of the steps taken to build the package, and at the end of it we find that there is a new gcal file inside the src directory. Let’s try to run it.

./gcal

screen6

The program performs as advertised!

Unfortunately, the documentation for gcal is a little overwhelming at the moment, so I won’t explore all of its functions in this post, but here’s a list of this year’s astronomical events (using GMT; this can be configured):

[andrei@localhost src]$ ./gcal -n --astronomical-holidays
Eternal holiday list: The year 2016 is A leap year
New Moon 01:30 (Ast) - Sun, Jan 10th 2016 = -19 days
Waxing Half Moon 23:26 (Ast) - Sat, Jan 16th 2016 = -13 days
Full Moon 01:46 (Ast) - Sun, Jan 24th 2016 = -5 days
Waning Half Moon 03:28 (Ast) - Mon, Feb 1st 2016 = +3 days
New Moon 14:39 (Ast) - Mon, Feb 8th 2016 = +10 days
Waxing Half Moon 07:46 (Ast) - Mon, Feb 15th 2016 = +17 days
Full Moon 18:20 (Ast) - Mon, Feb 22nd 2016 = +24 days
Waning Half Moon 23:11 (Ast) - Tue, Mar 1st 2016 = +32 days
New Moon 01:54 (Ast) - Wed, Mar 9th 2016 = +40 days
Solar Eclipse/Total 01:57 (Ast) - Wed, Mar 9th 2016 = +40 days
Waxing Half Moon 17:03 (Ast) - Tue, Mar 15th 2016 = +46 days
Equinox Day 04:30 (Ast) - Sun, Mar 20th 2016 = +51 days
Full Moon 12:01 (Ast) - Wed, Mar 23rd 2016 = +54 days
Lunar Eclipse/Penumbral 11:47 (Ast) - Wed, Mar 23rd 2016 = +54 days

And then, inside the data/dates directory, we find some more important information:

screen8

Let’s try to build something a little more complicated now. We’ll try to build NetHack, an ASCII dungeon-crawling game (which, coincidentally, just last month released its first major update in twelve years). NetHack is a popular Roguelike (meaning like Rogue) game that we can run in our terminal.

We download the file nethack-360-src.tgz from the official site. The .tgz extension is the same as the tar.gz extension we dealt with earlier. We extract the tarball using the same command.

tar xzf nethack-360-src.tgz

Inside the folder in which the archive has been extracted, there is a README file, which directs us to the sys/unix/Install.unx file, which then directs us to the newer sys/unix/NewInstall.unx. There, we learn that the sys/unix/hints directory contains a file which will help us configure the package. From the sys/unix directory, we run the command

sh setup.sh hints/linux

and everything seems to be okay. Nothing is printed to the terminal, which is usually a good sign. Next, we’re to go to the top directory and run the command

make all

Note that we’re doing this without having had installed any of the package’s dependencies. We’ll see where it gets us and we’ll deal with trouble as it comes.

Several files seem to compile properly, but then we’re met with the following error:

../win/tty/termcap.c:852:20: fatal error: curses.h: No such file or directory
compilation terminated.

The curses.h file can be found in the ncurses-devel package, which is a library containing developer’s tools for ncurses, which, according to the GNU website, “is software for controlling writing to the console screen under Unix, Linux and other operating systems.” Let’s install ncurses-devel:

sudo dnf install ncurses-devel

Now, if we run sudo find / -name curses.h (sudo is needed in order to traverse directories forbidden to us), we see that we now have multiple curses.h files:

find: /usr/include/ncursesw/curses.h
/usr/include/curses.h
/usr/include/ncurses/curses.h

Let’s try to compile NetHack again. The NewInstall.unx file told us to remove all the generated files before retrying to build the package, so from the top level directory (ie. The one into which the tarball had been extracted) we run this command:

make spotless

And then:

make all

Another error:

yacc -d dgn_comp.y
make[1]: yacc: Command not found
Makefile:327: recipe for target 'dgn_yacc.c' failed
make[1]: *** [dgn_yacc.c] Error 127
make[1]: Leaving directory '/home/andrei/Downloads/nethack-3.6.0/util'
Makefile:191: recipe for target 'dungeon' failed
make: *** [dungeon] Error 2

Yacc is a parser generator which, according to the Install.unx file, is being used here to produce dungeon and level compilers. A GNU tool called Bison is compatible with Yacc, and can do the same thing. Let’s install Bison:

sudo dnf install bison

We’ll also need the program flex, which is a lexical analyzer that can tokenize input data to be used by Bison. (There is a lot more to yacc and lex (and Bison and flex), but for the purposes of building the NetHack package, this is all we need to know.)

sudo dnf install flex

We must also edit the sys/unix/Makefile.utl file:

# yacc/lex programs to use to generate *_comp.h, *_lex.c, and *_yacc.c.

# if, instead of yacc/lex you have bison/flex, comment/uncomment the following.

YACC = yacc

LEX = lex

# YACC = bison -y

# YACC = byacc

# LEX = flex

Let’s comment out the yacc and lex lines and uncomment the bison -y and flex lines.

Now, since we’ve edited Makefile.utl, we need to run the setup script again. In sys/unix:

sh setup.sh hints/linux

And then, in the top directory:

make all

This time, there are no errors; we are told that everything is done. Indeed, if we look inside the src directory, we’ll find a new executable file entitled nethack. Let’s run it.

./nethack
/home/andrei/nh/install/games/lib/nethackdir: No such file or directory
Cannot chdir to /home/andrei/nh/install/games/lib/nethackdir.

It seems it wants to be installed. Let’s run the following command to see what would happen if we installed it:

make -n install

This prints all the steps that make install would go through, but it doesn’t actually execute them. It appears that the installation would be wholly contained inside the ~/nh/install/games/ directory. I spent a few minutes creating that directory and copying the necessary files into it by hand, and I was able to run the program, but there’s really no need to do that—nor do I think that anyone would be interested in the (very straightforward) process. Let’s just go ahead and install the package:

make install

Now, in the ~/nh/install/games directory there is an executable file called nethack. Let’s go there and run it:

./nethack

nethack4

It works!

nethack5

It is a hard game.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s