So, let's say that you have been building a parser from the file "myparse.c", and have been building an executable called "myparse". Your makefile may look something like this:
myparse: myparse.c support.o
cc -o myparse myparse.c support.o
support.o: support.c
cc -c -o support.o support.c
Now, the evil Randy comes along and says "I want your main project source file
to be named `parser.c' and the executable to be named `fred'." Why? Because
he is a petty, vindictive, and merciless TA, that's why. It doesn't matter if
it makes no sense: the grader gets what he wants, or you get a 0.
You now have two choices:
I'm quite sure you have all had enough practice to handle the first option without any further instruction, so let's try the second. If we have written a decent makefile, we should be able to change the rules to use the new names.
The original makefile was:
myparse: myparse.c support.o
cc -o myparse myparse.c support.o
support.o: support.c
cc -c -o support.o support.c
The program needs to be called "fred" rather than "myparse", so we can simply
change the rule that generates "myparse". In this rule we change the target so
that "make" looks for "fred" rather than "myparse" when deciding if to build
it. We also need to change the command to build "myparse" so that it builds
"fred" instead. The new rule looks like this:
fred: myparse.c support.o
cc -o fred myparse.c support.o
That was simple. Now we need to figure out how to handle Randy's idiotic
decree about the name of our source file. Essentially, we must change
"myparse.c" to "parser.c" everywhere it appears in the makefile. This isn't
really that difficult either. In this example we only have two places where
"myparse.c" is mentioned, both in the rule for what is now "fred":
fred: parser.c support.o
cc -o fred parser.c support.o
Our new makefile looks like this:
fred: parser.c support.o
cc -o fred parser.c support.o
support.o: support.c
cc -c -o support.o support.c
Of course, you will have to rename the source file itself, which may cause other problems, but if you don't panic, and don't build overly complicated makefiles, you should be able to handle it.
For the record it is unlikely that we will have you change the name of a file on short notice. It has happened before though, so you should be able to handle the situation.
Let's look at another solution to the same problem. This time, we will add a rule to the makefile instead of changing the current rules. The original makefile was again:
myparse: myparse.c support.o
cc -o myparse myparse.c support.o
support.o: support.c
cc -c -o support.o support.c
We need to have the executable "fred" made, but there is no reason we can't
make "myparse" instead and then rename it. So let's add a rule to do just
that:
fred: myparse
mv myparse fred
myparse: myparse.c support.o
cc -o myparse myparse.c support.o
support.o: support.c
cc -c -o support.o support.c
Now, when we build "fred", we actually build "myparse" then rename it to
"fred". Easy enough. No panic necessary. We can do the same type of thing
for "parser.c" and "myparse.c" by adding a rule that copies "parser.c" to
"myparse.c":
fred: myparse
mv myparse fred
myparse.c: parser.c
cp parser.c myparse.c
myparse: myparse.c support.o
cc -o myparse myparse.c support.o
support.o: support.c
cc -c -o support.o support.c
Notice that we didn't move parser.c to myparse.c, we just have
make copy it whenever we change parser.c. We still have to rename the source
file from "myparse.c" to "parser.c" (because Randy said so, remember), but we
don't have to search the entire makefile for each occurence of "myparse.c".
The last solution was inefficient though (from a filespace perspective), so we might try to use another tool that we have learned about: variables.
As we write the file, we could use variables to refer to the programs we wish to build and their sources. Suppose we use EXECFILE and SRCFILE to represent these files respectively. We would then have the following original makefile:
EXECFILE=myparse
SRCFILE=myparse.c
${EXECFILE}: ${SRCFILE} support.o
cc -o ${EXECFILE} ${SRCFILE} support.o
support.o: support.c
cc -c -o support.o support.c
Changing the file to build "fred" from "parser.c" only requires a change in
the definition of the variables EXECFILE and SRCFILE:
EXECFILE=fred
SRCFILE=parser.c
${EXECFILE}: ${SRCFILE} support.o
cc -o ${EXECFILE} ${SRCFILE}support.o
support.o: support.c
cc -c -o support.o support.c
This is easy when first writing the makefile, and makes changes easier later,
but is more work than using the first solution once the makefile is written
without using the variables.