I'd like to know if it's possible to write a Makefile with several rules, each one defining its own prerequisites and executing all of them the same recipe without duplicating the recipe. Example:
TARGETS= file1 file2 file3 all: $(TARGETS) file1: dep1 dep2 file2: dep2 dep3 dep4 file3: dep2 dep1 cat $^ > $@
Thanks!
The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.
A makefile consists of three sections: target, dependencies, and rules. The target is normally either an executable or object file name. The dependencies are source code or other things needed to make the target. The rules are the commands needed to make the target.
The order of rules is not significant, except for determining the default goal : the target for make to consider, if you do not otherwise specify one. The default goal is the target of the first rule in the first makefile. If the first rule has multiple targets, only the first target is taken as the default.
A rule appears in the makefile and says when and how to remake certain files, called the rule's targets (most often only one per rule). It lists the other files that are the prerequisites of the target, and the recipe to use to create or update the target.
Yes, it is written in a rather obvious way:
TARGETS= file1 file2 file3 all: $(TARGETS) file1: dep1 dep2 file2: dep2 dep3 dep4 file3: dep2 dep1 $(TARGETS): cat $^ > $@
Just to clarify.
Generic make rule looks like this:
targets... : prerequisites... recipe ...
Any part of the rule can be omitted. Without the recipe, one can populate the list of prerequisites anywhere in the makefile, a target can occur in the left hand side of multiple rule statements.
For example, the following is equivalent to the example above (well, assuming that the Makefile is properly designed so that the order of prerequisites does not matter):
file1 file3 : dep1 file1 file2 file3 : dep2 file2 : dep3 dep4
Unlike listing prerequisites, there can be at most one explicit recipe for each target. Inside the recipe you can use automatic variables to get the target name, the list of prerequisites, etc.
As @Calmarius mentions in comments this doesn't apply to pattern rules, like %.txt: %.foo
. Multiple patterns within targets mean that the rule produces all these targets at once.
This pattern rule has two targets:
%.tab.c %.tab.h: %.y bison -d $<
This tells make that the recipe
bison -d x.y
will make bothx.tab.c
andx.tab.h
. If the file foo depends on the filesparse.tab.o
andscan.o
and the file scan.o depends on the fileparse.tab.h
, whenparse.y
is changed, the recipebison -d parse.y
will be executed only once, and the prerequisites of bothparse.tab.o
andscan.o
will be satisfied.
One may define multiple prerequisites in a pattern rule though (that is, provided that its targets contain a %
stem, otherwise it would be a regular rule).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With