Programming in Plato’s Cave 179 whether the files are out of date with respect to each other. A small depen- dency graph, or Makefile, is shown below: program: source1.o source2.o cc -o program source1.o source2.o source1.o: source1.c cc -c source1.c source2.o: source2.c cc -c source2.c In this graph, the nodes are program, source1.o, source2.o, source1.c, and source2.c. The node program depends on the source1.o and source2.o nodes. Here is a graphical representation of the same makefile: When either source1.o or source2.o is newer than program, make will regenerate program by executing the command cc -o program source1.o source2.o. And, of course, if source1.c has been modified, then both source1.o and program will be out of date, necessitating a recompile and a relink. While make’s model is quite general, the designers forgot to make it easy to use for common cases. In fact, very few novice Unix programmers know exactly how utterly easy it is to screw yourself to a wall with make, until they do it. To continue with our example, let’s say that our programmer, call him Dennis, is trying to find a bug in source1.c and therefore wants to compile this file with debugging information included. He modifies the Makefile to look like this: program source1.o source2.o source1.c source1.c
180 Programming program: source1.o source2.o cc -o program source1.o source2.o # I'm debugging source1.c -Dennis source1.o: source1.c cc -c -g source1.c source2.o: source2.c cc -c source2.c The line beginning with “#” is a comment. The make program ignores them. Well, when poor Dennis runs make, the program complains: Make: Makefile: Must be a separator on line 4. Stop And then make quits. He stares at his Makefile for several minutes, then several hours, but can’t quite figure out what’s wrong with it. He thinks there might be something wrong with the comment line, but he is not sure. The problem with Dennis’s Makefile is that when he added the comment line, he inadvertently inserted a space before the tab character at the begin- ning of line 2. The tab character is a very important part of the syntax of Makefiles. All command lines (the lines beginning with cc in our example) must start with tabs. After he made his change, line 2 didn’t, hence the error. “So what?” you ask, “What’s wrong with that?” There is nothing wrong with it, by itself. It’s just that when you consider how other programming tools work in Unix, using tabs as part of the syntax is like one of those pungee stick traps in The Green Berets: the poor kid from Kansas is walking point in front of John Wayne and doesn’t see the trip wire. After all, there are no trip wires to watch out for in Kansas corn fields. WHAM! You see, the tab character, along with the space character and the newline character, are commonly known as whitespace characters. Whitespace is a technical term which means “you should just ignore them,” and most pro- grams do. Most programs treat spaces and tabs the same way. Except make (and cu and uucp and a few other programs). And now there’s nothing left to do with the poor kid from Kansas but shoot him in the head to put him out of his misery.
Previous Page Next Page