Using make and Makefiles

Compiling C consits of several steps:

  1. pre-processing
  2. create the object files
  3. link the object files into an executable
make is an utility for compiling executables from many modules. make takes as input a file (default name: Makefile) that specifies the rules on how the executable are to be built. Compiling can be a time-consuming, CPU-intensive process. When you change a file, you don't want to re-compile everything. That would be slow and not elegant. make will determine precisely the files that need to be recompiled and compile only those.

Using make

  1. Create a file called Makefile that specifies the dependencies and the rules for building the executable.
  2. Run make
    bid19628:startup ltoma$ make
Below is the simplest Makefile for compiling hello.c:
bid19628:startup ltoma$ cat Makefile 
all: hello.c
	gcc -g -Wall -o hello hello.c

	$(RM) hello
bid19628:startup ltoma$ make
gcc -g -Wall -o hello hello.c
bid19628:startup ltoma$ 
A more generic version:
 # the compiler: gcc for C program, define as g++ for C++
  CC = gcc

  # compiler flags:
  #  -g    adds debugging information to the executable file
  #  -Wall turns on most, but not all, compiler warnings
  CFLAGS  = -g -Wall

  # the build target executable:
  TARGET = hello

  all: $(TARGET)

  $(TARGET): $(TARGET).c
  	$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c

  	$(RM) $(TARGET)
And an example of building several executable from multiple .o files:
PROGRAMS = blockit visblocks


CC = gcc -std=c99
CFLAGS = -m64 -Winline -g -DNDEBUG -O3 -Wall

LIBS = -lm

blockit:  blockit.o blgrid.o rtimer.o 
	$(CC) -o $@ blockit.o blgrid.o rtimer.o  $(LIBS)
visblocks: visblocks.o blgrid.o rtimer.o visblgrid.o
	$(CC) -o $@ visblocks.o blgrid.o rtimer.o visblgrid.o $(LIBS)

blockit.o: blockit.c blgrid.h rtimer.h 
	$(CC) $(CFLAGS) -c blockit.c -o blockit.o 

blgrid.o: blgrid.c blgrid.h 
	$(CC) $(CFLAGS) -c blgrid.c -o blgrid.o 

rtimer.o: rtimer.c rtimer.h
	$(CC) $(CFLAGS) -c rtimer.c -o rtimer.o 

visblocks.o: visblocks.c blgrid.h rtimer.h
	$(CC) $(CLFAGS) -c visblocks.c -o visblocks.o
visblgrid.o: visblgrid.c visblgrid.h blgrid.h
	$(CC) $(CLFAGS) -c visblgrid.c -o visblgrid.o 

	rm -f *.o blockit visblocks