CS 194 Tutorial: Installing software and utility libraries

Notation and conventions

Whenever I show you something to type in at the command shell, I'll prepend it with a dollar sign to represent the shell prompt. Don't type in the dollar sign!

Downloading and unpacking

We'll be using version control systems a lot in this class for distributing libraries. You might be familiar with CVS or Subversion (SVN), perhaps by participating in projects on SourceForge; we'll be using Git, which we'll discuss below. The idea of a version control system is to keep track of changes to a project, so that if make a change that breaks something in your code, you can always go back to a known working version. We'll distribute our code and utility libraries this way so that it will be easier for you to update them if we catch a bug and have to release a new version. Instead of downloading the whole library all over again, you can just check for updates and recompile the affected code as necessary.

Git: a distributed version control system

Git is a version control system (like CVS or Subversion) designed for large, distributed software projects. (Actually, it was written by Linus Torvalds for the Linux kernel.) I favor it because Git archives are easy to host on web pages, and also because configuring CVS or Subversion for multiuser access is tricky and requires administrative access. You can even use Git for your own group projects; talk to Mark for more information about this, if you're interested.

We will give access to the latest version of all code libraries for this class using Git, and will occasionally post tarball versions of the libraries for those who do not have Git installed. Fear not, it's not any harder to use than CVS, but it's a bit different. The Git developers have put together a helpful tutorial called "Everyday GIT With 20 Commands or So." From there, you can access other documentation.

Where do I find Git?

We're working on getting Git installed on the clusters. For now, you can run it on PSI from my EECS home directory. If you are a bash user, just add the following to your .bashrc:

alias git="~mhoemmen/stow/i686/git/bin/git"
and if you are a (t)csh user, add the following to your .cshrc:
alias git "~mhoemmen/stow/i686/git/bin/git"
If you're running on Citris, you should change i686 to ia64 in the commands above. This is because Citris is an Itanium 2 machine and PSI is an x86 machine, so the binary formats are different. (I had to compile the application from source twice, once for each machine.) Neither of these will work on the Sun/Solaris instructional machines, nor will they work on the NERSC machines (as my UC Berkeley cluster home directory isn't exported to the NERSC clusters).

Unpacking tarballs

For those of you who aren't able to install Git, we'll also make available snapshots of our code and utility libraries as tarballs. A "tarball" is a single file, produced by the *nix utility tar, which can be unpacked to produce a directory and its contents. Tar can unpack the file into a directory on your local machine, once you download the tarball. Tarball files typically end in the extension ".tar". Since tarballs are uncompressed by default, most tarballs are compressed before release. Files ending in the extension ".tar.gz" were compressed using the GNU gzip protocol. If you have GNU's version of tar installed (you do if you are using Linux or Cygwin, and you probably do if you are using MacOS X), you can uncompress and unpack it using one command:

$ tar xvzf file.tar.gz 
If you're running on a system without GNU tar installed, like Solaris or IBM's AIX, you can get the same effect with the following:
$ gunzip < file.tar.gz | tar xvf -
Don't forget the hyphen at the end -- it tells tar to process standard input (which was piped from the output of gnuzip). Note that the resulting directory may not have the same name as the tarball's name!

Files with the extension ".tar.bz2" were compressed using the bzip2 protocol. This protocol often yields higher compression ratios, but can take longer to pack and unpack. Again, if you have GNU tar installed, you can uncompress and unpack a bzip2 tarball with one command:

$ tar xvjf file.tar.bz2
Notice the different letter -- j instead of z. The equivalent command systems without GNU tar installed is:
$ bunzip2 < file.tar.bz2 | tar xvf -
As with gzip'd tarballs, the resulting directory may not have the same name as the tarball.

Installing a Java utility library

We'll describe here how to install the Java native timer library.

Utilities and Java packages

Java utilities written for this class are in "subpackages" of the "edu.berkeley.cs.bebop.util" Java package. (I put "subpackages" in quotes because Java packages aren't hierarchical, although they are stored that way.) When you download a utility library, you'll notice that the Java files are in a sub-sub-...-subdirectory of the library's main directory. This is because Java packages require that the directory hierarchy reflect the package "hierarchy." The Java native timer library is in the "edu.berkeley.cs.bebop.util.timer" package.

Recommended installation path

We suggest putting utility libraries in a separate directory hierarchy from the working directories of your programming assignments. This prevents your homework files from getting mixed up with the library files. If one of your files happens to have the same name as one of ours, your file could get clobbered!

Let's say you do all your work in the directory MAINPATH. Then you might have a layout something like the following:

in which util/ contains the utility libraries and hw/ the programming assignments, one directory for each. Within util/ are subdirectories, each one containing a different utility library. We recommend this approach because some of the libraries involve C code as well as Java; it makes setting the CLASSPATH a little more difficult, but ensures that the library directories are self-contained.

Setting the Java CLASSPATH

Both Java's compiler and its bytecode interpreter (or just-in-time compiler) need to know where in the filesystem to look for compiled class files. By default, it looks in the current directory ".", as well as in the place where all the system libraries are (which you can't touch). This list of places where Java looks for class files is called the "classpath."

There are two ways to set the classpath: either by an environment variable, or by command-line flags. The first involves setting the environment variable CLASSPATH to a colon-delimited list of the directories in which Java should search for class files. You can put this in your shell startup scripts so that it is executed automatically at login. For example, with bash:

export CLASSPATH="$HOME/util/java-native-timer"
You can add additional entries to the classpath by separating them with colons. For example:
export CLASSPATH="$HOME/util/java-native-timer:$HOME/util/some-other-library"
If you'd rather not deal with shell environment variables, you can change the classpath on the command line when you invoke javac and java. Make sure that you use the same classpath for both! Just use the "-cp" or "-classpath" options (they are equivalent):
$ javac -cp "$HOME/util/java-native-timer:$HOME/util/some-other-library" MyClass.java
$ java -cp "$HOME/util/java-native-timer:$HOME/util/some-other-library" MyClass

Building the library

First, get the latest version of the Java native timer library into your $HOME/util directory:

$ cd $HOME/util
$ git clone http://www.cs.berkeley.edu/~mhoemmen/cs194/Code/Utilities/java-native-timer.git
Then, change into the java-native-timer directory and view the README file. Make any necessary changes to the Makefile.include configuration file in order to support your local setup. (If you don't know how to edit Makefiles, please talk to one of the GSI's.) Then run "make". Ensure that the build process runs without errors. If the Makefile supports it, try running "make test", and check for errors.

Using the library

In most cases, the library directory will include a Java class with a "main" function. You may have to search in the library's directory structure a bit for it; remember that Java uses the convention that the directory structure reflects the package "hierarchy." That class's source file has examples for using the library. For example, in the edu/berkeley/cs/bebop/util/timer/ subdirectory of java-native-timer, you'll find a TestTimer.java source file, with examples of how to invoke the timer library functions. Note that in your files, you'll need to use the import statement in order to access these functions. For example:

import edu.berkeley.cs.bebop.util.timer.*;
GenericTimer timer = (new TimerFactory()).newTimer();

Last updated 30 August 2007.