Search code examples
makefilegnu-make

How does one set up a group recipe that gets run only once?


Suppose I have a recipe that accepts a group of prerequisites:

prereqs=a b c

$(prereqs):
  bash configure.sh

And I would like any of a b c to trigger bash configure.sh, but I want it to be run only once.

I am aware of other ways to solve this problem. I know there are decorators that can be applied to the rule that cause various behaviors.

Within the call of this question, is there some way to cause make to evaluate the recipe only once?


Solution

  • I don't know what you mean by "decorators" and I don't know what you mean by "within the call of this question", so I can't decide what things you already know about and what your limitations are for an answer.

    If you can guarantee that you're using GNU Make 4.3 or newer, you can use the &: separator; this is exactly what it's for:

    prereqs = a b c
    
    $(prereqs) &:
           bash configure.sh
    

    If &: is what you mean by "decorator" (this is not the term used in the GNU Make manual) and you can't use this for whatever reason, then there's only one solution I'm aware of (assuming you want to be able to run with -j; if you don't want to run in parallel then your original makefile will work fine):

    prereqs = a b c
    
    $(prereqs): .sentinel ;
    
    .sentinel:
           bash configure.sh
           touch $@
    

    Don't forget the semicolon above, it's important!