MAKE(1)
НАЗВАНИЕ
make - поддержка, обновление и восстановление групп
программ
СИНТАКСИС
make [-f make-файл] [-p] [-i] [-k] [-s] [-r] [-n] [-b] [-e] [-u] [-t] [
[целевой_файл ...]
ОПИСАНИЕ
Утилита make позволяет поддерживать, изменять и регенерировать группы программ. Ниже приведено краткое описание всех опций и некоторых специальных имен:
- -f make-файл
-
Задание имени файла с описаниями.
- -p
- Вывести все макроопределения, а также описания зависимостей и операций для создания целевых_файлов.
- -i
- Игнорировать коды ошибок, возвращаемых запускаемыми программами. Этот режим устанавливается также
при появлении в файле описаний специального целевого имени .IGNORE.
- -k
- При ошибке прекращать выполнение команд, связанных
с текущей зависимостью, но продолжать обработку
других зависимостей.
- -s
- Не выводить командные строки перед их выполнением.
Этот режим устанавливается также при появлении в
файле описаний специального целевого имени
.SILENT.
- -r
- Не использовать встроенные правила.
- -n
- Выводить команды, но не выполнять их. Выводятся
даже команды, которые начинаются с @.
- -b
- Режим для совместимости со старыми версиями
make-файлов.
- -e
- В первую очередь используются переменные окружения, а не одноименные макросы make-файлов.
- -u
- Вызывает безусловное обновление.
- -t
- "Массаж" целевых_файлов: время их создания устанавливается равным текущему времени; команды,
предназначенные для получения целевых_файлов, не
выполняются.
- -q
- Запрос. Команда make возвращает нулевой или ненулевой код завершения в зависимости от того, нужно
ли обновлять целевые_файлы (0, если не нужно). Печать команд подавляется, даже если присутствует
опция -n.
- .DEFAULT
-
Если должен быть сделан файл, но нет ни явных команд, ни соответствующих встроенных правил, то используются команды, ассоциированные со специальным
целевым именем .DEFAULT, если они существуют.
- .PRECIOUS
-
Файлы, которые зависят от этого специального имени, не удаляются, если работа команды make была
прервана или прекращена.
- .SILENT
-
Дает тот же эффект, что и опция -s.
- .IGNORE
-
Дает тот же эффект, что и опция -i.
Make выполняет команды из make-файла для обновления одного или нескольких целевых_файлов, имена которых указаны в команде. Если отсутствует опция -f, то ищутся
файлы makefile, Makefile, и файлы системы управления
исходными текстами (SCCS) s.makefile и s.Makefile в
указанном порядке. Если вместо make-файла указан -, то
это означает стандартный ввод. В командной строке может
встретиться более чем одна пара -f make-файл.
Команда make обновляет целевой_файл только в том случае, если файлы, от которых он зависит, оказываются новее в смысле времени модификации (кроме случая, когда
была использована опция -u с целью вызвать безусловное
обновление). Все файлы, от которых зависит целевой_файл
добавляются рекурсивно к списку целевых файлов. Отсутствующие файлы считаются требующими обновления.
Make-файл состоит из последовательности разделов, определяющих зависимости. Первая строка раздела - непустой
список разделенных пробелами имен целевых файлов, затем
знак :, затем (возможно пустой) список необходимых файлов или зависимостей. Текст, следующий за ; и все последующие строки, начинающиеся с табуляции, представляет
собой команды shell'а, которые необходимо выполнить для
обновления целевого файла. Первая строка, которая не
начинается с табуляции или #, открывает новое описание
зависимости или макроопределение. Команды shell'а могут
быть продолжены в следующей строке, если последним символом текущей строки поставить \. Все, что выводит
make, кроме начальных символов табуляции, передается
shell'у в исходном виде. Например,
echo a\
b
даст
ab
как если бы команда выполнялась просто shell'ом.
Символы # и перевод_строки обрамляют комментарии.
В приведенном ниже make-файле определяется, что pgm зависит от двух файлов: a.o и b.o, и что они в свою очередь зависят от соответствующих исходных файлов (a.c и
b.c) и общего файла incl.h:
pgm: a.o b.o
cc a.o b.o -o pgm
a.o: incl.h a.c
cc -c a.c
b.o: incl.h b.c
cc -c b.c
Командные строки выполняются по одной, каждая своим
собственным shell'ом. Чтобы указать, каким shell'ом выполнять команду, можно использовать переменную окружения SHELL. Первые один или два символа команды могут
быть следующими: -, @, -@, @-. Если присутствует @, то
подавляется вывод команды. При указании символа - make
игнорирует ошибки. Команда перед ее выполнением выводится, если только не указана опция -s, или в make-файле отсутствует вход .SILENT:, или в начале команды не
стоит знак @. Опция -n специфицирует вывод команд без
их выполнения; однако, если командная строка содержит
текст $(MAKE), то она всегда выполняется (см. MAKEFLAGS
в пункте Окружение). Если указана опция -t, то изменяется время последней модификации файлов без выполнения
каких-либо команд. К сожалению, при этом не изменяются
даты сохранения файлов в библиотеках (см. Библиотеки),
а меняется только время последней модификации библиотеки.
Команды, возвращающие ненулевой код завершения, обычно
прекращают выполнение make. Если же указана опция -i
или в make-файле присутствует вход .IGNORE:, или командная строка начинается со знака -, то ошибки игнорируются. Если указана опция -k, то прекращается обработка текущего раздела, но продолжаются действия, которые
не зависят от целевого файла этого раздела. В конце выводится сообщение о первоначальных целях, которые не
были достигнуты.
Опция -b позволяет без ошибок выполнять make-файлы, написанные для старой версии make'а. Отличие состоит в
том, что в новой версии все строки зависимостей должны
содержать (возможно пустые или задаваемые по умолчанию)
команды, связанные с ними. В предыдущей версии считалось, что неспецифицированная команда является пустой.
Сигналы прерывания и выхода вызывают уничтожение целевого файла, если только он не зависит от специального
имени .PRECIOUS.
Окружение
Команда make читает окружение. Все переменные окружения
обрабатываются как макроопределения. Все они читаются и
обрабатываются до обработки make-файла и после обработки встроенных правил; поэтому макроопределения из
make-файла перекрывают макроопределения из окружения.
Если задана опция -e, то переменные из окружения перекрывают макроопределения из make-файла. Суффиксы и связанные с ними правила из make-файла перекрывают описания суффиксов во встроенных правилах.
Переменная окружения MAKEFLAGS обрабатывается как содержащая любую из допустимых опций (кроме -f и -p),
описанных для командной строки. Далее, если такой переменной в окружении нет, то make создает ее, помещая в
нее все указанные в командной строке опции, и передает
ее всем запускаемым им командам. Таким образом,
MAKEFLAGS всегда содержит текущие опции. Эта возможность очень полезна, если возникла необходимость отладить make-файл для проекта, состоящего из подсистем,
для которых есть свои собственные make-файлы. Как уже
отмечалось выше (при использовании опции -n) команда
$(MAKE) выполняется всегда, следовательно, можно выполнить make -n рекурсивно по всему проекту, чтобы посмотреть, что было бы выполнено при отсутствии опции -n.
Это возможно, так как флаг -n помещается в MAKEFLAGS и
передается при вызове $(MAKE). Тем самым перед нами
один из способов проверить все make-файлы проекта, не
выполняя их на самом деле.
Включение файлов
Если в make-файле строка начинается с цепочки символов
include и после нее пробел или табуляция, то остаток
строки после подстановки макросов считается именем файла и этот файл будет прочтен и включен в make-файл.
Макросы
Разделы, имеющие вид
цепочка1=цепочка2
являются макроопределениями. В цепочку2 входят все символы до начала комментария или до неэкранированного перевода строки. Последующие вхождения конструкции $(цепочка1[:подцеп1=[подцеп2]]) заменяются цепочкой2. При
этом, если в цепочке2 встречаются подцепочки подцеп1,
за которыми следует пробел или табуляция, и подцеп1 начинается с точки, они заменяются на подцепочку подцеп2.
Если имя макроса состоит из одного символа и нет подстановок, то круглые скобки можно опускать. Пример использования подстановок см. в пункте Библиотеки.
Внутренние макросы
Мake поддерживает пять внутренних макросов, полезных
при написании правил построения целевых файлов:
- $*
- Этот макрос является именем файла без расширения
из текущей зависимости; вычисляется только для
подразумеваемых правил (см. Суффиксы).
- $@
- Этот макрос заменяется на полное имя целевого файла; вычисляется только для явно заданных зависимостей.
- $<
- Вычисляется только для подразумеваемых правил или
для правила .DEFAULT. Этот макрос заменяется на
имя файла, от которого по умолчанию зависит целевой файл. Так, в правиле .c.o макрос $< будет заменен на имя файла с расширением .c. Например,
правило для изготовления оптимизированного об ектного файла из файла с расширением .c может быть
таким:
.c.o:
cc -c -O $*.c
или
.c.o:
cc -c -O $<
- $?
- Макрос $? можно использовать в явных правилах
make-файла. Этот макрос заменяется на список файлов-источников, которые изменялись позднее целевого файла.
- $%
- Этот макрос применяется только тогда, когда целевой файл указан в виде библ(файл.o), что означает,
что он находится в библиотеке библ. В этом случае
$@ заменяется на библ (имя архива), а $% заменяется на настоящее имя файла, файл.o.
Четыре из этих макросов имеют альтернативную форму. Если к любому из этих макросов добавлено F, то он заменяется на соответствующее макросу имя файла без имени каталога; если же добавлено D, то макрос заменяется на
остальную часть значения первоначального макроса без
последнего символа /, то есть на имя каталога. Так,
$(@D) соответствует каталогу из $@. Если каталог не
указан, то генерируется текущий каталог (.). Только
макрос $? не имеет альтернативной формы.
Суффиксы
Некоторые файлы (например файлы, имена которых оканчиваются на .o) имеют подразумеваемые источники, например, файлы, имена которых оканчиваются на .c, .s и т.д.
Если для этих файлов не указаны команды их модификации
в make-файле, но существуют подразумеваемые источники,
то они (источники) компилируются для получения требуемых файлов. В таких случаях make применяет подразумеваемые (встроенные) правила вывода, позволяющие получить
одни файлы из других путем исследования суффиксов и определения соответствующих команд. Подразумеваемые правила вывода таковы:
.c .c~ .f .f~ .sh .sh~
.c.o .c.a .c~.o .c~.c .c~.a
.f.o .f.a .f~.o .f~.f .f~.a
.h~.h .s.o .s~.o .s~.s .s~.a .sh~.sh
.l.o .l.c .l~.o .l~.l .l~.c
.y.o .y.c .y~.o .y~.y .y~.c
Встроенные правила можно изменять. Чтобы вывести их в
виде, пригодном для изменения, нужно воспользоваться
командой
make -fp - 2>/dev/null rules
Символ ~ (тильда) используется в этих правилах для
SCCS-файлов [см. sccsfile(4)]. Так, правило .c~.o
трансформирует SCCS C-файл в об ектный файл .o. Так как
s. в SCCS-файлах является префиксом, то это несовместимо с принятым в make способом определения правила по
суффиксу. Использование тильды вызывает замену ссылки
на файл ссылкой на SCCS-файл.
Правила с одним суффиксом (например .c:) описывают, как
получить файл x из x.c (то есть второй суффикс пустой).
Это полезно для построения целевого файла только из одного исходного файла (например, для построения
shell-процедуры или простой C-программы).
Дополнительные суффиксы даются как список зависимостей
для специального имени .SUFFIXES. При этом важен порядок: первое возможное имя, для которого существуют и
файл и правило, используется как имя источника. По
умолчанию этот список выглядит так:
.SUFFIXES: .o .c .c~ .y .y~ .l .l~ .s .s~ .h~ .h .f .f~
.sh~ .sh
Команда, указанная выше для вывода списка встроенных
правил, показывает также встроенный список суффиксов.
Многократные указания .SUFFIXES: об единяют списки суффиксов; указание .SUFFIXES: с пустым списком очищает
список суффиксов.
Подразумеваемые правила
Пример с целевым файлом pgm можно записать короче:
pgm: a.o b.o
cc a.o b.o -o pgm
a.o b.o: incl.h
Это возможно, так как make использует набор внутренних
правил. Пользователь может добавить правила просто поместив их в make-файл.
Некоторые макросы используются в подразумеваемых правилах, чтобы разрешить включение опций в какую-нибудь из
получающихся команд. Например, CFLAGS, LFLAFS, и YFLAGS
используется для задания опций компиляторам cc(1),
lex(1), и yacc(1) соответственно. Для определения значений по умолчанию этих макросов можно снова порекомендовать описанный ранее метод для просмотра встроенных
правил.
Подразумеваемые правила можно изменять. Правило создания файла с суффиксом .o из файла с суффиксом .c указывается как раздел с именем .c.o: и пустым списком зависимостей. Команды shell'а, связанные с этим именем, определяют способ получения файла .o из файла .c. Любое
имя, в которое не входит символ /, и которое начинается
с точки, распознается как имя правила, а не настоящего
целевого файла.
Библиотеки
Если целевой файл или имя из списка зависимостей содержит скобки, то оно рассматривается как имя архивной
библиотеки, а цепочка символов в скобках - как имя элемента библиотеки. Так, и библ(файл.o), и
$(БИБЛ)(файл.o) обозначают библиотеку, содержащую
файл.o (предполагается, что макрос БИБЛ был предварительно определен). Выражение $(БИБЛ)(файл1.o файл2.o)
недопустимо. Правила обработки библиотечных файлов имеют вид .XX.a, где XX - суффикс, по которому будет получен элемент библиотеки. К сожалению, в текущей реализации требуется, чтобы XX отличался от суффикса элемента
библиотеки. Например, нельзя, чтобы библ(файл.o) зависел от файл.o явно. Наиболее общее использование интерфейса работы с библиотеками следующее (предполагается,
что исходными являются файлы на языке C):
lib: lib(file1.o) lib(file2.o) lib(file3.o)
@echo lib is now up-to-date
.c.a:
$(CC) -c $(CFLAGS) $<
$(AR) $(ARFLAGS) $@ $*.o
rm -f $*.o
Фактически, правило .c.a, приведенное выше, встроено в
make. Более интересный, но более ограниченный пример
конструкции, поддерживающей работу с библиотеками:
lib: lib(file1.o) lib(file2.o) lib(file3.o)
$(CC) -c $(CFLAGS) $(?:.o=.c)
$(AR) $(ARFLAGS) lib $?
rm $? @echo lib is now up-to-date
.c.a:;
Здесь используется режим подстановки расширений макросов. Список $? определен как множество имен об ектных
файлов (в библиотеке lib), чьи исходные C-файлы были
изменены. Подстановка заменяет .o на .c. (К сожалению,
нельзя еще трансформировать в .c~; однако, это может
стать возможно в будущем). Заметим также, что запрещается правило .c.a:, создающее каждый об ектный файл
один за другим. Эта конструкция значительно ускоряет
обновление библиотек, но становится весьма громоздкой,
если библиотека содержит как программы на C, так и на
ассемблере.
ФАЙЛЫ
[Mm]akefile и s.[Mm]akefile
/bin/sh
СМ. ТАКЖЕ
sccsfile(4).
cc(1), lex(1), yacc(1), cd(1), sh(1) в Справочнике
пользователя.
СЮРПРИЗЫ
Некоторые команды возвращают ненулевой код завершения и
после успешной работы; для преодоления этой трудности
используйте опцию -i.
Не допускаются файлы с символами =:@ в имени.
Команды, непосредственно выполняемые shell'ом, например
cd(1), нельзя продолжать на новую строку.
Если после слова include находится больше одного пробела, то make не сможет прочитать включаемый файл.
Макрос $(a:.o=.c~) не работает. Именованные фильтры
поддерживаются плохо.
Выражение $(LIB)(file1.o file2.o) синтаксически неверно. Нельзя построить lib(file.o) из file.o.
В текущей версии не распознается опция -u.
В текущей версии целевой файл не удаляется, если произошла ошибка. Специальное имя .PRECIOUS не работает.
Специальное имя .DEFAULT не работает.
Макросы $(@D), $(*D), $(<D) и $(%D) не вполне правильно
работают с подстановкой: подстановка производится не в
имя каталога, а в имя файла.