3

I've been reading the documentation but it's still unclear to me how the order is processed. In the example:

myrule: | myrule_step1 myrule_step2
    @echo "$(@)"

myrule_step1:
    @echo "$(@)"

myrule_step2:
    @echo "$(@)"

what will print first? myrule_step1 or myrule_step2?

1

The order is unspecified and can run in either order. This isn't just a theoretical concern. It can happen during parallel builds. Assuming the same Makefile as in the question, I ran:

watch -n 0.1 make -j8

It only took a few seconds to print:

myrule_step2
myrule_step1
myrule

See also this StackOverflow answer by Jörg W Mittag:

No, the order is not defined. That is the whole point in using declarative dependency-oriented programming: that the computer can pick the optimal evaluation order, or in fact, evaluate them even at the same time.

However, as mosvy points out, this is only true for GNU Make. POSIX make (which can be emulated in GNU Make by adding the special .POSIX target to your makefile) specifies a left-to-right ordering when handling prerequisites.

12
  • Is this really the case, or is it simply because the echos are run as external commands via fork+exec, and it's up to the kernel the order in which to schedule them to run? Does it also happens if you replace the @echo "$(@)" with @: $(info $@)? – mosvy May 8 '19 at 5:54
  • @mosvy - There's no difference. If make guaranteed that they ran left to right, it would have to wait for one to finish before starting the next to make parallel builds behave the same as serial ones. But then you wouldn't actually get any parallelism. – Alex Reinking May 8 '19 at 9:59
  • The bottom line is that if you need something to depend on something else, then you declare it as a dependency. Use myrule_step2: | myrule_step1 to get the desired ordering in OP's question. – Alex Reinking May 8 '19 at 10:02
  • Do you mean you can get it to do the $(info $@) functions in reverse order? My impression (maybe false) was that GNU make doesn't parallelize itself, but the external commands it runs (the echos or the :s in the examples) – mosvy May 8 '19 at 10:39
  • @mosvy - It's not about the parallelism, it's about what make guarantees and why. Even if GNU make happens to process dependencies left to right doesn't mean it has to. Because it doesn't promise that it does, you can't rely on it. Why doesn't it make that promise? Because there wouldn't be a way to reconcile it with parallel builds that touch the filesystem. – Alex Reinking May 8 '19 at 11:00
1

While it's not clear from the documentation, running the example you will find that the order is indeed from left to right.

myrule_step1
myrule_step2
myrule
2
  • 2
    If it's not in the documentation, is it really guaranteed to run left to right, or is that an implementation detail that might change in a newer version? – Alex Reinking May 7 '19 at 23:06
  • With -j option they will run in parallel. – Desik Jul 26 '20 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.