Здесь вы идете
function randomChoice(arr) {
return arr[Math.floor(arr.length * Math.random())];
}
Это поведение make
. make
расширит рецепты цели перед ее выполнением.
Рецепт $(eval NEW_VER:=$(shell cat version | cut -d '_' -f 2 ))
будет расширен, а переменная NEW_VER
будет сохранена в списке переменных со значением V7.1.2.3 (из файла версии). Поскольку версия еще не обновлена в файле версии. Рецепт echo $(NEW_VER)
будет заменен на echo V7.1.2.3
.
Перед выполнением рецепты цели firmware
будут
cat version
sed -i 's/V7/V177/g' version
cat version
echo V7.1.2.3
Следовательно, в конце выводится печать старой версии.
Чтобы это работало, поставьте две разные цели. Один для изменения версии в файле и другой для чтения.
blockquote>Makefile:
all: replace_version read_version replace_version: cat version sed -i 's/V7/V177/g' version read_version: cat version $(eval NEW_VER:=$(shell cat version | cut -d '_' -f 2 )) echo $(NEW_VER)
Существует другой возможный способ заставить эту работу работать с одной целью. Измените команду
blockquote>sed
как расширяемый рецептMakefile:
firmware: $(call version_replace, 100)
image.mk
[113 ]
Ваше явление может быть сведено к простому, хотя и загадочному примеру:
MY_OUTPUT := First line
.PHONY: foo
foo:
@echo $(MY_OUTPUT)
$(eval MY_OUTPUT := $(shell $(info eval-time) echo Second line))
@echo $(MY_OUTPUT)
$(shell read -p "Hit return:")
Вывод:
$ make foo
eval-time
Hit return:
... в ожидании нажатия клавиши [117 ]
blockquote>First line Second line
Оценка рецепта выглядит следующим образом: Выделите буфер строк, которые будут содержать командные строки окончательного рецепта без синтаксиса make. Затем пройдитесь по всем строкам рецепта, выполните весь известный синтаксис make, удалите один уровень из всех кавычек (
$
), выполните вещи$(eval)
и запишите строки в буфер. только затем перебирают результирующий список командных строк и выдают ихsh
по очереди.$(info)
говорит нам, что строка аргумента уже была оценена заранее, что нарушает ваш предполагаемый порядок.
Может быть трудно заставить call
работать с несколькими командами, как у вас, поэтому иногда мне проще (хотя и менее переносимо) создать вместо этого сценарий оболочки:
Makefile
EXEC := $(shell sh script.sh)
FILE := new_version
VERS := $(shell cat $(FILE))
.PHONY: firmware
firmware:
$(info $(VERS))
script.sh
#!/bin/bash
sed 's/V7/V177/g' version | cut -d '_' -f 2 > new_version
# optional # mv new_version version
При желании вы можете перезаписать файл version
, раскомментировав последнюю строку в скрипте и изменив FILE
переменная в Makefile
- version
вместо.
$ make firmware
V177.1.2.3
make: Nothing to be done for `firmware'.
Я бы разделил две вещи следующим образом:
.PHONY: firmware
firmware: version
# replace with firmware generation command that reads from [110]lt;
@echo FIRMWARE $@ [110]lt;
.PHONY: version
version:
# replace with version update command (sequence)
@echo VERSION $@
Строительство firmware
приведет к такой последовательности:
$ make firmware
# replace with version update command (sequence)
VERSION version
# replace with firmware generation command that reads from version
FIRMWARE firmware version
РЕДАКТИРОВАТЬ: ваше требование для разных версий приращения должна быть переменная, управляющая командными строками для цели version:
, например make VERSION_INCREMENT=200 firmware
.