НАЗВАНИЕ
make - поддержка, обновление и восстановление групп
программ
СИНТАКСИС
make [-f make-файл] [-p] [-i] [-k] [-s] [-r] [-n] [-b] [-e] [-u] [-t] [ [целевой_файл ...]
ОПИСАНИЕ
Утилита make позволяет поддерживать, изменять и регенерировать группы программ. Ниже приведено краткое описание всех опций и некоторых специальных имен:
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 поддерживает пять внутренних макросов, полезных
при написании правил построения целевых файлов:
.c.o: cc -c -O $*.cили
.c.o: cc -c -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) не вполне правильно работают с подстановкой: подстановка производится не в имя каталога, а в имя файла.