In reality (i.e., in companies and in university research) most codes are split into many different files with different people working simultaneously on them.
The compiler must be able to compile the files separately, and then link all of them together into a working program. When a file changes, it is necessary to compile that file, and usually others that depend on it. There is a mechanism called "make" or "makefile" to keep track of this automatically. Next to a text editor, it is probably the most important tool in a computer scientist's toolchest. Make is the Unix version of this; other systems such as Microsoft Visual C++ usually come with similar "build" facilities.
The name "make" also has the advantage of leading to great puns (making out, making your way, etc.)
touch blurbthen either:
blurb: touch blurb \______/ /\ <TAB> <RET>There must be a tab character at the start of the second line before the word "touch". If you downloaded the sample makefile with Netscape it may have changed the tab to spaces, which is why we asked that you just directly copy the file to your directory.
The make file must be called "makefile" or "Makefile" (actually, it can be called anything and then invoked using the -f option for the make command, but for now let's keep things simple). When you type "make" in the directory where the makefile lives, in the example above it will print
touch blurband actually execute that same command. If "blurb" did not exist in your directory you will see that it now does - although as an empty file. If you now type "make" again, you will see
make: `blurb' is up to date.When the file named in the first line exists and is "up-to-date", make recognizes nothing need be done and ... doesn't do anything.
Now add some lines to the file "makefile":
blurb: blob touch blurb blob: touch bloband remove the file "blurb" from your directory. When you type "make" you get
touch blob touch blurbwhich shows that "blob" was created first followed by "blurb". The way to read this is that
< target >: < dependent 1 > < dependent 2 > .... < command > < command >When you type "make" with no arguments, a recursive "update" function is called on the target of the first rule in the file. Make can also be called with an argument, e.g. "make blob", which calls update on a different target. The update function could be written like this in pseudo-code
update(target) { for (i in dependents(target)) do update(i) if ((exists(target) == false) or (date(target) < last_date(dependents(target)))) execute commands }In the example above the first call to make causes it to invoke update(blurb). The rule in the makefile for blurb has blob as a dependent. So update(blob) is called. Helper has no dependents, and it doesn't exist, so the command "touch blob" is executed. Then update(blob) returns back to update(blurb). Since blurb doesn't exist, it is created as well. Yep, that is the usual "explanation of a recursive function call" that is pretty darned weird, but if you parse it carefully ... never mind.
The second time we type "make", update(blurb) calls update(blob) again, but now blob exists and since it has no dependents, the command "touch blob" is not executed. It then returns back to update(blurb). Now blurb exists and it has a dependent, but the dependent was created slightly before it. So the date comparison fails and blurb is unchanged.
Now you figure out what would happens if you do:
The command in the rule can be any Unix command. Usually it is a command that creates the target. e.g. in the rules for blurb and blob, the touch command actually created files blurb and blob, or updated their dates. A common example is a "clean" rule, which cleans up the directory of all the debris created by the makefile:
blurb: blob touch blurb blob: touch blob clean: rm blurb blobSince clean isn't in any list of dependents, it doesn't get called in any recursive update call. But if you type "make clean", make looks for the rule for "clean", notices that a file named "clean" does not exist, and executes the command "rm blurb blob". That causes blurb and blob to be deleted, but it doesn't cause a file named "clean" to be created. So the next time you type "make clean" it will still try to delete blurb and blob. "make clean" is a standard command to get rid of the individual binaries after a compiling several separate files, since they're usually not needed. OK, if you are really cocky, what happens with this sequence:
make touch clean make clean
CC = cxxand which compiler options to use in
CCFLAGS = -O3 -checkThen when we specified how to compile the codes, we used
$(CC) -c $(CCFLAGS)which is translated into the Unix command
cxx -c -O3 -checkYou can define anything you want, but note
.C.o: $(CC) -c $(CCFLAGS) $<says that every file with a suffix of ".C" should have a corresponding object file with suffix ".o" created, and the way to do that is to apply the command
cxx -c -O3 -checkon every file with suffix ".C". The " < " expands to allow this to be carried out for all files in the current directory with the corresponding suffix.