Make: Difference between revisions

From miki
Jump to navigation Jump to search
Line 4: Line 4:
* [http://www.gnu.org/software/make/ GNU 'Make']
* [http://www.gnu.org/software/make/ GNU 'Make']
** [http://www.gnu.org/software/make/manual/make.html Manual]
** [http://www.gnu.org/software/make/manual/make.html Manual]

== Quick Reference ==

=== Automatic Variables ===
{| class="wikitable"
|+ Make Automatic Variables (most frequent)
|-
|<tt>'''{{blue|$@}}'''</tt>
|'''Target''' of the rule (if multi target, the one that cause the rule's command to run)
|-
|<tt>'''{{blue|$%}}'''</tt>
|Target member name, when target is an archive member
|-
|<tt>'''{{blue|$&lt;}}'''</tt>
|Name of '''1st prerequisite'''
|-
|<tt>'''{{blue|$?}}'''</tt>
|'''All newer prerequisites''' (more recent than the target)
|-
|<tt>'''{{blue|$^}}'''</tt>
|'''All prerequisites'''
|-
|<tt>'''{{blue|$+}}'''</tt>
|'''All prerequisites, incl. duplicates'''
|-
|<tt>'''{{blue|$*}}'''</tt>
|The '''stem''' with which the rule matched (e.g. if target is <tt>{{red|dir/}}a.foo.b</tt>, a pattern like <tt>a.%.b</tt> gives a stem <tt>{{red|dir/}}foo</tt>)
|}

{| class="wikitable"
|+ Automatic Variables - F and D variants:
|-
|<tt>'''{{blue|$(@D)}}'''</tt>
|<tt>'''{{blue|$(@F)}}'''</tt>
|Resp. the directory (w/o trailing <tt>/</tt>) and filename part of the '''target'''
|-
|<tt>'''{{blue|$(*D)}}'''</tt>
|<tt>'''{{blue|$(*F)}}'''</tt>
|Resp. the directory (w/o trailing <tt>/</tt>) and filename part of the '''stem'''
|-
|<tt>'''{{blue|$(&lt;D)}}'''</tt>
|<tt>'''{{blue|$(&lt;F)}}'''</tt>
|Resp. the directory (w/o trailing <tt>/</tt>) and filename part of the '''1st prerequisite'''
|-
|<tt>'''{{blue|$(^D)}}'''</tt>
|<tt>'''{{blue|$(^F)}}'''</tt>
|Resp. the directory (w/o trailing <tt>/</tt>) and filename part of the '''all prerequisite'''
|-
|<tt>'''{{blue|$(+D)}}'''</tt>
|<tt>'''{{blue|$(+F)}}'''</tt>
|Resp. the directory (w/o trailing <tt>/</tt>) and filename part of the '''all prerequisites, incl. duplicates'''
|-
|<tt>'''{{blue|$(?D)}}'''</tt>
|<tt>'''{{blue|$(?F)}}'''</tt>
|Resp. the directory (w/o trailing <tt>/</tt>) and filename part of the '''newer prerequisites'''
|}


== Tips ==
== Tips ==
Line 44: Line 100:
* Only one <tt>.d</tt> file generated, indep. of <tt>$(DEFINES)</tt>, so if <tt>$(DEFINES)</tt> changed, and include files depends on these defines, the <tt>.d</tt> files will not be updated.
* Only one <tt>.d</tt> file generated, indep. of <tt>$(DEFINES)</tt>, so if <tt>$(DEFINES)</tt> changed, and include files depends on these defines, the <tt>.d</tt> files will not be updated.
:A solution would be to name the <tt>.d</tt> files according to relevant defines, as we do for the <tt>.o</tt> files
:A solution would be to name the <tt>.d</tt> files according to relevant defines, as we do for the <tt>.o</tt> files



== Frequent Mistakes ==
== Frequent Mistakes ==

Revision as of 09:42, 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

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
	@set -e; rm -f $@; \
	$(CC) $(CFLAGS) $(INCPATHS) -MM $< | sed -r 's!(.*)\.o[ :]*!\1.o $@ : !g' > $@
#----- 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 have suffix $(VARIANT)

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

$(VARDIR)/%.d: $(SRCDIR)/%.cpp
	@mkdir -p "$(@D)"; \
	set -e; rm -f $@; \
	$(CPP) $(CFLAGS) $(INCPATHS) -MM -MT $(VARDIR)/$*.o $< | sed 's!\(.*\)\.o[ :]*!\1$$(VARIANT).o $@ : !g' > $@
#----- 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.