86

In a makefile, can I call a rule from another rule?

Similar to:

rule1:
        echo "bye"
rule2:
        date
rule3:
        @echo "hello"
        rule1
Eric3
  • 1,021
  • 9
  • 10
JuanPablo
  • 23,792
  • 39
  • 118
  • 164

5 Answers5

132

Either use dependencies or recursive making to connect from one rule to another.

Dependencies would be done like this (though the order will be different):

rule1:
        echo "bye"
rule2:
        date
rule3: rule1
        @echo "hello"

Recursive make would be done like this (though it does involve a subprocess):

rule1:
        echo "bye"
rule2:
        date
rule3:
        @echo "hello"
        $(MAKE) rule1

Neither is perfect; indeed, with recursive make you can get into significant problems if you build a loop. You also probably ought to add a .PHONY rule so as to mark those rules above as synthetic, so that a stray rule1 (etc.) in the directory won't cause confusion.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
34

Just add a new rule with the ordering you want..

rule1:
        echo "bye"
rule2:
        date
rule3:
        @echo "hello"

rule4: rule3 rule1
John Eikenberry
  • 1,133
  • 12
  • 12
  • Imho this is a much nicer solution than the other answers. – Jason McVetta Jul 03 '17 at 13:33
  • Simple - I like it. – Petr Vepřek Nov 20 '17 at 21:31
  • 14
    This won't impose the ordering. It will just assure that rule1 and rule3 are done before rule4, no assurance on ordering – CristianDonosoC Dec 08 '17 at 20:31
  • 1
    I second CristianDonosoC's comment. Since there is no ordering between rule1 and rule3 here, doing a parallel make (`make -j2`, for instance) will give you indeterminant execution order. – seanahern Sep 06 '18 at 14:30
  • 1
    There is a way to run pre-requisites in a specified order: https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html – Using this, rule4 should be: `rule4: | rule3 rule1` – Yoone Oct 15 '20 at 23:11
20

Makefiles are not procedural; "rules" are not like functions. That said, you can specify that one rule is a prerequisite of another:

rule1:
    @echo "Rule 1"

rule2: rule1
    @echo "Rule 2"

If you do make rule2, you should see:

Rule 1
Rule 2
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
5

There are two advanced functions in GNU Make which can do this, although it should only be used in extenuating circumstances. This SO is top rated in google.

Rule prerequisites are more recommended, but sometimes you need a post-requisite.

GNU Make Call function

GNU Make Eval function

Essentially, Eval lets you build targets on the fly, and Call allows function like "defines" to be created.

Kevin
  • 2,761
  • 1
  • 27
  • 31
0

A simple way to do it is:

ifeq (a, b)
    build_target:=one
else
    build_target:=two
endif

mytarget: $(build_target)