| .IGNORE:
.SILENT: mirror: input.o mirror.o process.o output.o
mirror.o: mirror.cc
input.o: input.cc
output.o: output.cc
process.o: process.cc
clean:
distclean:
again:
|
All object files are made using g++. On other machines that
may be cxx, cpp, or something the like. So let's define a macro
for the C++ compiler:
| C++ = g++ |
The command line options are also different for different compilers
so it's a good idea to have a macro for them:
| C++-Flags = -c -Wall |
On some machines the command to remove files is rm (or
rm -f), on others del, some use delete, some
erase, and some even discard.So that's another candidate
for a macro:
| RM = rm -f |
Even make may not always be called make (though I know of no system
where this is the case):
| MAKE = make |
In our example the linker is also g++. In general that need not be the
case. So we define the following two macros:
| LINKER = g++
LINKER-FLAGS = -o |
The meaning of the following two macros is obvious:
| OBJS = input.o mirror.o process.o output.o
TARGET = mirror |
After these changes the present state of the Makefile is Makefile6:
| C++ =
g++
C++-FLAGS = -c -Wall LINKER = g++ LINKER-FLAGS = -o RM = rm -f MAKE = make OBJS = input.o mirror.o process.o output.o TARGET = mirror .IGNORE:
$(TARGET): $(OBJS)
mirror.o: mirror.cc
input.o: input.cc
output.o: output.cc
process.o: process.cc
clean:
distclean:
again:
|
| <filename>.o: <filename>.cc
$(C++) $(C++-FLAGS) <filename>.cc |
To avoid all these lenthy entries in a Makefile there are inference
rules: They describe the 'standard procedure' of making files of type b
from files of type a. In this case the rule to make an object file from
a given C++ file is
| .cc.o:
$(C++) $(C++-FLAGS) $< |
or alternatively you could use
| .cc.o:
$(C++) $(C++-FLAGS) $*.cc |
It's easy to see what $< and $* mean but I'll come
back to that in just a moment. First I will change the rule for making
the target 'mirror' so that it makes use of another strange-looking predefined
macros:
| $(TARGET): $(OBJS)
$(LINKER) $(LINKER-FLAGS) $@ $(OBJ) |
Now let's have a look at the meaning of $*, $<, and $@:
$* ist the current target without an extension (the
base file name) with path. For example, in
| input.o: input.cc
$(C++) $(C++-FLAGS) $*.cc |
the value of $* is input. $* is commonly used only in inference rules and command lines.
$@ is the current target (including extension, if any).
For example, in
| mirror: $(OBJS)
$(LINKER) $(LINKER-FLAGS) $@ $(OBJS) |
the value of $@ is mirror.
$< is a dependent file out-of date with the target
file. For example,
| .cc.o:
$(C++) $(C++-FLAGS) $*.cc |
Notice that $<, in an inference rule such as .cc.o, is equivalent to $*.cc (as already mentioned).
Just to remind you: Your Makefile should now look like Makefile7:
| C++ =
g++
C++-FLAGS = -c -Wall LINKER = g++ LINKER-FLAGS = -o RM = rm -f MAKE = make OBJS = input.o mirror.o process.o output.o TARGET = mirror .IGNORE:
$(TARGET): $(OBJS)
.cc.o:
clean:
distclean:
again:
|
| OBJS = input.o mirror.o process.o output.o |
to read
| OBJS = input.o \
mirror.o \ process.o \ output.o |
| C++ =
g++ # use GNU
C++ compiler
C++-FLAGS = -c -Wall # warn all LINKER = g++ # use GNU C++ as linker LINKER-FLAGS = -o # flags for linker RM = rm -f # how to remove files MAKE = make # name of make utility # you cannot add comments after the continuation character! OBJS = input.o \ mirror.o \ process.o \ output.o TARGET = mirror # name of executable .IGNORE:
# ignore problems (as far as possible)
$(TARGET): $(OBJS)
.cc.o:
# remove object files and core (if any)
# remove object files, core dump, and executable (if any)
# remove object files, core dump, and executable (if any) and
|
| .SUFFIXES: |
If you do that you have to list all suffixes that your Makefile does
support. In the above case that would be
| .SUFFIXES: .o .cc |
You can also use .SUFFIXES to add rules to the predefined ones (in precisely the same manner as in the example above).
| info:
echo $(USER) |
Surely this is not a very useful example. Finding more useful ones is
left to the reader. Now, your Makefile should look like Makefile9:
| C++ =
g++ # use GNU
C++ compiler
C++-FLAGS = -c -Wall # warn all LINKER = g++ # use GNU C++ as linker LINKER-FLAGS = -o # flags for linker RM = rm -f # how to remove files MAKE = make # name of make utility # you cannot add comments after the continuation character! OBJS = input.o \ mirror.o \ process.o \ output.o TARGET = mirror # name of executable .IGNORE:
# ignore problems (as far as possible)
$(TARGET): $(OBJS)
.cc.o:
# remove object files and core (if any)
# remove object files, core dump, and executable (if any)
# remove object files, core dump, and executable (if any) and
# echo username
|