Next: , Previous: , Up: Using Implicit Rules   [Contents][Index]


10.4 Chains of Implicit Rules

Sometimes a file can be made by a sequence of implicit rules. For example, a file n.o could be made from n.y by running first Yacc and then cc. Such a sequence is called a chain.

If the file n.c exists, or is mentioned in the makefile, no special searching is required: make finds that the object file can be made by C compilation from n.c; later on, when considering how to make n.c, the rule for running Yacc is used. Ultimately both n.c and n.o are updated.

However, even if n.c does not exist and is not mentioned, make knows how to envision it as the missing link between n.o and n.y! In this case, n.c is called an intermediate file. Once make has decided to use the intermediate file, it is entered in the data base as if it had been mentioned in the makefile, along with the implicit rule that says how to create it.

Intermediate files are remade using their rules just like all other files. But intermediate files are treated differently in two ways.

The first difference is what happens if the intermediate file does not exist. If an ordinary file b does not exist, and make considers a target that depends on b, it invariably creates b and then updates the target from b. But if b is an intermediate file, then make can leave well enough alone: it won’t create b unless one of its prerequisites is out of date. This means the target depending on b won’t be rebuilt either, unless there is some other reason to update that target: for example the target doesn’t exist or a different prerequisite is newer than the target.

The second difference is that if make does create b in order to update something else, it deletes b later on after it is no longer needed. Therefore, an intermediate file which did not exist before make also does not exist after make. make reports the deletion to you by printing a ‘rm’ command showing which file it is deleting.

You can explicitly mark a file as intermediate by listing it as a prerequisite of the special target .INTERMEDIATE. This takes effect even if the file is mentioned explicitly in some other way.

A file cannot be intermediate if it is mentioned in the makefile as a target or prerequisite, so one way to avoid the deletion of intermediate files is by adding it as a prerequisite to some target. However, doing so can cause make to do extra work when searching pattern rules (see Implicit Rule Search Algorithm).

As an alternative, listing a file as a prerequisite of the special target .NOTINTERMEDIATE forces it to not be considered intermediate (just as any other mention of the file will do). Also, listing the target pattern of a pattern rule as a prerequisite of .NOTINTERMEDIATE ensures that no targets generated using that pattern rule are considered intermediate.

You can disable intermediate files completely in your makefile by providing .NOTINTERMEDIATE as a target with no prerequisites: in that case it applies to every file in the makefile.

If you do not want make to create a file merely because it does not already exist, but you also do not want make to automatically delete the file, you can mark it as a secondary file. To do this, list it as a prerequisite of the special target .SECONDARY. Marking a file as secondary also marks it as intermediate.

A chain can involve more than two implicit rules. For example, it is possible to make a file foo from RCS/foo.y,v by running RCS, Yacc and cc. Then both foo.y and foo.c are intermediate files that are deleted at the end.

No single implicit rule can appear more than once in a chain. This means that make will not even consider such a ridiculous thing as making foo from foo.o.o by running the linker twice. This constraint has the added benefit of preventing any infinite loop in the search for an implicit rule chain.

There are some special implicit rules to optimize certain cases that would otherwise be handled by rule chains. For example, making foo from foo.c could be handled by compiling and linking with separate chained rules, using foo.o as an intermediate file. But what actually happens is that a special rule for this case does the compilation and linking with a single cc command. The optimized rule is used in preference to the step-by-step chain because it comes earlier in the ordering of rules.

Finally, for performance reasons make will not consider non-terminal match-anything rules (i.e., ‘%:’) when searching for a rule to build a prerequisite of an implicit rule (see Match-Anything Pattern Rules).


Next: Defining and Redefining Pattern Rules, Previous: Variables Used by Implicit Rules, Up: Using Implicit Rules   [Contents][Index]