CSC270 October 28 Tutorial: Makefiles


Makefiles

[ King 15.4 ] `make' is a Unix program that helps in compiling large programs that occupy more than one source file. Suppose you had a program that occupied three source files: maze.c read.c shortest-matrix.c Typically, what you do is compile each file separately and then link them together: % gcc -c maze.c % gcc -c read.c % gcc -c shortest-matrix.c % gcc -o mazem maze.o read.o shortest-matrix.o The -c flag causes gcc to stop compiling after producing an object file with the .o suffix. Thus, the first three lines above produce the files maze.o read.o shortest-matrix.o The last line above links the three *.o files into an executable called `mazem'. It would be painful if you had to do this by hand every time you made a change in your source code. In fact, you might forget which files you made changes to and then forget to recompile, resulting in a debugging nightmare! `make' deals with this. You must create a `Makefile' that defines the dependences between your files. For example, mazem depends upon maze.o, read.o, and shortest-matrix.o maze.o depends upon maze.c read.o depends upon read.c shortest-matrix.o depends upon shortest-matrix.c The corresponding Makefile would contain mazem: maze.o read.o shortest-matrix.o gcc -o mazem maze.o read.o shortest-matrix.o maze.o: maze.c gcc -c maze.c read.o: read.c gcc -c read.c shortest-matrix.o: shortest-matrix.c gcc -c shortest-matrix.c The lines of the form FILE: FILE1 FILE2 FILE3 ... define dependences, where FILE depends upon FILE1 FILE2 FILE3 ... If you change any one of the file to the right of the colon, `make' will recreate the file to the left of the colon. WARNING: There must be at least one TAB after the colon. Otherwise, `make' will not work. The line below the dependency line gives a Unix command to recreate FILE from FILE1, FILE2, FILE3, ... There can be more than one line if necessary. WARNING: These line must also start with TABs. NOTE: If a *.o file depends only upon a *.c file of the same name, no dependency line is necessary; `make' knows what to do. Thus, the Makefile above could be shortened to: mazem: maze.o read.o shortest-matrix.o gcc -o mazem maze.o read.o shortest-matrix.o

Including compilation flags

There are several variables that can be used in the Makefile. The most important is CC, which is the string used by `make' to run the C compiler. If you want to include flags with every C compilation, include the following at the top of your Makefile: CC = gcc -g -Wall Then `make' will use that string every time it does a C compilation. However, you must then use $(CC) in your makefile everywhere that you do a compilation. The Makefile would change to CC = gcc -g -Wall mazem: maze.o read.o shortest-matrix.o $(CC) -o mazem maze.o read.o shortest-matrix.o

Including header files *.h

If your source files depend upon other *.h files that contain definitions, it's often a good idea to state this in the Makefile. For example, if read.c has a line of the form #include "defs.h" then this is reflected in the Makefile as read.o: read.c defs.h Thus, `make' will recompile read.o if there is a change to read.c OR to defs.h. As before, no compilation statement is necessary since `make' knows how to create read.o from read.c.