2009-01-16 141 views
21

看看這個makefile,它有某種基本的進度指示(可能是一個進度條)。Make/makefile進度指示!

請給我建議/意見吧!


 

# 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) 


所有的建議表示歡迎!

+1

可愛的把戲,但我看不到它。 – 2009-01-16 18:27:51

+1

我可以。在Gentoo上這會很好。 `cmake`有一個內置的計數器[文件x/n文件]。但是,如果不用每條命令行都可以獲得進度條而不會溢出屏幕,那就太好了。 – Evi1M4chine 2017-11-06 01:34:41

回答

6

這一個是少侵入性和更真棒

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 
1

好戲! ( - :

,但沒有真正可擴展的種植這些由許多分佈的目錄有很多的makefile的項目

我會更傾向於有記錄通過[MM] akefiles *在你的項目,並撒上用它來跟蹤進度

只是一個想法BTW感謝分享這個

編輯:。只是有一個想法這可能是在修改的形式是有好處的,以顯示活動指示器顯示進度。而一個長期的任務仍在繼續,例如解開一個大的分配ibution tarball,而不是隻爲tar命令指定-v選項。還有一點糖衣,但也有點有趣。 ( - :

歡呼聲,

羅布

+0

感謝您的評論,請你解釋一下爲什麼你認爲這不會縮放?好的代碼只是一個草圖,但如果需要,MAX可以保存64k x,並且T變量的計算速度非常快。 – 2009-01-16 18:51:43

2

這是一個輕微修改@ GiovanniFunchal的優秀answer

左右。我想更好地理解這一點,並使其適用於< 10%,因此我深入研究了documentation並瞭解了更多約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 

我擺脫了: '.*\(....\)$$'部分。它會返回內部expr命令的最後4個字符,但如果它小於4則會失敗。現在它適用於10%以下的內容!

這裏是評論免費版本:

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 

希望有所幫助。