Makefile Memo

Continuation lines
first_part_of_line second_part_of_line

is the same as:
first_part_of_line \ second_part_of_line

# # Compiler: Microsoft C 6.0 # Linker: Microsoft Link 5.10 # some makefile statement # a comment line_one \ line_two # more_line_two \ line_three is the same as:
line_one line_two line_three

Rules tell Make both when and how to make a file.

Explicit rules
project.exe : main.obj io.obj tlink c0s main.obj io.obj, project.exe,, cs /Lf:\bc\lib main.obj : main.c bcc –ms –c main.c

Inference rules
Inference rule for building .obj files from coresponding .c files: %.obj : %.c $(CC) $(CFLAGS) –c $(.SOURCE) or .c.obj : $(CC) $(CFLAGS) –c $(.SOURCE) Meaning of $*, $<, $@ 1. S* is the current target without an extension (the base file name) with path.
main.o: main.c $(CC) $(CFLAGS) $*.c

 S* is main

2. S< is a dependent file out-of-date with the target file.
main.o: main.c $(CC) $(CFLAGS) $<

 S< is main.c 3. S@ is the current target (including extension, if any).
mirror: $(OBJS) $(LINKER) $(LINKER-FLAGS) $@ $(OBJS)

 S@ is mirror

Response Files
Because of restriction on the length of a shell line, the shell line is ofter too short for many compilers and far too short for linkers and librarians. To overcome this restriction, many programs can receive command-line input from a response file.

Automatic Response Files
Determines where Make decides when to build a response file. Automatic responses are defined with a directive of the form:
.RESPONSE.XXX : [ parameter ... ] [ program ... ]

Where XXX is the name of a response class, parameter describes the response class, and program is the name of a program that accepts the response class. This directive both defines response classes (see the manual for details) and adds program names to existing classes. For example, to add automatic response file support for Borland's TLINK use the following:

Inline Response Files
Determines where you write response file – creating statements directly in the makefile.
target : command [prolog] << [ response_file ] [ line copied to response file ] ... << [epilog]

where << begin and end the response file, response_file names the file, and epilog and prolog are optional text. The most common prolog is "@". The epilog can be used for redirection or other text. There are three special words that can appear in the epilog: Epilog Meaning KEEP Do not delete the response file. NOKEEP ECHO Delete the response file (Default.) Show the contents of the response file.

Dependency lines: When to build a Target
The line with the colon “:” target: sources (target depends on the sources)

project.exe : main.obj io.obj

Additional Dependencies
main.obj : main.c io.obj : io.c main.c and io.c include def.h, so becomes main.obj : main.c def.h io.obj : io.c def.h or add the additional dependencies main.obj io.obj : def.h

Shell lines: How to build a Target
The indented lines that follow each dependency line
project.exe : main.obj io.obj tlink c0s main.obj io.obj, project.exe,, cs /Lf:\bc\lib

Macros are used to reduce the amount of repeated text and also used in inference rules to generalize the build process.

Macro definition:
macro_name= macro_value. In expressions of the form $name or $(name) or ${name} are replaced with macro_value. OBJS = main.obj io.obj MODEL = s CC = bcc CFLAGS = –m$(MODEL) project.exe : $(OBJS) tlink c0$(MODEL) $(OBJS), project.exe,, c$(MODEL) /Lf:\bc\lib main.obj : main.c $(CC) $(CFLAGS) –c main.c io.obj : io.c $(CC) $(CFLAGS) –c io.c $(OBJS) : incl.h

Macro Modifiers
OBJS = main.obj io.obj Get the list of source files from the OBJS macro: SRCS = $(OBJS,.obj=.c) -> $(SRCS) is “main.c io.c” Expansion: $(name,modifier[,modifier ...])

Filename Components
SRCS = d:\src\main.c io.asm There is a set of macro modifiers for accessing parts of file names. Example:

Modifier, and description D, the directory E, the extension (or suffix) F, the file name

Example $(SRCS,D) $(SRCS,E) $(SRCS,F)

Value d:\src . .c .asm main.c io.asm

