programA: programBthen we follow it with a set of shell commands that will ``bring programA up to date''. Each rule and its associated group of commands is called a ``stanza''. The command line in the stanza MUST start with a TAB character. This is the most common mistake when writing Makefiles.
Lets put together a simple Makefile for this project. Make will execute the first stanza in a Makefile by default. By convention this has the name ``all''. So our Makefile looks like:
all: mainprog mainprog: mainprog.o fun1.o fun2.o cc -o mainprog fun1.o fun2.o mainprog.o mainprog.o: mainprog.c cc -c mainprog.c fun1.o: fun1.c cc -c fun1.c fun2.o: fun2.c cc -c fun2.cThe above logic reads:
to bring all up to date => bring mainprog up to date to bring mainprog up to date => bring mainprog.o fun1.o fun2.o up to date to bring mainprog.o up to date => compile mainprog.c to bring fun1.o up to date => compile fun1.c to bring fun2.o up to date => compile fun2.c to bring mainprog up to date => link fun1.o fun2.o mainprog.oSo we start out with this set of files:
bash-2.05b# ls -l total 36 -rw-r--r-- 1 root root 61 Mar 9 06:07 fun1.c -rw-r--r-- 1 root root 13 Mar 9 06:07 fun1.h -rw-r--r-- 1 root root 61 Mar 9 06:08 fun2.c -rw-r--r-- 1 root root 13 Mar 9 06:08 fun2.h -rwxr-xr-x 1 root root 11897 Mar 9 18:28 mainprog -rw-r--r-- 1 root root 219 Mar 9 18:30 mainprog.c -rw-r--r-- 1 root root 208 Mar 9 18:30 Makefileand we type make. We can see the compile steps take place in the order given above.
bash-2.05b# make cc -c mainprog.c cc -c fun1.c cc -c fun2.c cc -o mainprog fun1.o fun2.o mainprog.oand we can see all of the files that got created.
bash-2.05b# ls -l total 48 -rw-r--r-- 1 root root 61 Mar 9 06:07 fun1.c -rw-r--r-- 1 root root 13 Mar 9 06:07 fun1.h -rw-r--r-- 1 root root 788 Mar 9 18:34 fun1.o -rw-r--r-- 1 root root 61 Mar 9 06:08 fun2.c -rw-r--r-- 1 root root 13 Mar 9 06:08 fun2.h -rw-r--r-- 1 root root 788 Mar 9 18:34 fun2.o -rwxr-xr-x 1 root root 11905 Mar 9 18:34 mainprog -rw-r--r-- 1 root root 219 Mar 9 18:30 mainprog.c -rw-r--r-- 1 root root 988 Mar 9 18:34 mainprog.o -rw-r--r-- 1 root root 208 Mar 9 18:30 Makefileand we can see that mainprog works.
bash-2.05b# ./mainprog I am the main program I depend on fun1 and fun2 change 1 applied fun1 called fun2 called bash-2.05b#Suppose we change fun2.c to output ``fun2 invoked''. It will look like:
#include <stdio.h>
void fun2()
{ printf("fun2 invoked\n");
}
Changing the file means that the fun2.c file is newer than
fun2.o. make will follow instructions and bring fun2.o up
to date by compiling fun2.c. However, make now knows that
mainprog depends on fun2.o so it will relink mainprog. Notice that
it does not need to compile fun1.c or mainprog.c as these files
have not changed. So we see:
ls -l total 52 -rw-r--r-- 1 root root 61 Mar 9 06:07 fun1.c -rw-r--r-- 1 root root 13 Mar 9 06:07 fun1.h -rw-r--r-- 1 root root 788 Mar 9 18:38 fun1.o -rw-r--r-- 1 root root 62 Mar 9 18:43 fun2.c -rw-r--r-- 1 root root 61 Mar 9 06:08 fun2.c~ -rw-r--r-- 1 root root 13 Mar 9 06:08 fun2.h -rw-r--r-- 1 root root 788 Mar 9 18:38 fun2.o -rwxr-xr-x 1 root root 11905 Mar 9 18:38 mainprog -rw-r--r-- 1 root root 219 Mar 9 18:30 mainprog.c -rw-r--r-- 1 root root 988 Mar 9 18:38 mainprog.o -rw-r--r-- 1 root root 208 Mar 9 18:30 Makefile bash-2.05b# make cc -c fun2.c cc -o mainprog fun1.o fun2.o mainprog.o bash-2.05b# ./mainprog I am the main program I depend on fun1 and fun2 change 1 applied fun1 called fun2 invoked bash-2.05b# ls -l total 52 -rw-r--r-- 1 root root 61 Mar 9 06:07 fun1.c -rw-r--r-- 1 root root 13 Mar 9 06:07 fun1.h -rw-r--r-- 1 root root 788 Mar 9 18:38 fun1.o -rw-r--r-- 1 root root 62 Mar 9 18:43 fun2.c -rw-r--r-- 1 root root 61 Mar 9 06:08 fun2.c~ -rw-r--r-- 1 root root 13 Mar 9 06:08 fun2.h -rw-r--r-- 1 root root 788 Mar 9 18:43 fun2.o -rwxr-xr-x 1 root root 11905 Mar 9 18:43 mainprog -rw-r--r-- 1 root root 219 Mar 9 18:30 mainprog.c -rw-r--r-- 1 root root 988 Mar 9 18:38 mainprog.o -rw-r--r-- 1 root root 208 Mar 9 18:30 MakefileIf we were to try make again without changing anything we get:
bash-2.05b# make make: Nothing to be done for `all'.
So the basic idea is that you can write rules that tell make exactly how to construct your program.