The make command helps us to manage large programs or groups of programs. When we are working with large files, the compilation/recompilation time is much longer. Most of the time in recompilation we might have changed some part of program. In such cases we don’t need to recompile the program. ‘make’ command helps us in this aspect of compilation.
The make program aids you in developing your large programs by keeping track of which portions of the entire program have been changed, compiling only those parts of the program which have changed since the last compile.
By creating a descriptor file containing dependency rules, macros and suffix rules, you can instruct ‘make’ to automatically rebuild your program when one of the program’s component files is modified. Make is smart enough to only recompile the files that were affected by changes thus saving compile time.
Lets look at what happens when we compile a C program. The three different tasks required to produce the executable program are as follows:
Compile green.o: cc -c green.c
Compile blue.o: cc -c blue.c
Link the parts together: cc green.o blue.o
Now lets see how ‘make’ command works with an example:
Suppose we have three source files file1.c, file2.c, and file3.c. An include file, mydefs.h, is required by files file1.c and file2.c. We have a descriptor file called ‘prog1’ If you wanted to compile this file from the command line using C++ the command would be
% CC -c prog1 file1.cc file2.cc file3.cc
This command line is rather long to be entered many times as a program is developed and is prone to typing errors. A descriptor file could run the same command better by using the simple command
% make prog1
or if prog1 is the first target defined in the descriptor file
Now lets look how to write a descriptor file. To operate ‘make’ needs to know the relationship between your program’s component files and the commands to update each file. This information is contained in a descriptor file (prog1) you must write called Makefile or makefile.
OBJS = file1.o file2.o file3.o prog1 : $(OBJS) CC -c prog1 $(OBJS) file1.o : file1.c mydefs.h CC -c file1.cc file2.o : file2.c mydefs.h CC -c file2.c file3.o : file3.cc CC -c file3.c clean : rm $(OBJS)
Let’s go through the example to see what make does by executing with the command make prog1 and assuming the program has never been compiled.
1)make finds the target prog1 and sees that it depends on the object files file1.o file2.o file3.o
2)make next looks to see if any of the three object files are listed as targets. They are so make looks at each target to see what it depends on. make sees that file1.o depends on the files file1.c and mydefs.h.
3)Now make looks to see if either of these files are listed as targets and since they aren’t it executes the commands given in file1.o’s rule and compiles file1.c to get the object file.
4)make looks at the targets file2.o and file3.o and compiles these object files in a similar fashion.
5)make now has all the object files required to make prog1 and does so by executing the commands in its rule.