tags:

views:

32

answers:

1

I have a makefile structured something like this:

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

I realized that I was consistently running "make clean" followed by "clear" in my terminal before running "make all". I like to have a clean terminal before I try and sift through nasty C++ compilation errors. So I tried to add a 3rd target:

fresh :
    rm -f *.o $(EXEC)
    clear
    make all

This works, however this runs a second instance of make (I believe). Is there a right way to get the same functionality without running a 2nd instance of make?

+3  A: 

Actually you are right: it runs another instance of make. A possible solution would be:

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : clean clearscr all

clearscr:
    clear

By calling make fresh you get first the clean target, then the clearscreen which runs clear and finally all which does the job.

EDIT

What happens in case of "-j" option? There's a way of fixing the order. From the make manual, section 4.2:

Occasionally, however, you have a situation where you want to impose a specific ordering on the rules to be invoked without forcing the target to be updated if one of those rules is executed. In that case, you want to define order-only prerequisites. Order-only prerequisites can be specified by placing a pipe symbol (|) in the prerequisites list: any prerequisites to the left of the pipe symbol are normal; any prerequisites to the right are order-only: targets : normal-prerequisites | order-only-prerequisites

The normal prerequisites section may of course be empty. Also, you may still declare multiple lines of prerequisites for the same target: they are appended appropriately. Note that if you declare the same file to be both a normal and an order-only prerequisite, the normal prerequisite takes precedence (since they are a strict superset of the behavior of an order-only prerequisite).

Hence the makefile becomes

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : | clean clearscr all

clearscr:
    clear
Dacav
I don't think this solution is compatible with parallel builds (i.e. make -j). Seems that the clean, clearscr, and all rules could all run at the same time.
Dan Moulding
@Dan Moulding: interesting comment. I've also found an answer on the manual: I'll update the page.
Dacav
Thank you! Of course it works perfectly. I know this is a question I've seen answered so many places, but I still don't understand the ".PHONY". It doesn't seem to have any impact on how anything runs (in this case). I read that .PHONY targets are never up-to-date, but then why does it say "Nothing to be done for 'all'."?
@sas4740: http://www.gnu.org/software/automake/manual/make/Phony-Targets.html
Dacav
I think I understand it now..thanks
@sas4740: basically everything follows `.PHONY : ` is treated as some keyword that gets always executed, while non-phony targets are intended to be files.
Dacav