Makefile Memo: Continuation Lines
Makefile Memo: Continuation Lines
Continuation lines
first_part_of_line second_part_of_line
is the same as:
first_part_of_line \
second_part_of_line
Comments
#
# Compiler: Microsoft C 6.0
# Linker: Microsoft Link 5.10
#
line_one \
line_two # more_line_two \
line_three
is the same as:
line_one line_two line_three
Rules
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:
.RESPONSE.LINK : TLINK
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 Delete the response file (Default.)
ECHO Show the contents of the response file.
Macros
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 Example Value
D, the directory $(SRCS,D) d:\src .
E, the extension (or suffix) $(SRCS,E) .c .asm
F, the file name $(SRCS,F) main.c io.asm
Tokenize
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.