Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make/makefile progress indication!

Look at this makefile, it has some sort of primitive progress indication (could have been a progress bar).

Please give me suggestions/comments on it!


  # BUILD is initially undefined ifndef BUILD  # max equals 256 x's sixteen := x x x x x x x x x x x x x x x x MAX := $(foreach x,$(sixteen),$(sixteen))  # T estimates how many targets we are building by replacing BUILD with a special string T := $(shell $(MAKE) -nrRf $(firstword $(MAKEFILE_LIST)) $(MAKECMDGOALS) \             BUILD="COUNTTHIS" | grep -c "COUNTTHIS")  # N is the number of pending targets in base 1, well in fact, base x :-) N := $(wordlist 1,$T,$(MAX))  # auto-decrementing counter that returns the number of pending targets in base 10 counter = $(words $N)$(eval N := $(wordlist 2,$(words $N),$N))  # BUILD is now defined to show the progress, this also avoids redefining T in loop BUILD = @echo $(counter) of $(T) endif  # dummy phony targets  .PHONY: all clean  all: target     @echo done  clean:     @rm -f target *.c  # dummy build rules  target: a.c b.c c.c d.c e.c f.c g.c     @touch $@     $(BUILD)  %.c:     @touch $@     $(BUILD)  

All suggestions welcome!

like image 733
Giovanni Funchal Avatar asked Jan 16 '09 18:01

Giovanni Funchal


2 Answers

This one is less intrusive and more awesome.

ifneq ($(words $(MAKECMDGOALS)),1) .DEFAULT_GOAL = all %:         @$(MAKE) $@ --no-print-directory -rRf $(firstword $(MAKEFILE_LIST)) else ifndef ECHO T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \       -nrRf $(firstword $(MAKEFILE_LIST)) \       ECHO="COUNTTHIS" | grep -c "COUNTTHIS")  N := x C = $(words $N)$(eval N := x $N) ECHO = echo "`expr " [\`expr $C '*' 100 / $T\`" : '.*\(....\)$$'`%]" endif  .PHONY: all clean  all: target         @$(ECHO) All done  clean:         @rm -f target *.c #       @$(ECHO) Clean done  target: a.c b.c c.c d.c e.c         @$(ECHO) Linking $@         @sleep 0.1         @touch $@  %.c:         @$(ECHO) Compiling $@         @sleep 0.1         @touch $@  endif 
like image 145
Giovanni Funchal Avatar answered Sep 28 '22 02:09

Giovanni Funchal


This is a slight modification to @GiovanniFunchal's excellent answer.

So I wanted to understand this better and make it work for < 10% so I dug into the documentation and learned more about expr.

# PLACE AT THE TOP OF YOUR MAKEFILE #--------------------------------- # Progress bar defs #-------------------------------- #  words = count the number of words ifneq ($(words $(MAKECMDGOALS)),1) # if no argument was given to make... .DEFAULT_GOAL = all # set the default goal to all #  http://www.gnu.org/software/make/manual/make.html #  $@ = target name #  %: = last resort recipe #  --no-print-directory = don't print enter/leave messages for each output grouping #  MAKEFILE_LIST = has a list of all the parsed Makefiles that can be found *.mk, Makefile, etc #  -n = dry run, just print the recipes #  -r = no builtin rules, disables implicit rules #  -R = no builtin variables, disables implicit variables #  -f = specify the name of the Makefile %:                   # define a last resort default rule       @$(MAKE) $@ --no-print-directory -rRf $(firstword $(MAKEFILE_LIST)) # recursive make call,  else ifndef ECHO #  execute a dry run of make, defining echo beforehand, and count all the instances of "COUNTTHIS" T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \       -nrRf $(firstword $(MAKEFILE_LIST)) \       ECHO="COUNTTHIS" | grep -c "COUNTTHIS") #  eval = evaluate the text and read the results as makefile commands N := x #  Recursively expand C for each instance of ECHO to count more x's C = $(words $N)$(eval N := x $N) #  Multipy the count of x's by 100, and divide by the count of "COUNTTHIS" #  Followed by a percent sign #  And wrap it all in square brackets ECHO = echo -ne "\r [`expr $C '*' 100 / $T`%]" endif #------------------ # end progress bar #------------------  # REST OF YOUR MAKEFILE HERE  #----- Progressbar endif at end Makefile endif 

I got rid of the : '.*\(....\)$$' part. It would return the last 4 characters of the inner expr command, but would fail if it was less than 4. And now it works for sub 10%!

And here is the comment free version:

ifneq ($(words $(MAKECMDGOALS)),1) # if no argument was given to make... .DEFAULT_GOAL = all # set the default goal to all %:                   # define a last resort default rule       @$(MAKE) $@ --no-print-directory -rRf $(firstword $(MAKEFILE_LIST)) # recursive make call,  else ifndef ECHO T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \       -nrRf $(firstword $(MAKEFILE_LIST)) \       ECHO="COUNTTHIS" | grep -c "COUNTTHIS") N := x C = $(words $N)$(eval N := x $N) ECHO = echo -ne "\r [`expr $C '*' 100 / $T`%]" endif  # ...  endif 

Hope that helps.

like image 33
phyatt Avatar answered Sep 28 '22 02:09

phyatt