makefiledependenciesgnu-maketargetprerequisites

Impose an order for the prerequisites of a target


I have a makefile snippet:

all: $(objects)
fresh: clean all
clean: ;rm $(objects)

Here, I want to ensure that when I do make fresh - clean should precede all.

But how can I make sure this, given that when I do make all, clean should not be made?


I can imagine that one way could be like this

fresh: clean
    make all

Is it the right (or the only) way to solve this issue?


Solution

  • If you use GNU make:

    all:
        @echo $@
        @sleep 1
        @echo end $@
    
    clean:
        @echo $@
        @sleep 1
        @echo end $@
    
    fresh:: clean
    fresh:: all
    
    .PHONY: clean fresh all
    

    Please note the double colon after targets fresh! See the documentation:

    The double-colon rules for a target are executed in the order they appear in the makefile.

    If you run make -j2 fresh it shows it works as expect:

    clean
    end clean
    all
    end all
    

    But with fresh:: clean all doesn't work properly parallel (maybe unexpected).

    With BSD make:

     all:
        @echo $@
        @sleep 1
        @echo end $@
    
    clean:
        @echo $@
        @sleep 1
        @echo end $@
    
    fresh:  clean all
        @echo $@
    
    .ORDER: clean all
    .PHONY: clean all fresh
    

    Note the line begin with .ORDER. It works well in parallelization too (see man make). Without parallelization the order of dependencies in line fresh: counts.