Order of processing components in makefile

2019-01-24 00:07发布

问题:

In a makefile, the dependency line is of the form -

abc: x y z

All three of the components (x,y,z) are themselves targets in dependency lines further down in the makefile.

If make abc is invoked, in what order will the three targets x,y,z be executed?

回答1:

By default, the order of execution is the same as specified in the prerequisites list, unless there are any dependencies defined between these prerequisites.

abc: x y z

The order is x y z.

abc: x y z
y : z

The order would be x z y.

But ideally, you should design your Makefiles so that it wouldn't rely on the order in which prerequisites are specified. That is, if y should be executed after z, there must be a y : z dependence.

And keep in mind that GNU Make can execute some recipes in parallel, see Mat's answer.



回答2:

You really shouldn't depend on the order in which they are executed - all else being equal, all three recipes for those prerequisites could run in parallel.

The only hard rule is that all prerequisites must be met before the target recipe is run.

If there are no dependencies between x, y and z, and no parallel execution, GNU make appears to run them in the order you specified them, but this is not guaranteed in the docs.



回答3:

The POSIX description of make includes a rationale which says:

The make utilities in most historical implementations process the prerequisites of a target in left-to-right order, and the makefile format requires this. It supports the standard idiom used in many makefiles that produce yacc programs; for example:

foo: y.tab.o lex.o main.o
     $(CC) $(CFLAGS) -o $@ t.tab.o lex.o main.o

In this example, if make chose any arbitrary order, the lex.o might not be made with the correct y.tab.h. Although there may be better ways to express this relationship, it is widely used historically. Implementations that desire to update prerequisites in parallel should require an explicit extension to make or the makefile format to accomplish it, as described previously.

(I believe the t.tab.o in the $(CC) line is a typo for y.tab.o, but that is what the rationale actually says.)

Thus, the observed behaviour that pre-requisites are processed from left to right has validation here, though it is only in the Rationale section, not in the main description. The Rationale also mentions issues with parallel make etc.



回答4:

From https://stackoverflow.com/a/22638294/636849, you can add the pipe symbol:

abc: | x y z

From make manual: 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