In the following Makefile definition:
$$@
in the second last line stand for?|
symbol in the middle line?define KERNEL_RULE $(DESTDIR)/$(1) : kernel_modules $(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR) cp $(DESTDIR)/$(1) $$@ endef
Order-only prerequisites can be specified by placing a pipe symbol ( | ) in the prerequisites list: any prerequisites to the left of the pipe symbol are normal; any prerequisites to the right are order-only: targets : normal-prerequisites | order-only-prerequisites.
The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.
In the first line, the list of target names is terminated by a colon. This, in turn, is followed by the dependency list, if there is one. If several targets are listed, this indicates that each such target is to be built independently using the rule supplied.
Hyphen prior to commands in makefiles is used to suppress errors and continue instead of failing like this: clean: -rm -f *.o. The same way goes for include syntax in makefiles to suppress the error messages that would otherwise appear if the file isn't available like this: -include $(SRC:%.c=%.d)
(You have a lamentable choice of variable names; let's change DESTDIR
to SOURCE_DIR
and leave DEST_DIR
alone.)
Suppose you were writing an ordinary rule:
$(DEST_DIR)/foo : $(SOURCE_DIR)/foo cp $(SOURCE_DIR)/foo $(DEST_DIR)/foo
That works, but the redundancy is troublesome. Sooner or later you'll change $(DEST_DIR)/foo
in the preq but forget to change it in the rule. And the rule is hard to read. So we put in an automatic variable:
$(DEST_DIR)/foo : $(SOURCE_DIR)/foo cp $(SOURCE_DIR)/foo $@
When this rule runs, $@
will be expanded to the name of the target, $(DEST_DIR)/foo
. (We can do even better than that, but let's stop there.)
Now we want to make sure that $(DEST_DIR)
exists before this rule runs, but we don't want it to be a prerequisite exactly, because the absence of that directory shouldn't be enough to cause this rule to run. So we make it an order-only prerequisite:
$(DEST_DIR)/foo : $(SOURCE_DIR)/foo | $(DEST_DIR) cp $(SOURCE_DIR)/foo $@
Now we want many rules like this, for different targets, and instead of doing it the smart way, we'll use a "canned recipe", sort of a template for creating rules on the fly.
# This won't work define KERNEL_RULE $(SOURCE_DIR)/$(1) : kernel_modules $(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR) cp $(SOURCE_DIR)/$(1) $@ endef
The problem is that when we evaluate this definition, $@
will be expanded, and since it isn't a rule yet, it will expand to nothing. So we change it to $$@
:
# This will work define KERNEL_RULE $(SOURCE_DIR)/$(1) : kernel_modules $(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR) cp $(SOURCE_DIR)/$(1) $$@ endef
When Make calls this definition, $$@
expands to $@
, then if/when it runs the rule, $@
will expand to the name of the target.
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