Определите переменную на основе результата выполнения команды в Makefile.

Вопрос или проблема

Я пытаюсь использовать makefile для объединения сочетания команд, которые должны выполняться одна за другой. Часть makefile выглядит следующим образом:

.PHONY: dispersion
all: dispersion

-include make.in

dispersion:
    phonopy --qe -d --dim='$(nx) $(ny) $(nz)' -c $(material)_primitive.in 
    $(eval VAR=$(shell grep nat supercell.in))
    echo $(VAR)

По сути, первая строка создает файл с именем “supercell.in”, а вторая создает переменную с именем VAR, которая будет использоваться в последующих строках. Вышеуказанное не присваивает значение переменной, и я предполагаю, что это связано с приоритетом выполнения строк. Я был бы признателен за способ решения этой проблемы.

Попробуйте использовать оператор обратных кавычек для выполнения команды.

.PHONY: dispersion
all: dispersion

-include make.in

dispersion:
    phonopy --qe -d --dim='$(nx) $(ny) $(nz)' -c $(material)_primitive.in
    $(eval VAR=`grep nat supercell.in`)
    echo $(VAR)

Я полагаю, что проблема связана с тем, когда $(shell) оценивается интерпретатором.

Ответ или решение

Ваша проблема связана с тем, что команда $(eval VAR=$(shell ...)) выполняется на этапе разбора Makefile, а не во время выполнения цели. В результате переменная VAR не будет иметь значение, которое вы ожидаете.

Чтобы правильно назначить переменную на основе результата выполнения команды, вы можете использовать $(shell ...) в самом правиле или непосредственно внутри команды. Таким образом, результатами выполнения команды будет являться переменная, которую вы сможете использовать позже.

Вот как можно изменить ваш Makefile:

.PHONY: dispersion
all: dispersion

-include make.in

dispersion:
    phonopy --qe -d --dim='$(nx) $(ny) $(nz)' -c $(material)_primitive.in
    VAR=$(shell grep nat supercell.in)
    echo $$VAR

Обратите внимание, что вместо $(eval ...) мы просто создаем переменную VAR и присваиваем ей результат команды grep. Также при выводе значения переменной необходимо использовать двойной символ доллара ($$), чтобы указать make, что вы хотите использовать значение переменной, а не создать новую переменную.

Этот подход позволяет вам использовать результат выполнения команды grep nat supercell.in в следующей строке в рамках одной цели. Таким образом, вы получите значение переменной VAR, присвоенное непосредственно в процессе выполнения команды.

Если вам всё же нужно использовать значение VAR в нескольких местах в вашем Makefile, вы можете применить следующий подход:

.PHONY: dispersion
all: dispersion

-include make.in

dispersion:
    phonopy --qe -d --dim='$(nx) $(ny) $(nz)' -c $(material)_primitive.in
    @VAR=$(shell grep nat supercell.in); \
    echo $$VAR; \
    # здесь вы можете продолжить использовать $$VAR в других командах

В этом примере используется @ перед командой для предотвращения вывода самой команды в терминал (выводится только результат), а VAR будет доступен в рамках этой последовательности команд благодаря продолжению в том же контексте.

Надеюсь, это поможет вам правильно определить переменную на основе результата выполнения команды в вашем Makefile.

Оцените материал
Добавить комментарий

Капча загружается...