Как создать Makefile
GNU make выполняет свою работу в двух отдельных фазах. В первой фазе он считывает все makefiles, включенные makefiles и т. д., интернализует все переменные и их значения, неявные и явные правила и строит граф зависимостей всех целей и их предпосылок. Во второй фазе make использует эти интернализованные данные, чтобы определить, какие цели нужно обновить, и выполнить рецепты, необходимые для их обновления.
Важно понимать этот двухфазный подход, потому что он напрямую влияет на то, как происходит расширение переменных и функций; это часто является источником путаницы при написании makefiles. Ниже приведён обзор различных конструкций, которые можно найти в makefile, и фаза, в которой происходит расширение каждой части конструкции.
Мы говорим, что расширение является немедленным, если оно происходит во время первой фазы: make будет расширять эту часть конструкции при разборе makefile. Мы говорим, что расширение является отложенным, если оно не является немедленным. Расширение отложенной части откладывается до тех пор, пока расширение не будет использовано: либо когда оно ссылается в немедленном контексте, либо когда оно необходимо во время второй фазы.
Вы, возможно, ещё не знакомы с некоторыми из этих конструкций. Вы можете обратиться к этому разделу по мере знакомства с ними в последующих главах.
Присваивание переменной
Определения переменных анализируются следующим образом:
immediate = deferred immediate ?= deferred immediate := immediate immediate ::= immediate immediate :::= immediate-with-escape immediate += deferred or immediate immediate != immediate define immediate deferred endef define immediate = deferred endef define immediate ?= deferred endef define immediate := immediate endef define immediate ::= immediate endef define immediate :::= immediate-with-escape endef define immediate += deferred or immediate endef define immediate != immediate endef
Для оператора добавления «+=» правая часть считается немедленной, если переменная ранее была установлена как простая переменная («:=» или «::=»), и отложенной в противном случае.
Для оператора немедленного-с-эскейпом «:::=» значение в правой части немедленно расширяется, а затем экранируется (то есть все вхождения $ в результате расширения заменяются на $$).
Для оператора присваивания оболочки «!=» правая часть вычисляется немедленно и передаётся оболочке. Результат сохраняется в переменной, указанной слева, и эта переменная считается рекурсивно расширяемой переменной (и, следовательно, будет переоцениваться при каждом обращении).
Условные директивы
Условные директивы анализируются немедленно. Это означает, например, что автоматические переменные не могут быть использованы в условных директивах, так как автоматические переменные не устанавливаются до тех пор, пока не вызывается рецепт для этой правила. Если вам нужно использовать автоматические переменные в условной директиве, вы должны перенести условие в рецепт и использовать синтаксис условных выражений оболочки вместо этого.
Определение правила
Правило всегда расширяется одинаково, независимо от формы:
immediate : immediate ; deferred
deferred
То есть, разделы цели и предпосылок расширяются немедленно, а рецепт, используемый для построения цели, всегда отложен. Это верно для явных правил, правил шаблонов, правил суффиксов, статических правил шаблонов и простых определений предпосылок.
Copyright © 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html