make is a Unix tool that simplifies building programs when they are composed from many files, or building many programs simultaneously. It is able to determine when source files have changed and rebuild only those components needed for an update.
This is just a quick overview, see the man page for more details. A more complete reference can be found in the GNU make manual.
Run make: All you need to do is run the program from the command line without any arguments.
% make
You can also specify a "target" or make use of multiple processors.
# compile a specific target % make target_name # clean up things (rule needs to be in the Makefile) % make clean # use multiple processors (in this case 3) % make -j 3
While it may seem that Makefiles are a bit arcane, they can be readily understood with just a little bit of information.
# comments if desired
target: dependency1 dependency2 ...
<tab> command
Here is a simple makefile to build a C program.
# build a program from 2 files and one shared header
CC = gcc
CFLAGS = -g
program: source1.c source2.c
$(CC) $(CFLAGS) -o program source1.c source2.c
This is OK for a small program, but you can only recompile the parts that have changed with just a few changes.
# build a program from 2 files and one shared header
CC = gcc
CFLAGS = -g
source1.o: source1.c
$(CC) $(CFLAGS) -c source1.c
source2.o: source2.c
$(CC) $(CFLAGS) -c source2.c
program: source1.o source2.o
$(CC) $(CFLAGS) -o program source1.o source2.o
If you are using the proper variables (e.g., CC and CFLAGS), then you can take advantage of make's builtin rules for creating object files. For example, it knows how to properly make a .o file from a .c file. Run make --print-data-base to see all the builtin rules.
This means you can shorten the above makefile down to just one specified build rule, with the rest being implicit. (I've added some additional debugging in to the compiler flags.)
# build a program from 2 files and one shared header
CC = gcc
CFLAGS = -g -Wall -pedantic
program: source1.o source2.o
$(CC) $(CFLAGS) -o program source1.o source2.o
There are also a variety of automatic variables that make uses when evaluating a rule. Two that I find useful are:
So we can further simplify things by writing:
# build a program from 2 files and one shared header
CC = gcc
CFLAGS = -g -Wall -pedantic
program: source1.o source2.o
$(CC) $(CFLAGS) -o $@ $^
For other languages, other variables are used. For example: