2009-01-16 4 views
21

Schauen Sie sich dieses Makefile an, es hat eine Art primitiver Fortschrittsanzeige (könnte ein Fortschrittsbalken sein).Make/Makefile Fortschrittsanzeige!

Bitte geben Sie mir Anregungen/Kommentare dazu!


 

# 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 [email protected] 
    $(BUILD) 

%.c: 
    @touch [email protected] 
    $(BUILD) 


Alle Vorschläge willkommen!

+1

Netter Trick, aber ich kann nicht sehen, es zu wollen. –

+1

kann ich. Auf Gentoo wäre das nett. 'cmake' hat einen eingebauten Zähler [file x/n files]. Aber eine Möglichkeit, einen Fortschrittsbalken zu haben, ohne den Bildschirm mit jeder Befehlszeile zu überfluten, wäre schön. – Evi1M4chine

Antwort

6

Dieser ist weniger aufdringlich und ehrfürchtige

ifneq ($(words $(MAKECMDGOALS)),1) 
.DEFAULT_GOAL = all 
%: 
     @$(MAKE) [email protected] --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 [email protected] 
     @sleep 0.1 
     @touch [email protected] 

%.c: 
     @$(ECHO) Compiling [email protected] 
     @sleep 0.1 
     @touch [email protected] 

endif 
+0

das ist ein toter Link – thejoshwolfe

+0

@Giovanni Funchal, können Sie den Link bitte aktualisieren? – thegreendroid

+0

haha, welcher Link !? rsrs – JohnTortugo

1

Netter Trick! (-:.

aber nicht wirklich skalierbar für Projekte wachsen, die sich über viele Verzeichnisse mit vielen Makefiles verteilt sind

Ich würde eher geneigt sein, die Protokollierung durch die [mm] akefiles bestreut zu haben * in Ihrem Projekt und verwenden, die Spur des Fortschritts zu halten

Nur so ein Gedanke BTW Dank dieses für den Austausch von

Edit:... hatte nur einen Gedanken Dies in einer modifizierten Form nützlich sein könnte, einen throbber anzuzeigen Fortschritt zu zeigen. während eine lange Aufgabe abläuft, z. B. Auspacken eines großen Distr ibution tarball, anstatt nur die Option -v für den Befehl tar anzugeben. Noch ein bisschen Zuckerguss, aber auch ein bisschen Spaß. (-:

prost,

Rob

+0

Danke für Ihren Kommentar, können Sie bitte erklären, warum Sie denken, dass dies nicht skaliert? Ok, der Code ist nur eine Skizze, aber MAX kann bei Bedarf 64k x speichern, und die Berechnung der T-Variablen ist ziemlich schnell. –

+0

Es wird nicht skaliert, da es nicht funktioniert, wenn Sie make über mehrere Verzeichnisse verwenden, wobei jedes Unterverzeichnis über ein eigenes Makefile verfügt. –

+0

@ ScottieT812, Prost, das war der Hauptgrund für meinen Kommentar!(-: Der andere muss ständig die Anzahl der benötigten x berechnen und aktualisieren, wenn das Projekt erweitert wird. Trotzdem. Netter Trick. –

2

Dies ist eine leichte Modifikation an @ GiovanniFunchal ausgezeichnete answer

So.. Ich wollte das besser verstehen und es für < 10% arbeiten lassen, also grub ich in die documentation und lernte mehr über 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 
# [email protected] = 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) [email protected] --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 

Ich habe den : '.*\(....\)$$' Teil losgeworden. Es würde die letzten 4 Zeichen des inneren Befehls expr zurückgeben, würde aber scheitern, wenn es weniger als 4 wäre. Und jetzt funktioniert es für unter 10%!

Und hier ist der Kommentar kostenlose 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) [email protected] --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 

Hoffnung, das hilft.