The Wstr modifier replaces white space between elements of the macro with str, a string.. For example:
$(OBJS,W +\n) -> main.obj + io.obj

Other Modifiers
Other modifiers include @ (include file contents), LC (lowercase), UC (uppercase), M (member), and N (nonmember). The M and N modifiers and the S (substitute) modifier use regular expressions for powerful and flexible pattern-matching.

Environment Variables
Environment variables are placed into the environment with this command: set name=value

Makefile Directives
Makefile directives control the makefile lines Make reads at read time. Here is our example extended with conditional directives (%if, %elif, %else and %endif) to support both Borland and Microsoft compilers. Comments have been added for documentation: # This makefile compiles the project listed in the PROJ macro # PROJ = project # the name of the project OBJS = main.obj io.obj # list of object files # Configuration: # MODEL = s # memory model CC = bcc # name of compiler # Compiler-dependent section # %if $(CC) == bcc # if compiler is bcc CFLAGS = –m$(MODEL) # $(CFLAGS) is –ms LDSTART = c0$(MODEL) # the start-up object file LDLIBS = c$(MODEL) # the library LDFLAGS = /Lf:\bc\lib # f:\bc\lib is library directory %elif $(CC) == cl # else if compiler is cl CFLAGS = –A$(MODEL,UC) # $(CFLAGS) is –AS

LDSTART = # no special start-up LDLIBS = # no special library LDFLAGS = /Lf:\c6\lib; # f:\c6\lib is library directory %else # else % abort Unsupported CC==$(CC) # compiler is not supported %endif # endif # The project to be built # $(PROJ).exe : $(OBJS) tlink $(LDSTART) $(OBJS), $(.TARGET),, $(LDLIBS) $(LDFLAGS) $(OBJS) : incl.h The layout of this makefile is fairly traditional — macros are defined first, the primary target follows the macros and the extra dependency information is last. This example also uses the %abort directive to abort Make if the makefile does not support a particular compiler. Directives can also be used at run time, to control the shell lines Make executes.

Cleaning up & Re-Make
‘make clean’ to remove all object files (which are no longer needed once the excutable has been built). ‘make distclean’ to remove all excutables, core dumps and object files so that all what remains is the source files which can be distributed and recompiled on the another system. ‘make again’ to recompile all files – that is remove all object files, core dumps, program files and then make target again.
clean: rm –f *.o core distclean: make clean rm $(TARGET) again: make distclean make $(TARGET)

Silencing make – Nonstop make
When make command is built, it can cause some very verbose. To keeping make form behaving so just add another line - this time at the very beginning of your makefile .SILENT: If make succeeds there won't be any output but if there happens to be an error make will stop and report it to you. There are cases in which you don't want make to stop after the very first error that occurs. This is usually done for efficency reasons - maybe you are looking for all the files a certain error does occur in, maybe you are debugging the Makefile itself (rather frequently, just think about porting a program). To do so simply add a row .IGNORE:

An useful example
C++ LINKER RM MAKE OBJS = g++ = g++ = rm -f = make = input.o \ # use GNU C++ compiler # warn all # use GNU C++ as linker # flags for linker # how to remove files # name of make utility

C++-FLAGS = -c -Wall LINKER-FLAGS = -o

# you cannot add comments after the continuation character! mirror.o \ process.o \ output.o TARGET .IGNORE: .SILENT: .SUFFIXES: .SUFFIXES: .cc .o $(TARGET): $(OBJS) $(LINKER) $(LINKER-FLAGS) $@ $(OBJS) .cc.o: $(C++) $(C++-FLAGS) $< # remove object files and core (if any) clean: $(RM) *.o core # remove object files, core dump, and executable (if any) distclean: $(MAKE) clean $(RM) $(TARGET) # remove object files, core dump, and executable (if any) and # make them again. again: $(MAKE) distclean $(MAKE) $(TARGET) # echo username info: echo User is: $(USER) = mirror # name of executable # ignore problems (as far as possible) # don't echo commands executed # get rid of predefined rules