Переменная не найдена в рецепте makefile

Как насчет ПОЦЕЛУЯ

sed '1,/^Previous/!d' file | head -n -2
0
19.08.2020, 23:46
2 ответа

Посмотрел твой шлейф... цитируется здесь:

.PHONY: test
test:
    @$(eval export files = $(shell ls))
    for f in $(files) ; do \
        t = $(ls | grep $$f) ; \
        echo $$t;\
    done

Итак... $(eval... )запускает команду make.

$(shell ls)запускает команду lsв оболочке и подменяет ее вывод.

Таким образом, команда, запускаемая $(eval... ), похожа на export files = file file2 makefile source.c. Эта команда создает переменную make с именем files и экспортирует ее в дочерние make. Таким образом, экспорт, вероятно, не нужен.

Целиком $(eval... ), вероятно, можно было бы заменить на files = $(wildcard *)И, возможно, использовать :=и поместить вне правила.

Цикл for, состоящий из четырех строк, выполняется в оболочке. Первое, что делается, это подстановка переменных и функций make. Странным является $(ls | grep $$f). Поскольку ls не является функцией make, она попытается расширить переменную, которая не определена. Это пустая строка. Если это должен был быть оператор оболочки $(...), вам нужно удвоить $. $$расширяется до $. $(files)расширен на основе eval.

Это становится (с использованием моего предыдущего примера):

for f in file file2 makefile source.c ; do
    t =
    echo $t;
done

На первый взгляд может показаться, что это четыре пустые строки, но нет. Команда t =фактически запускает программу tи передает знак равенства в качестве аргумента. tскорее всего не существует. Таким образом, мы получаем четыре ошибки о том, что t не является корректной программой, за каждой из которых следует пустая строка (, если только t не определена в другом месте ).

Что-то более близкое к тому, что вы хотели:

files := $(wildcard *)
.PHONY: test
test:
    for f in $(files) ; do \
        t=$$(ls | grep $$f) ; \
        echo $$t ; \
    done

Будет выведено:

file file2
file2
makefile
source.c

Обратите внимание, что в первой строке перечислены два файла, так как в именах обоих есть слово «файл». Если это не то, что вы хотите, вы можете рассмотреть:

files := $(wildcard *)
.PHONY: test
test:
    for f in $(files) ; do \
        echo $$f ; \
    done

или даже (могут быть специфичными для GNU make):

files := $(wildcard *)
.PHONY: test
test:
    $(foreach f, $(files), echo $f ; )
1
18.03.2021, 23:11

Внутри рецепта make target команды обрабатываются иначе (путем порождения оболочки ), чем логика вне рецепта.

Вы можете переместить переменную за пределы рецепта:

.PHONY: test
foo := $(shell ls | grep makefile)
test:
    echo $(foo)

или, благодаря этому вопросу , используйте eval:

.PHONY: test
test:
    $(eval foo=$(shell ls | grep makefile))
    echo $(foo)

Оба выводят следующее:

echo makefile
makefile
1
18.03.2021, 23:11

Теги

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