52

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?

Shailesh Tainwala
  • 6,299
  • 12
  • 58
  • 69
  • 2
    possible duplicate of [In what order prerequisites will be made by the GNU make?](http://stackoverflow.com/questions/1647480/in-what-order-prerequisites-will-be-made-by-the-gnu-make) – Mike Nov 03 '14 at 17:02

5 Answers5

71

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.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Eldar Abusalimov
  • 24,387
  • 4
  • 67
  • 71
58

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.

Mat
  • 202,337
  • 40
  • 393
  • 406
22

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.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • +1 for POSIX description and the important caveat about parallel `make` jobs. IMO the choice not to allow enforcement of any order on parallel jobs was a misstep. _e.g._ I am happy for my `.o`bjects to be compiled in any order, but I need a bunch of other things to happen before and after compiling and linking respectively, and it's a lot more difficult than it should be... – underscore_d Apr 06 '16 at 21:05
  • 1
    I'll point out that GNU make diverges pretty significantly from POSIX make, and the `.POSIX` special target should be included in the makefile to signal that it should behave in a compatible way. – Alex Reinking May 08 '19 at 12:50
0

New to GNU make 4.4, we have the .WAIT prerequisite!

Set it as a dependency, and it will pause all dependencies to the right of it until all the ones to the left are completed.

all: please_run_me and_me .WAIT before_me

Note that please_run_me & and_me are not ordered in relation to eachother, but both will finish before before_me starts.

You can throw multiple .WAITs on a line.

There was another way added to do this too - .NOTPARALLEL, you can read about it in the changelog or in the manual


Though it released on the 31st October 2022, some distributions (e.g.: Ubuntu) may not come with it preinstalled yet.

If you want to install make for such devices, you'll have to build from source.

Icedude_907
  • 172
  • 3
  • 11
-5

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

Lucas Cimon
  • 1,859
  • 2
  • 24
  • 33
  • 9
    No, that's not what order-only prerequisites do. `foo: | bar baz` does not enforce `bar baz` any more than without the pipe character. Instead, the pipe says roughly "when ordering foo, bar and baz, bar and baz must both come before foo, but updates to bar and baz are not sufficient reason to cause foo to be considered updated and to need to run". Docs are at https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html and are not the clearest. – Phil P Mar 02 '18 at 08:13
  • 2
    @PhilP I'm not a native speaker, but I would suggest that "consider OUTdated" (and thus to need to run) is what you meant, no? – BUFU Sep 08 '20 at 14:07
  • 1
    I can't edit it to fix, but yes you are right. I think I reworded a couple of times and lost something. "to be considered as needing updates" works too. Thank you. – Phil P Sep 09 '20 at 19:57