2017-01-12 12 views
0

Я пытаюсь создать файл и установить содержимое файла в переменную, но переменная всегда считается пустой.Установить новый файл как переменную в make-файле

Пример:

define FILE_VAR 
    cat /output/1.txt >> /output/2.txt 
    $(eval s := $(shell cat /output/2.txt)) 
    $(eval FILENAME_BIN=$(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).bin) 
    $(eval FILENAME_JFFS2=$(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).jffs2)   
endef 

Если 2.txt существует перед запуском этой переменные будут установлены в данных перед запуском сделать (а не новые перенаправленные данные), если 2.txt не существует, то переменные не задано. Похоже, что он оценивает, что такое файл, когда первый запуск выполняется, а это не то, что я хочу ...

+0

Разве это не дубликат [ваш предыдущий пост] (http://stackoverflow.com/questions/41570930/using-eval-in-make-file)? Несколько комментариев, сделанных по этому сообщению, относятся к этому. Проводка [Минимальный, Полный и Подтверждаемый пример] (http://stackoverflow.com/help/mcve) настоятельно рекомендуется. –

ответ

2

Вы не знаете, что сделано GNU make, и когда и что делается shell, и когда, чтобы выполнить рецепт.

Все где-нибудь в Makefile формы $(...) оценивается make , если он не бежал, как $$(...) в команде оболочки.

Команда оболочки, если в контексте косметики функции $(shell ...) или обратно-тики не может быть только команда в рецепте:

target: [prerequisite...] 
    command 
    ... 

Команда, составляющие рецепты выполняется последовательно, каждый в отдельной оболочке , чтобы выполнить рецепт.

Ничего немаскированной форма $(...) не является командой в командной последовательности из рецепта, если это не является расширение переменного или макрокоманды вы определили, что расширяет к команде.

Линия в области действия цели не обязательно должна быть командой или расширена до команды. Он может также состоять из выражения $(...), которое не увеличивается до нуля, и просто инструктирует make, чтобы что-то сделать, например.

$(info ...) 

расширяет ничего и говорит make для печати ... на стандартный вывод.

$(eval ...) 

расширяет ничего и говорит make оценить ...

Этот рецепт имеет только две команды, а не четыре:

target: prereq... 
    $(eval [email protected]) 
    command1 
    $(info $(TARGET)) 
    command2 

Есть подпиточной выражения, $(...) в области видимости рецепте оценивается в последовательности, когда make решает запустить рецепт , а командная последовательность - это то, что осталось после того, как все они были оценены d. Затем выполняется командная последовательность.Например:

Makefile

target: 
    echo Hello > hello.txt 
    $(info Begin {) 
    $(eval s := $(shell cat hello.txt)) 
    $(eval WORD=$(word 1, $(s))) 
    $(info [$(WORD)]) 
    $(info } End) 

Run что:

$ make 
Begin { 
cat: hello.txt: No such file or directory 
[] 
} End 
echo Hello > hello.txt 

Заметим, что все замыкающие выражений оцениваются до того в команды мишени запускаются.

Ваш макрос FILE_VAR, очевидно, предназначен для расширения в области рецептов, так как первая строка представляет собой команду оболочки. Таким образом, оставшиеся линии должны достичь своих целей командами оболочки, если они зависят от последствий работы первой линии. Ни один из них не делает этого. Оставшиеся 3 строки оцениваются до 2.txt, если он еще не существует во время выполнения.

+0

Спасибо, Майк, отличный ответ. Никогда раньше не использовалось так, чтобы оно было очень информативным. То, что я в основном беру от ti для решения моей проблемы, состоит в том, что Make оценивает выражения до того, как я их желаю, поэтому должен делать все через оболочку. Вот почему, если мой файл существует во время выполнения и изменяется, я читаю старые значения в файле. – Paul

+0

Да. Почти всегда правильно составлять рецепт строк, которые являются командами оболочки , или развернуть до команд оболочки после расширения обычных, глобальных make-переменных и макросов. Случаи, в которых ['$ (eval ...)'] (https://www.gnu.org/software/make/manual/html_node/Eval-Function.html) исправны в рецепте, необычны. См. [Как сделать чтение Makefile] (https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html) и в целом обратитесь к [manual] (https: //www.gnu .org/software/make/manual/make.html) для руководства. –

+0

Отличный материал, приветствия. – Paul

 Смежные вопросы

  • Нет связанных вопросов^_^