Intermediate files in make
's terminology is a file needed somewhere on way from a source file to
target file. An examples is a file.c
needed to create file.o
from file.y
(YACC source). From
that principle, an intermediate file is needed only once to generate the target after the source
changed and thus can be removed after it was used. Therefore, an intermediate file which did not
exist before make
also does not exist after make
(see gnu_rule_chains). In other words,
make
removes the intermediate files it needed to create (unless .SECONDARY
or .PRECIOUS
is
used). For details refer to gnu_rule_chains.
That being said, the use of explicit intermediate files (i.e. .INTERMEDIATE
) is rarely needed. Often one either really
wants to see the itermediate files too (thus making explicit targets and dependencies and remove
them as a part of make clean
) or use them implicitly in connection to pattern rules
(and thus no need to use .INTERMEDIATE
, see gnu_pattern_rules).
The following Makefile example shows the effects of explicit intermediate targets. See the differences
between make final
and make finalx
.
# This example is to show the effects of .INTERMEDIATE target.
# For targets/files marked as `intermediate` it holds that targets
# depending on them call the intermediate targets only once.
# Note that the choice of target names is only to make them
# self-explanatory.
# This is how to identify intermediate targets.
.INTERMEDIATE: intermediate
# As the target creates a file of that name, the `intermediate`
# target is called only once for the initial creation of the
# `final` file. While the `intermediate` target is not called,
# the dependency is still checked. That is, if one creates a
# new `intermediate` file herself (after the last update to
# the `final` file), then the `final` target's recipe is
# executed.
final: intermediate
cat intermediate >> $@
rm -rf $^
# Since this target does NOT create a file of the same name
# it will call the `intermediate` target every time.
# Also notice that the explicit `rm` is missing but still
# gets issued (and intermediate files removed). This is
# done implicitly by `make` (so the explicit `rm` in the
# `final` target is not necessary). This is the result of
# the make's nature "an intermediate file which did not exist
# before make also does not exist after make" (see GNU Make
# Manual, Sec. 10.4 Chains of Implicit Rules).
finalx: intermediate
cat intermediate >> final
rm -rf $^
intermediate:
echo "intermediate file $$(date)" > $@
Here is an example taken from here
and shows how trying to make wildcard targets intermediates may not work (i.e. .INTERMEDIATE: %.dep
).
oncetwice: once twice
@echo $@: $^
## Uncommenting the following line is sufficient to cause GNU make 3.81 to
## not delete the intermediate 'twice.dep', even if it didn't exist
## previously (i.e., was created by this invocation).
#another: twice.dep
%: %.dep
@echo $^ >$@
## the following .INTERMEDIATE has no effect re: the twice: twice.dep
## dependency
## PROBLEM: `%.dep` may not work as a pattern/wildcard dependency. Discussion from
## the link says that there is a bug in GNU 3.81 related to .INTERMEDIATE. Suprisingly
## enough this example works on Red Hat 6.7.
.INTERMEDIATE: %.dep
## This is the pattern rule for the intermediate files. Even when the `.INTERMEDIATE: %.dep`
## is removed/commented, `make` will treat the .dep files as intermadiate because they
## satisfy the condition "does not exist before make".
%.dep:
@echo $@ >$@
Hi. Is there way to delete directory using .INTERMEDIATE ?
Maybe change flags or command that doing it (or something else?).
Thanks