Ответ основан на простой точке с большими разветвлениями - в файле makefile есть два диалекта, 1) сам язык создания и 2) язык оболочки, который вы используете для таких вещей, как вызов gcc
.
Напоминания о нормальном макияже «правила» Синтаксис:
targets : prerequisites
recipe
Пока цель марки и предпосылка находятся в сделать синтаксис, материал в рецепте есть в синтаксисе оболочки , не делает синтаксис ,
Это объясняет, почему вы не можете делать такие вещи, как правопреемник сделать переменные как часть рецепта, как это:
all: the_dependencies_of_all
this_will_not_work := because_the_shell_does_not_know_what_this_line_means
В синтаксисе оболочки бит, сделать это три специальные текстовые манипуляции, а затем оставшаяся строка передан дословно в оболочку. Эти три шага
- сделка с сбежавших переносом строк (например, обратный слеш с последующим новой строкой)
- запустить любую марку функция (как
$(filter ....)
и $(eval ..)
- расширить любой сделать целевую переменные (как
[email protected]
)
В нормальном случае эти процессы с тремя шагами, а затем оболочками происходят один раз на линию рецепта, поэтому каждая строка вашего рецепта makefile запускается в другой оболочке (следовательно, некоторые вызовы make
порождают множество /bin/sh
).
Манипуляция # 2 выше объясняет, почему вы можете использовать eval
внутри рецепта, чтобы добавить синтаксис make к вашему рецепту. Eval превратится в пустую строку, которая не вызовет проблем с оболочкой, но make будет оценивать строку внутри вашего оператора, поэтому возможны такие вещи, как определения переменных.
Точный момент, когда эта оценка происходит, немного сложна, чтобы ее можно было сбрасывать - кажется, это происходит, когда переменная сначала расширяется, что само зависит от того, где вы ссылаетесь на эту переменную в своем файле.Возможно, кто-то может прояснить это немного больше, так как, когда это происходит уже последствия для призываний марки, которые используют -j
флаг для запуска нескольких линий рецепта параллельно
Дополнительная информация:
консервированный рецепт документации, вы ссылаетесь на переговоры о _shell_ фрагменты, а не Make (фактически, само слово «рецепт» в контексте Make всегда означает «часть кода оболочки правила»). –
@MichaelLivshin спасибо, это был лакомый кусочек, мне нужно было очистить все мое замешательство. Если вы хотите опубликовать его как «ответ», я буду рад принять – Hamy