Make: Difference between revisions

From miki
Jump to navigation Jump to search
Line 88: Line 88:
bar = $(foo:%.o=%.c) # bar = a.c b.c c.c
bar = $(foo:%.o=%.c) # bar = a.c b.c c.c
</source>
</source>

=== Functions for File Names ===
;<tt>$(dir ''names...'')</tt>
:Extract the directory part

;<tt>$(notdir ''names...'')</tt>
:Extract the not-directory part

;<tt>$(suffix ''names...'')</tt>
:Extract the suffix of each file name (incl. the period <tt>.</tt>)

;<tt>$(basename ''names...'')</tt>
:Extract the basename of each file name

;<tt>$(addsuffix ''suffix'',''names...'')</tt>
:Append the value of ''suffix'' to each file name.
<source lang="make">
$(addsuffic .c,foo bar) # Produces 'foo.c bar.c'
</source>

;<tt>$(addprefix ''prefix'',''names...'')</tt>
<source lang="make">
$(addsuffic src/,foo bar) # Produces 'src/foo src/bar'
</source>

;<tt>$(join ''list1'',''list2'')</tt>

;<tt>$(wildcard ''pattern'')</tt>

;<tt>$(realpath ''names...'')</tt>

;<tt>$(abspath ''names...'')</tt>


== Tips ==
== Tips ==

Revision as of 11:37, 3 October 2011

make is an utility that determines automatically which pieces of a program need to be recompiled, and issues the commands to rebuild them. make uses a file called Makefile, which describes the relationships among files in the program.

References

Quick Reference

Automatic Variables

Make Automatic Variables (most frequent)
$@ Target of the rule (if multi target, the one that cause the rule's command to run)
$% Target member name, when target is an archive member
$< Name of 1st prerequisite
$? All newer prerequisites (more recent than the target)
$^ All prerequisites
$+ All prerequisites, incl. duplicates
$* The stem with which the rule matched (e.g. if target is dir/a.foo.b, a pattern like a.%.b gives a stem dir/foo)
Automatic Variables - F and D variants:
$(@D) $(@F) Resp. the directory (w/o trailing /) and filename part of the target
$(*D) $(*F) Resp. the directory (w/o trailing /) and filename part of the stem
$(<D) $(<F) Resp. the directory (w/o trailing /) and filename part of the 1st prerequisite
$(^D) $(^F) Resp. the directory (w/o trailing /) and filename part of the all prerequisite
$(+D) $(+F) Resp. the directory (w/o trailing /) and filename part of the all prerequisites, incl. duplicates
$(?D) $(?F) Resp. the directory (w/o trailing /) and filename part of the newer prerequisites

How to Use Variables

Recursive vs. simple expansion
# Recursive expansion
CFLAGS = $(INCLUDES) -O
INCLUDES = -Ifoo -Ibar

all:
	echo $(CFLAGS)           # will echo '-Ifoo -Ibar -O'
# Simple expansion
x := foo
y := $(x) bar                    # expansion occurs here, once for all (y = foo bar)
x := later                       # y still = foo bar
Substitution References
foo = a.o b.o c.o
bar = $(foo:.o=.c)               # bar = a.c b.c c.c
Using % (equiv. to $(patsubst a,b,$(var)):
foo = a.o b.o c.o
bar = $(foo:%.o=%.c)             # bar = a.c b.c c.c

Functions for File Names

$(dir names...)
Extract the directory part
$(notdir names...)
Extract the not-directory part
$(suffix names...)
Extract the suffix of each file name (incl. the period .)
$(basename names...)
Extract the basename of each file name
$(addsuffix suffix,names...)
Append the value of suffix to each file name.
$(addsuffic .c,foo bar)        # Produces 'foo.c bar.c'
$(addprefix prefix,names...)
$(addsuffic src/,foo bar)      # Produces 'src/foo src/bar'
$(join list1,list2)
$(wildcard pattern)
$(realpath names...)
$(abspath names...)

Tips

Automatic Prerequisites

A standard solution (inspired from Makefile manual):

#----- BEGIN Automatic-Prerequisites -----
# - see http://www.gnu.org/software/make/manual/make.html#Automatic-Prerequisites
# - Note that .d files are automatically regenerated because of the include command below.
# - Only 1 .d file generated, indep. of defines. So if include files depend on defines, the .d files will *NOT* be updated.

-include $(SOURCES:.cpp=.d)

%.d: %.cpp
	$(CPP) $(CFLAGS) $(INCPATHS) -MM -MT $*.o -MT $*.d -MF $@ $<
#----- END Automatic-Prerequisites -----

A more advanced solution, where object files are stored in directory $(VARDIR), and have a suffic $(VARIANT):

#----- BEGIN Automatic-Prerequisites -----
# - see http://www.gnu.org/software/make/manual/make.html#Automatic-Prerequisites
# - Note that .d files are automatically regenerated because of the include command below.
# - Only 1 .d file generated, indep. of defines. So if include files depend on defines, the .d files will *NOT* be updated.
# - [CHANGES] .o and .d files are stored in directory $(VARDIR)/, and .o have suffix $(VARIANT)

-include $(addprefix $(VARDIR)/, $(notdir $(SOURCES:.cpp=.d) ) )

$(VARDIR)/%.d: $(SRCDIR)/%.cpp
	$(CPP) $(CFLAGS) $(INCPATHS) -MM -MT $(VARDIR)/$*$$"(VARIANT)".o -MT $*.d -MF $@ $<
#----- END Automatic-Prerequisites -----


Limitations:

  • Only one .d file generated, indep. of $(DEFINES), so if $(DEFINES) changed, and include files depends on these defines, the .d files will not be updated.
A solution would be to name the .d files according to relevant defines, as we do for the .o files

Frequent Mistakes

Use TABS to prefix commands in rules, *NOT* SPACES
Each rule in a makefile gives the set of commands that must be executed to build a given target from a given set of dependencies. These commands MUST be indented with a TAB character, not with SPACES. So make sure that the editor does not automatically change these tabs into spaces.