Как вы отметили в своем комментарии, проблема в том, что цикл for выполняется внутри оболочки и поэтому не обновляет переменные Makefile (или, по крайней мере, не более одного раза, когда Make создает командную строку путем оценки ссылок на переменные).внутри него).
Единственное возможное решение, которое я вижу, это переместить вашу конструкцию цикла в Makefile.Попробуйте это:
## PRINT_PROGRESS is initially undefined
ifndef PRINT_PROGRESS
# T estimates how many targets we are building by replacing PRINT_PROGRESS with a special string
T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
-rRf $(firstword $(MAKEFILE_LIST)) \
PRINT_PROGRESS="echo COUNTTHIS" BUILD="test x ||" | grep -c "COUNTTHIS")
N := 1
## PRINT_PROGRESS is now defined to show the progress and update N
PRINT_PROGRESS = echo "`expr " [\`expr $N '*' 100 / $T\`" : '.*\(....\)$$'`%]"$(eval N := $(shell expr $N + 1))
endif
ifndef BUILD
BUILD := #blank
endif
MODULE_LIST = module1
MODULE_LIST += module2
MODULE_LIST += module3
MODULE_LIST += module4
MODULE_LIST += module5
simple:
# T=5 and C increases for every access
@$(PRINT_PROGRESS) "Cleaning Module \"module1\""
@$(BUILD) { sleep 0.1 ; echo "doing some work" ; }
@$(PRINT_PROGRESS) "Cleaning Module \"module2\""
@$(BUILD) { sleep 0.1 ; echo "doing some work" ; }
@$(PRINT_PROGRESS) "Cleaning Module \"module3\""
@$(BUILD) { sleep 0.1 ; echo "doing some work" ; }
@$(PRINT_PROGRESS) "Cleaning Module \"module4\""
@$(BUILD) { sleep 0.1 ; echo "doing some work" ; }
@$(PRINT_PROGRESS) "Cleaning Module \"module5\""
@$(BUILD) { sleep 0.1 ; echo "doing some work" ; }
for:
@$(foreach MODULE,$(MODULE_LIST),\
$(PRINT_PROGRESS) "Cleaning Module \"$(MODULE)\"" ; \
$(BUILD) { \
sleep 0.1 ; \
echo "doing some work" ; \
} ; \
)
Это включает в себя также несколько других изменений.
Решение, которое кажется правдоподобным на первый взгляд, состоит в export N
из make-файла и разработке команды PRINT_PROGRESS
так что N
всегда обновляется как переменная окружения.Я не смог найти способ заставить эту работу работать, так как для этого требуется какой-то способ получить обновленное N значение назад в Make после после командынаписано, так что отдельные команды все еще работают.
Редактировать: Вывод при запуске точного сценария выше (с исправленными отступами табуляции), плюс используемые версии:
jpab@oberon : /memtmp
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
jpab@oberon : /memtmp
$ bash --version
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
jpab@oberon : /memtmp
$ make
# T=5 and C increases for every access
[20%] Cleaning Module "module1"
doing some work
[40%] Cleaning Module "module2"
doing some work
[60%] Cleaning Module "module3"
doing some work
[80%] Cleaning Module "module4"
doing some work
[100%] Cleaning Module "module5"
doing some work
jpab@oberon : /memtmp
$ make for
[20%] Cleaning Module "module1"
doing some work
[40%] Cleaning Module "module2"
doing some work
[60%] Cleaning Module "module3"
doing some work
[80%] Cleaning Module "module4"
doing some work
[100%] Cleaning Module "module5"
doing some work