2013-04-08 3 views
4

Я изучаю makefile. У меня проблема в понимании использования eval в make-файле.Как использовать eval в Makefile

Это мой Makefile: не

testt: 
    @R=5 
    $(eval $(echo $R)) 

когда я бегу делают testt, отображается ничего. Не могли бы вы показать мне, в чем причина? Большое спасибо.

ответ

7

Я не знаю, что stackoverflow - это лучшее место для уровня информации, который вы ищете здесь. Это лучше всего подходит для ответа на конкретные вопросы, но на основе этого примера вам нужно сначала получить более фундаментальное понимание.

FYI, первая строка в вашем тесте устанавливает оболочка переменная R. Затем заканчивается эта строка, которая выходит из этого вызова оболочки, и теперь ваша переменная утеряна. Затем в следующей строке вы получите значение переменной R путем ссылки $R. Это никогда не было нигде, поэтому всегда есть пустая строка. Затем вы пытаетесь дать это функции make $(echo ...), но в make нет такой функции, чтобы она также расширялась до пустой строки. Затем вы передаете полученную пустую строку в функцию $(eval ...), а оценка пустой строки приводит к другой пустой строке, которая затем предоставляется оболочке в качестве команды для запуска, которая ничего не делает.

Если вы хотите задать конкретный вопрос («как мне сделать XYZ?»), Тогда мы сможем дать ответ ... но для этого потребуется значительная часть руководства GNU. Также вы можете запросить список рассылки [email protected]

+0

Благодарим вас за быстрый ответ. Я сожалею о моем вопросе о новичках, но я не понимаю, что причиной является пустая переменная. Я попробовал: testt: $ (eval $ (echo abc)) , но еще раз, ничего не отображается. – AlexTP

+0

@PatrickDiwel: 'echo' - это команда оболочки, но вы пытаетесь ее оценить, как если бы это была функция Make. – Beta

+2

Опять же, я думаю, что stackoverflow не подходит для такого уровня вопроса. Я настоятельно призываю вас перенаправить свой вопрос в список рассылки [email protected]: у них гораздо больше опыта, обеспечивающего фундаментальные понимания. Функция '$ (eval ...)' в make - это очень сложная тема. Если вы не очень четко понимаете разницу между переменными оболочки и производными переменными, а также командами оболочки и выполняете функции и которые используются, когда и как они взаимодействуют, то понимание '$ (eval ...)' просто не реалистично. – MadScientist

5

Когда make читается в вашем файле makefile, он сохраняет блок команд оболочки для testt как единую рекурсивно расширенную переменную. Ничего неприятного еще не произошло.

После прочтения в своем файле make make теперь решает, что нужно построить. testt - первая цель, так что у нее есть шанс. У вас нет файла с именем testt в вашей файловой системе, поэтому решите, что он должен запускать блок команд оболочки.

В этот момент он пытается расширить переменную, с которой она раньше безводила. Он начинается с

@R=5 
$(eval $(echo $R)) 

Первый - это расширение $R. Расширение пусто, оставляя сделать с

@R=5 
$(eval $(echo)) 

Теперь он расширяется $(echo). Эта переменная не существует либо, и сделать уже дошел до

@R=5 
$(eval) 

Make знает о $(eval ...), но выход всегда пуст. Таким образом, теперь делают имеет

@R=5 

Расширение закончено, и делают в настоящее время проходит каждую линию отдельно и последовательно на свежие призываний оболочки, проверяя код возврата каждого из них. Итак, оболочка видит R=5. Эта команда (простое присвоение переменной оболочки) завершается без ошибок. Make не делает это для stdout из-за префикса @. Все сделано.

Всегда бегать с --warn-undefined-variables.

$ make --warn-undefined-variables 
Makefile:3: warning: undefined variable `R' 
Makefile:3: warning: undefined variable `echo ' 
make: Nothing to be done for `testt'. 

(Обратите внимание на то, что дополнительное пространство в конце имени переменной:. `echo ' (да, вы можете иметь имена переменных, которые содержат пробелы))

О, и в то время как я на него, $(eval ...) действительно полезен, но не использует его в командах оболочки. Это редко имеет смысл.

+0

Такое хорошее объяснение, но вы все еще не представили исправленное выражение. –

+0

@ Nik-Lz На самом деле нет исправленного выражения. Как я уже сказал, рецепт (обычно) - неправильное место для '$ (eval ...)'. Фрагмент _make_ OP показывает ряд других недоразумений. Я просто хотел прояснить проблему с помощью _eval_. @MadScientist охватывает все остальные в своем ответе. – bobbogo