make
интерпретирует нераспознанные аргументы командной строки, которые не начинаются с минуса ( -
), как целевые объекты для сборки. Таким образом, make install
приводит к сборке целевого объекта install
. Если целевой объект foo
устарел, make сначала соберет зависимости foo
, а затем инсталлирует его. Если требуется собрать целевой объект, начинающийся со знака минус, этот знак перед именем целевого объекта должен быть продублирован ( --
).
4.2.1 Сложные командные строки
Каждая командная строка выполняется в своей собственной подоболочке, таким образом, команды cd
в командной строке влияют только на строку, в которой они записаны. Любую строку в make-файле можно расширить на множество строк, указывая в конце каждой обратный слэш. Ниже показан пример того, как иногда могут выглядеть командные строки.
1: cd первый_ каталог ; \
2: сделать что-то с файлом $ (FOO) ; \
3: сделать еще что-то
4: cd второй_каталог ; \
5: if [ -f некоторый_файл ] ; then\
6: сделать что-то другое ; \
7: done; \
8: for i in * ; do \
9: echo $$i >> некоторый__файл ; \
10: done
make
находит в этом фрагменте кода только две строки. Первая командная строка начинается в строке 1 и продолжается до строки 3, а вторая начинается в строке 4 и заканчивается в строке 10. Здесь следует отметить несколько моментов.
• второй_каталог
является относительным не к каталогу первый_каталог
, а к каталогу, в котором запущен make
, поскольку эти команды выполняются в разных подоболочках.
• Строки, образующие каждую командную строку, передаются оболочке в виде одной строки. Таким образом, все символы ;
, которые нужны оболочке, должны присутствовать, включая даже те, которые обычно в сценариях оболочки опускаются, поскольку их наличие подразумевается благодаря символам новой строки. Более детально о программировании программной оболочки рассказывается в [22].
• Если требуется разыменовывать переменную make
, это делается обычным образом (то есть $( переменная )
), но если нужно разыменовывать переменную оболочки, необходимо применять двойной символ $
: $$i
.
Часто бывает необходимо определить только один компонент переменной за раз. Можно написать, например, такой код:
OBJS = foo.о
OBJS = $(OBJS) bar.о
OBJS = $(OBJS) baz.о
Ожидается, что здесь OBJS
будет определен как foo.о bar.о baz.о
, но в действительности он определен как $(OBJS) baz.о
, поскольку make
не разворачивает переменные до момента их использования [4] Несмотря на то что такое поведение выглядит неудобным, это важное средство, а не ошибка. Неразворачиваемые переменные критически важны при написании обобщенных суффиксных правил, которые создают подразумеваемые зависимости.
. При ссылке в правиле на OBJS make
войдет в бесконечный цикл [5] Большинство версий make, включая версию GNU, распространяемую с Linux, определят бесконечный цикл и завершатся с выдачей соответствующего сообщения об ошибке.
. Во избежание этого во многих make-файлах разделы организуются следующим образом:
OBJS1 = foo.о
OBJS2 = bar.о
OBJS3 = baz.о
OBJS = $(OBJS1) $(OBJS2) $(OBJS3)
Объявления переменных вроде предыдущего встречаются, когда объявление одной переменной оказывается слишком длинным и потому не удобным.
Развертывание переменной вызывает типичный вопрос, который программист в Linux должен решить. Инструменты GNU, распространяемые с Linux, обычно более функциональны, чем версии инструментов, включенных в другие системы, и GNU make
— не исключение. Авторы GNU make предусмотрели альтернативный способ присваивания переменных, но не все версии make
понимают эти альтернативные формы. К счастью, GNU make
можно собрать для любой системы, в которую можно перенести исходный код, написанных под Linux. Существует форма простого присваивания переменных, которая показана ниже.
OBJS := foo.о
OBJS := $(OBJS) bar.о
OBJS := $(OBJS) baz.о
Операция :=
заставляет GNU make
вычислить выражение переменной при присваивании, а не ждать вычисления выражения при его использовании в правиле. В результате выполнения этого кода OBJS
действительно получит foo.о bar.о baz.о
.
Простое присваивание переменной используется очень часто, но в GNU make
есть еще и другой синтаксис присваивания, который позаимствован из языка С:
Читать дальше