install
приводит к сборке целевого объекта install
. Если целевой объект foo
устарел, make сначала соберет зависимости foo
, а затем инсталлирует его. Если требуется собрать целевой объект, начинающийся со знака минус, этот знак перед именем целевого объекта должен быть продублирован (--
).
4.2.1 Сложные командные строки
Каждая командная строка выполняется в своей собственной подоболочке, таким образом, команды cd
в командной строке влияют только на строку, в которой они записаны. Любую строку в make-файле можно расширить на множество строк, указывая в конце каждой обратный слэш. Ниже показан пример того, как иногда могут выглядеть командные строки.
1: cd
2:
3:
4: cd
5: if [ -f
6:
7: done;
8: for i in * ; do
9: echo $$i >>
10: done
make
находит в этом фрагменте кода только две строки. Первая командная строка начинается в строке 1 и продолжается до строки 3, а вторая начинается в строке 4 и заканчивается в строке 10. Здесь следует отметить несколько моментов.
•
является относительным не к каталогу
, а к каталогу, в котором запущен make
, поскольку эти команды выполняются в разных подоболочках.
• Строки, образующие каждую командную строку, передаются оболочке в виде одной строки. Таким образом, все символы ;
, которые нужны оболочке, должны присутствовать, включая даже те, которые обычно в сценариях оболочки опускаются, поскольку их наличие подразумевается благодаря символам новой строки. Более детально о программировании программной оболочки рассказывается в [22].
• Если требуется разыменовывать переменную make
, это делается обычным образом (то есть $(
), но если нужно разыменовывать переменную оболочки, необходимо применять двойной символ $
: $$i
.
4.2.2. Переменные
Часто бывает необходимо определить только один компонент переменной за раз. Можно написать, например, такой код:
OBJS = foo.о
OBJS = $(OBJS) bar.о
OBJS = $(OBJS) baz.о
Ожидается, что здесь OBJS
будет определен как foo.о bar.о baz.о
, но в действительности он определен как $(OBJS) baz.о
, поскольку make
не разворачивает переменные до момента их использования[4]. При ссылке в правиле на OBJS make
войдет в бесконечный цикл[5]. Во избежание этого во многих 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
есть еще и другой синтаксис присваивания, который позаимствован из языка С:
OBJS := foo.о
OBJS += bar.о
OBJS += baz.о
4.2.3. Суффиксные правила
Суффиксные правила — это другая область, в которой вам нужно решить, писать ли стандартные make-файлы или использовать расширения GNU. Стандартные суффиксные правила намного ограниченнее, нежели шаблонные правила GNU, но во многих ситуациях стандартные суффиксные правила могут оказаться полезными. К тому же шаблонные правила поддерживаются не во всех версиях make
. Суффиксные правила выглядят следующим образом:
.c.o:
$(CC) -с $ (CFLAGS) $ (CPPFLAGS) -о $<
.SUFFIXES: .с .о
В этом правиле говорится (если не касаться излишних деталей), что make
должна, а.с
в а.о
путем запуска приложенной командной строки. Каждый файл .с
будет рассматриваться так, будто он явно внесен в список в качестве зависимости соответствующего файла .о
в вашем make-файле.
Это суффиксное правило демонстрирует другую возможность make
— автоматические переменные. Понятно, что нужно найти способ подставить зависимость и целевой объект в командную строку. Автоматическая переменная $@
выступает в качестве целевого объекта, $<
выступает в качестве первой зависимости, а $^
представляет все