CSE 303 Homework 5 - How To Build

What To Build?

There are really four separate programs hanging out in the skeleton code: btdriver, dllistdriver, lexerdriver, and hw5. Each has a main(). While they (may) share use of the data structure implementation code, each is built separately.

Prerequisites

The system you're building on must have flex installed. This is required even if you do not try to rebuild the the lexer library -- simply building your application requires linking against the flex library (named "fl"), because the lexer library requires some flex routines. (The flex library is most often named /usr/lib/libfl.a, but could be elsewhere. If flex is installed, $ which flex should return something sensible.)

If you're working on a cygwin system and don't have flex installed, re-run cygwin setup to install it. For other kinds of systems, use whatever procedure is typical for installing packages.

Build Problems

Remember that compiling and linking are separate steps, even if you type just a single gcc command that causes both to happen. (Remember also that when compiling, each .c file is compiled completely separately from the others, even if you have issued a single command that eventually causes many of them to be compiled.) Different errors are likely, depending on the step.

For compiling, you may have forgotten to #include a .h file that gives prototypes for routines you call but don't define in the exact same .c file. Or, you may have remembered, but made a mistake in how you named the .h file. Some .h files live at the top level of the skeleton's directory tree. So, for instance, you'd say

#include "lexer.h"
in hw5.c. Some live a level lower, though:
#include "bt/bt.h"

For linking, what is required is that you tell gcc where to find all the compiled versions of all the instructions in all code that might be executed by the program. In the simplest case, this means naming all the .o files that are required by that program. Sometimes, though, compiled code is made available in libraries, rather than by handing around .o files. The compiled code for the lexer routines has been distributed that way, in the library named liblexer.a Additionally, that code (the lexer's) needs the flex library code. That's a library that lives off in some system directory (just like stdio.h lives in /usr/include, installed libraries live in some system directory). More on that in a minute, but for now just keep in mind that you might need to tell gcc to include the flex code when linking.

Building From the Command Line, or With a Script

Here are the commands to link the various applications. It should be clear from looking at them that you first have to compile each of the files they require (and that the .o has to end up in the proper directory). All of these commands are done in the root skeleton code directory.

btdriver

$ gcc <flags> -o btdriver bt/bt.o btdriver.o

dllistdriver

$ gcc <flags> -o dllistdriver dllist/dllist.o dllistdriver.o

lexerdriver

$ gcc <flags> -o lexerdriver lexerdriver.o liblexer.a -lfl

hw5

$ gcc <flags> -o hw5 dllist/dllist.o bt/bt.o hw5.o liblexer.a -lfl

In each case, <flags> are flags you might want to give, e.g., -Wall. If you want to try using gdb, you should specify the -g flag, both for compiling and linking.

This application is small enough that you can afford to compile and link every time you run. Therefore, at the very least you should write one or more little shell scripts that issue the commands needed to build for you -- if you don't, I'll bet you end up spending a lot more time retyping the commands, or hitting the up arrow, or looking them up here, etc., than it would have cost you to put them in a script file and have them once and for all.

Using make

We haven't yet talked about make in class, and I'm not going to try to explain it here. But, as everything is set up to use it, all you should have to do is issue appropriate commands. make will then both compile and link. The upside of this is that it's fast -- a tiny bit of typing and you're done. The downside is that it isn't entirely clear what has happened, so that if things go wrong you might not notice, and that if anything does go wrong you won't know how to fix it (except to revert to the script build approach, above).

btdriver

$ make btdriver

dllistdriver

$ make dllistdriver

lexerdriver

$ make lexerdriver

hw5

$ make

All of the above

$ make all

Look in the file README.make for more info.

Note: The command make clean will delete files. It deletes only things that normally are eminently deletable, because they can be rebuilt (.e.g, the .o files that come from compiling .c files). However, if you've done something extremely unanticipated (like named the file containing the bulk of your code hw5.o), executing make clean may have unfortunate effects.

No other use of make will delete anything, so it's relatively safe to try make commands as a way of clarifying just what they'll do. (However, they will compile things, and that will overwrite .o files and the like, so if you did the unusual thing above there will still be trouble. Of course, the same trouble would have ensued had you simply tried to compile by issuing gcc commands to the shell.)