6

Is there a way to execute a recipe more than once? In the SSCCE below it appears that the recipe is executed only once:

$ cat Makefile 
.PHONY: a b
a: b b 
b:
    echo "beta"
$ make 
echo "beta"
beta
Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
  • 5
    A recipe is for building a dependency. One only needs to build a dependency once (hence Make pays no attention to the duplicate). If you want to do something twice, put a loop *inside* your recipe. – Oliver Charlesworth Sep 03 '14 at 22:37
  • 1
    @OliCharlesworth this is an SSCCE, there are valid reasons to want the same recipe to be executed twice, not necessarily in succession. E.g: `test: drop-db create-db load-data dump-data drop-db create-db restore-data` – Marcus Junius Brutus Sep 03 '14 at 22:49
  • 1
    @MarcusJuniusBrutus: Your example is nonsense -- dependencies are dependencies and there is no order to them. If you want recipes to be executed in order, you execute them in order inside your action. – Chris Dodd Sep 03 '14 at 22:56
  • 3
    Recipes are not functions, they simply correspond to nodes in a dependency graph. They can't be used for procedural behaviour. Accepting that fact is the first step to using Make (and similar build systems) effectively ;) – Oliver Charlesworth Sep 03 '14 at 23:12
  • 1
    There is an order for prerequisites (but it isn't explicit and shouldn't be depended on). There are also reasons to want the same prerequisite listed more than once in the prereq list (but running that prereq more than once isn't among them). – Etan Reisner Sep 04 '14 at 00:02

1 Answers1

10

Once you've read and understood the comments ;-), there are two ways I can think of to run a recipe twice:

@OliCharlesworth mentions the first - use a loop inside your recipe:

.PHONY: a b
a: b b
b:
    for i in 1 2; do \
        echo "beta" ;\
    done

Note you need to be quite careful when embedding multi-line shell expressions in recipes. Unless you terminate lines with backslashes, make will treat each line as a separate shell invocation, which wouldn't work for a loop.

The other way is to duplicate your b target, so that both copies have the same recipe:

.PHONY: a b1 b2
a: b1 b2
b1 b2:
    echo "beta"

This defines the b1 and b2 targets with the same recipe. Then a depends on both b1 and b2, so the recipe gets called twice. Note that there is no guarantee of the order in which b1 and b2 will be invoked - and they'll likely be invoked concurrently if you have a -j factor greater than 1.

Digital Trauma
  • 15,475
  • 3
  • 51
  • 83