make automates compilation make regenerates a file if it does not exist or is older than any of its prerequisites. make knows how to generate a file from source files, if just the extension is different. Thus make can generate executable "prg" from object file "prg.o" and "prg.o" from source "prg.c" The simplest make is: make prg This will generate prg from prg.c but assumes that prg.c is self contained and no other source programs such as prg.p, prg.f exist. For more complicated situations a file, by default "Makefile" or "makefile", of commands describing file prerequisites and commands must be given. EXAMPLE: Derived files: reduce <------- initial target program / | \ simplify.o io.o libmatrix.a / | | | | | \ ... Primary files: simplify.c | | io.c add.c | inv.c ... : | | : : | : newio.h matrix.h Although primary files may depend on other primary files (:), never tell make about such dependencies since make should not attempt to update one from the other -- that's a code writer's task. VARIABLES (MACROS): VAR=value sets a variable to value (rest of line up to a comment symbol #) $(VAR) gives value of variable, which is ignored if undefined or null ^ ^ optional if VAR is a single character Some predefined variables and typical values are: CC=cc CFLAGS= LDFLAGS= LDLIBS= RM=rm :::::::: Makefile ::: primitive :: # make when no library functions required. Suppose standard math lib needed PRG=reduce OBJS=simplify.o io.o LDLIBS=-lm $(PRG): $(OBJS) $(CC) $(CFLAGS) $(OBJS) $(LDLIBS) -o $(PRG) ## NB - The previous line starts with a TAB. TAB is required. $(OBJS): newio.h :::::::: Makefile ::: libraries :: # make using library archive # Suppose simplify.c calls a function in add.c and has #include "matrix.h" INCDIR=./lib# path to matrix.h dir - when commenting macros put # flush left LIBDIR=./lib# path to library LDFLAGS=-L$(LIBDIR) LDLIBS=-lmatrix -lm# order usually important CFLAGS=-I$(INCDIR) $(MORECFLAGS) PRG=reduce OBJS=simplify.o io.o $(PRG): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(PRG) $(OBJS): newio.h clean: -@rm -f $(PRG) $(OBJS) install: # no commands here yet test: $(PRG) $(PRG) # add options, redirection from input files, etc. :::::::::::::::::::::::::::::::::: By default the first target is done. Other targets need to be entered on command line. For example, "make clean" will execute the "rm" command. "@" means don't echo command and "-" means continue even if command fails. Dependencies involving the library are usually not listed since we may not own the library or may not want to regenerate it. The library presumably is changed infrequently and updated by a separate make (see below). Otherwise, append the library makefile and add dependencies: $(PRG): $(LIBDIR)/libmatrix.a and $(OBJS): $(INCDIR)/matrix.h A reasonable alternative to this is to "make clean" whenever a library changes. SYNTAX of the make command line (all arguments optional): make -f -n -p VAR="value" VAR2="value2" ... where -f : use instead of Makefile or makefile : use instead of first target in file -n : no execute - show commands only -p : print variables and values - also shows rules VAR="value" : set variable (may drop the quote if value is blank free) Variables are read from make's internal tables, then from user's environment, then from Makefile, and finally from the command line. SYNTAX of dependency lines: target1 target2 ... : dependency1 ... ; commands # comment TAB commands # and/or comment TAB commands # and/or comment ... If no commands are given, then this only adds more dependencies to the targets; the commands are to be found elsewhere. Each line is run by a separate Bourne shell "sh". NOTE THE TABS!!!!!! Also the last line of Makefile should end with newline, otherwise it will be ignored. You can set up your own default rules: .c.o: command(s) to generate file.o from file.c, e.g., $(CC) $(CFLAGS) -c $< ## In default rules, $* is file, $@ is file.o and $< is file.c ## For other rules: $@ is current target and $? is out of date prerequisites ## To have default rules, for example, .in.out , for nonstandard suffixes ## take effect add dependency: .SUFFIXES: .in .out :::::::: Makefile for a lib :::::: L=libmatrix.a # if a function in add.o calls function in transpose.o then # add.o should come before transpose.o to make library search more efficient LOBJS=$L(add.o) $L(inv.o) \ $L(transpose.o) # run archiver just once, after all the .o files are generated $L: $(LOBJS) $(AR) $(ARFLAGS) $@ $? -@$(RM) -f $? # ranlib is for BSD UNIX only. It creates a symbol table for the linker # In BSD set RANLIB=ranlib, in SYS V set RANLIB=-@true $(RANLIB) $@ $(LOBJS): matrix.h .c.a: $(CC) $(CFLAGS) -c $< # .c.a is weird rule: files in libraries have special form: libmatrix.a(add.o) # The target has ".a" extension while "file" is "add"