Make
Jump to navigation
Jump to search
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
$@ | 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) |
$(@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.