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!
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With