4.3 Including other files

It is cool to have main.d and array.d. But they are only informational up to this point. We can, indeed, include them in the Makefile:

CXXFLAGS = -O -Wall -g # affects the compilation of C++ code  
CFLAGS = -O -Wall -g # affects the compilation of C code  
LDFLAGS = -g # affects the linker  
ASFLAGS = --gstabs # affects the assembler  
CSRC = main.c array.c # source files in C  
CCSRC = someclass.cc # source files in C++  
AASRC = someasm.S # source files in assembly language (needs CPP)  
ASRC = simpleasm.s # source files in assembly language (does not need CPP)  
EXE = main  
 
$(EXE):  $(CSRC:.c=.o) $(CCSRC:.cc=.o) $(AASRC:.S=.o) $(ASRC:.s=.o)  
 
#array.o:  array.c array.h  
# gcc $(CXXFLAGS) -c array.c  
 
#main.o:  main.c array.h  
# gcc $(CXXFLAGS) -c main.c  
 
%.d: %.c  
 set -e; gcc $(CXXFLAGS) $^ -MM \  
| sed ’s/\($*\)\.o[ :]*/\1.o $@ : /g’ > $@; \  
[ -s $@ ] || rm -f $@  
 
%.d: %.cc  
 set -e; gcc $(CXXFLAGS) $^ -MM \  
| sed ’s/\($*\)\.o[ :]*/\1.o $@ : /g’ > $@; \  
[ -s $@ ] || rm -f $@  
 
%.d: %.S  
 set -e; gcc $(CXXFLAGS) $^ -MM \  
| sed ’s/\($*\)\.o[ :]*/\1.o $@ : /g’ > $@; \  
[ -s $@ ] || rm -f $@  
 
clean:  
rm -f $(EXE) \  
  $(CSRC:.c=.o) $(CSRC:.c=.d) \  
  $(CCSRC:.cc=.o) $(CCSRC:.cc=.d) \  
  $(AASRC:.S=.o) $(AASRC:.S=.d) \  
  $(ASRC:.s=.o)  
 
include $(CSRC:.c=.d)  
include $(CCSRC:.cc=.d)  
include $(AASRC:.S=.d)  

Here, the statement “include $(CSRC=.c=.d) is saying for each source file listed in CSRC, include its .d (dependency) file. Because these files already specify that array.o depends on array.c and array.h, there is no need to explicitly state that rule anymore. The # symbol states that whatever follows on the same line should be ignored.

Note that in this file, we also have CCSRC corresponding to C++ source files (with .cc extension), AASRC corresponding to assembly language source files that requires pre-processor macro expansion (with .S extension), and ASRC corresponding to assembly language source files that do not require pre-processor macro expansion.

Now, go ahead and update array.h, then run make again.

The variable LDFLAGS is similar to to CFLAGS, but instead of specifying compile-time flags, it specifies link time flags. Here we only specify -g to include debug information in the executable.

The variables CFLAGS, CXXFLAGS, ASFLAGS and LDFLAGS are special because they are used by the default Makefile rules. You need to use these specific names if implicit rules (like those contained in .d files) are used.

The special target clean is used if you want to delete all the created files.