Чтение обновленного файла в функции Makefile

Здесь вы идете

function randomChoice(arr) {
    return arr[Math.floor(arr.length * Math.random())];
}
0
задан Nayab Basha Sayed 18 January 2019 в 07:36
поделиться

4 ответа

Это поведение 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

Следовательно, в конце выводится печать старой версии.

Чтобы это работало, поставьте две разные цели. Один для изменения версии в файле и другой для чтения.

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)

Существует другой возможный способ заставить эту работу работать с одной целью. Измените команду sed как расширяемый рецепт

Makefile:

firmware:
        $(call version_replace, 100)

image.mk

[113 ]
0
ответ дан Thiyagarajan P 18 January 2019 в 07:36
поделиться

Ваше явление может быть сведено к простому, хотя и загадочному примеру:

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 ]

First line
Second line

Оценка рецепта выглядит следующим образом: Выделите буфер строк, которые будут содержать командные строки окончательного рецепта без синтаксиса make. Затем пройдитесь по всем строкам рецепта, выполните весь известный синтаксис make, удалите один уровень из всех кавычек ($), выполните вещи $(eval) и запишите строки в буфер. только затем перебирают результирующий список командных строк и выдают их sh по очереди. $(info) говорит нам, что строка аргумента уже была оценена заранее, что нарушает ваш предполагаемый порядок.

0
ответ дан Vroomfondel 18 January 2019 в 07:36
поделиться

Может быть трудно заставить 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'.
0
ответ дан l'L'l 18 January 2019 в 07:36
поделиться

Я бы разделил две вещи следующим образом:

.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.

0
ответ дан Stefan Becker 18 January 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: