Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://mavr.sao.ru/hq/sts/linux/doc/infocity/GNU_Make_3-79_russian_manual.html
Дата изменения: Unknown Дата индексирования: Fri Dec 28 19:52:33 2007 Кодировка: koi8-r Поисковые слова: п п п п п п п п п п п п п п п п п |
make
Версия 3.79Версия перевода 0.1
Английский оригинал этого текста находится здесь.
Оригинал перевода находится на моей домашней страничке.
make
make
make
override
make
make
для обновления архивов
make
make
Утилита make
автоматически определяет какие части большой программы
должны быть перекомпилированы, и выполняет необходимые для этого действия.
В данном руководстве описывается программа
GNU make
, авторами которой являются Richard
Stallman и Roland McGrath.
Начиная с версии 3.76, разработку программы ведет
Paul D. Smith.
GNU make
удовлетворяет требованиям
раздела 6.2
стандарта IEEE Standard 1003.2-1992 (POSIX.2).
В приводимых примерах будут фигурировать программы на языке Си, поскольку
они широко распространены. Однако, вы можете использовать
make
с любым языком программирования для которого имеется компилятор,
работающий из командной строки.
На самом деле, область применения make
не ограничивается только
сборкой программ. Вы можете использовать ее для решения любых задач, где
одни файлы должны автоматически обновляться при изменении других файлов.
Перед тем, как использовать make
, вы должны создать так называемый
make-файл (makefile), который будет описывать зависимости между
файлами вашей
программы, и
содержать команды для обновления этих файлов. Как правило, исполняемый файл программы зависит
от объектных файлов, которые, в свою очередь, получаются в результате компиляции соответствующих
файлов с исходными текстами.
После того, как нужный make-файл создан, простой команды :
make
будет достаточно для выполнения всех необходимых перекомпиляций если какие-либо из исходных
файлов программы были изменены.
Используя информацию из make-файла, и, зная время
последней модефикации файлов, утилита make
решает, каких из файлов должны быть обновлены.
Для каждого из этих файлов будут выполнены указанные в make-файле команды.
При вызове make
, в командной строке могут быть заданы параметры,
указывающие, какие файлы следует перекомпилировать и каким образом это делать.
Смотрите раздел
Запуск make
.
Если вы - начинающий пользователь make, или просто хотите получить общее представление об этой утилите, то вам следует прочесть несколько первых разделов из каждой главы, пропуская остальные. В каждой главе первые несколько разделов посвящены введению в тему и содержат общую информацию, а последующие разделы содержат специальную и техническую информацию. Исключение составляет раздел Знакомство с make-файлами, который целиком посвящен введению в данную тему.
Если вы знакомы с другими версиями программы make
, обратите внимание
на раздел
Возможности GNU make
,
в котором описан широкий набор возможностей, имеющихся в утилите
GNU make
,
а также раздел
Несовместимость и нереализованные функции,
в котором описаны несколько вещей, которые имеются в других реализациях, но
отсутствуют в
GNU make
Для быстрого получения справки, смотрите разделы Обзор опций и Справочник, а также раздел Имена специальных целей.
Если у вас возникли проблемы с использованием GNU make
или вам кажется,
что вы обнаружили ошибку в ее работе, пожалуйста, сообщите об этом разработчикам.
Мы не может обещать невозможного, однако постараемся исправить положение.
Прежде, чем сообщать об ошибке, убедитесь в том что это - действительно ошибка. Еще раз внимательно перечитайте документацию. Если у вас что-то не получается - посмотрите, действительно ли в документации говорится о том, что это можно сделать. Если из документации непонятно - допустимы ли ваши действия или нет, сообщите нам об этом. Это означает ошибку в документации!
Прежде, чем сообщать об ошибке или пытаться исправить ее самостоятельно, попробуйте
локализовать ошибку - создать make-файл минимального размера, на котором она проявляется.
Затем, вышлите нам этот make-файл вместе с полученными результатами работы make
.
Укажите также, каких результатов вы на самом деле ожидали - это поможет нам обнаружить
возможные ошибки в документации.
Если вы действительно обнаружили проблему, пожалуйста, сообщите нам об этом по следующему адресу:
bug-make@gnu.org
Пожалуйста, укажите номер версии вашей программы make
. Вы можете
получить эту информацию, набрав в командной строке
`make --version'. Не забудьте также указать тип вашей машины и операционной
системы.
По возможности, укажите содержимое файла `config.h', который получается
в результате работы процесса конфигурирования на вашей машине.
Для работы с утилитой make
, вам понадобится так называемый
make-файл (makefile),
который будет содержать описание требуемых действий.
Как правило, make-файл описывает, каким образом нужно компилировать и компоновать
программу.
В этой главе мы обсудим простой make-файл, который описывает, как скомпилировать
и скомпоновать программу - текстовой редактор. Наш текстовой редактор будет состоять
из восьми файлов с исходными текстами на языке Си и трех заголовочных файлов.
Make-файл также может инструктировать make
как выполнять те или иные
действия, когда явно будет затребовано их выполнение (например, удалить определенные
файлы в ответ на команду "очистка").
Пример более сложного make-файла будет
приведен в разделе Пример "сложного" make-файла.
При компиляции текстового редактора, любой файл с исходным текстом, который был модефицирован, должен быть откомпилирован заново. Если был модефицирован какой-либо из заголовочных файлов, то, во избежании проблем, должны быть перекомпилированы все исходные файлы, которые включали в себя этот заголовочный файл. Каждая компиляция исходного файла породит новую версию соответствующего ему объектного файла. И, наконец, если какие-либо из исходных файлов были перекомпилированы, то все объектные файлы (как "новые", так и оставшиеся от предыдущих компиляций) должны быть заново скомпонованы для получения новой версии исполняемого файла нашего текстового редактора.
Простой make-файл состоит из "правил" (rules) следующего вида:
цель ... : пререквизит ... команда ... ...
Обычно, цель (target) представляет собой имя файла, который
генерируется в процессе
работы утилиты make
. Примером могут служить объектные и исполняемый файлы
собираемой программы.
Цель также может быть именем некоторого действия, которое нужно выполнить (например,
`clean' - очистить). Подробнее это обсуждает в разделе
Абстрактные цели ).
Пререквизит (prerequisite) - это файл, который используется как исходдные данные для порождения цели. Очень часто цель зависит сразу от нескольких файлов.
Команда - это действие, выполняемое утилитой make
.
В правиле может содержаться несколько команд - каждая на свое собственной
строке.
Важное замечание: строки, содержащие команды обязательно должны
начинаться с символа табуляции! Это - "грабли", на которые наступают многие начинающие
пользователи.
Обычно, команды находятся в правилах с пререквизитами и служат для создания файла-цели, если какой-нибудь из пререквизитов был модефицирован. Однако, правило, имеющее команды, не обязательно должно иметь пререквизиты. Например, правило с целью `clean' ("очистка"), содержащее команды удаления, может не иметь пререквизитов.
Правило (rule) описывает, когда и каким образом следует обновлять файлы,
указанные в нем в качестве цели. Для создания или обновления цели, make
исполняет
указанные в правиле команды, используя пререквизиты в качестве исходных данных.
Правило также может описывать каким образом должно выполняться некоторое действие.
Подробно это обсуждается в разделе
Составление правил.
Помимо правил, make-файл может содержать и другие конструкции, однако, простой make-файл может состоять и из одних лишь правил. Правила могут выглядеть более сложными, чем приведенный выше шаблон, однако все они более или менее соответствуют ему по структуре.
Вот пример простого make-файла, в котором описывается, что исполняемый
файл edit
зависит от восьми объектных файлов, которые, в свою очередь,
зависят от восьми соответствующих исходных файлов и трех заголовочных файлов.
В данном примере, заголовочный файл `defs.h' включается во все файлы с исходным текстом. Заголовочный файл `command.h' включается только в те исходные файлы, которые относятся к командам редактирования, а файл `buffer.h' - только в "низкоуровневые" файлы, непосредственно оперирующие буфером редактирования.
edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o
Для повышения удобочитаемости, мы разбили длинные строки на две части с помощью символа обратной косой черты, за которым следует перевод строки.
Для того, чтобы с помощью этого make-файла создать исполняемый файл `edit', наберите:
make
Для того, чтобы удалить исполняемый и объектные файлы из директории проекта, наберите:
make clean
В приведенном примере, целями, в частности, являются объектные файлы `main.o' и `kbd.o', а также исполняемый файл `edit'. К пререквизитам относятся такие файлы, как `main.c' и `defs.h'. Каждый объектный файл, фактически, является одновременно и целью и пререквизитом. Примерами команд могут служить `cc -c main.c' и `cc -c kbd.c'.
В случае, если цель является файлом, этот файл должен быть перекомпилирован или перекомпонован всякий раз, когда был изменен какой-либо из его пререквизитов. Кроме того, любые пререквизиты, которые сами генерируются автоматически, должны быть обновлены первыми. В нашем примере, исполняемый файл `edit' зависит от восьми объектных файлов; объектный файл `main.o' зависит от исходного файла `main.c' и заголовочного файла `defs.h'.
За каждой строкой, содержащей цель и пререквизиты, следует строка с командой.
Эти команды указывают, каким образом надо обновлять целевой файл.
В начале каждой строки, содержащей команду, должен находится символ табуляции.
Именно наличие символа табуляции является признаком, по которому
make
отличает строки с командами от прочих строк make-файла.
Имейте ввиду, что make
не имеет ни малейшего представления о том,
как работают эти команды. Поэтому, ответственность за то, что выполняемые команды
нужным образом обновят целевой файл, целиком ложится на вас.
Утилита make
просто исполняет указанные в правиле команды если
цель нуждается в обновлении.
Цель `clean' является не файлом, а именем действия.
Поскольку, при обычной сборке программы это действие не требуется, цель
`clean' не является пререквизитом какого-либо из правил.
Следовательно,
make
не будет "трогать" это правило, пока вы специально
об этом не попросите. Заметьте, что это правило не только не является пререквизитом,
но и само не содержит каких-либо пререквизитов. Таким образом, единственное
предназначение данного правила - выполнение указанных в нем команд.
Цели, которые являются не файлами, а именами действий называются
абстрактными целями (phony
targets).
Абстрактные цели подробно рассматриваются в разделе
Абстрактные цели.
В разделе Ошибки при выполнении команд описано,
как заставить make
игнорировать ошибки, которые могут возникнуть
при выполнении команды
rm
и любых других команд.
make
обрабатывает make-файлПо умолчанию, make
начинает свою работу с первой встреченной цели
(кроме целей, чье имя начинается с символа `.').
Эта цель будет являться главной целью по умолчанию (default goal).
Главная цель (goal) - это цель, которую стремится достичь make
в качестве
результата своей работы.
В разделе Аргументы для задания главной цели обсуждается,
каким образом можно явно задать главную цель.
В примере из предыдущего раздела, главная цель заключалась в обновлении исполняемого файла `edit', поэтому мы поместили данное правило в начало make-файла.
Таким образом, когда вы даете команду:
make
make
читает make-файл из текущей директории и начинает его обработку
с первого встреченного правила.
В нашем примере это правило обеспечивает перекомпоновку исполняемого файла
`edit'. Однако, прежде чем make
сможет полностью обработать это правило,
ей нужно обработать правила для всех файлов, от которых зависит
`edit'. В данном случае - от всех объектных файлов программы.
Каждый из этих объектных файлов обрабатывается согласно своему собственному правилу.
Эти правила говорят, что каждый файл с расширением
`.o' (объектный файл) получается в результате компиляции соответствующего ему
исходного файла.
Такая компиляция должна быть выполнена, если исходный файл или какой-либо из заголовочных
файлов, перечисленных в качестве пререквизитов, являются "более новыми", чем объектный файл,
либо объектного файла вообще не существует.
Другие правила обрабатывается потому, что их цели прямо или косвенно являются
пререквизитами для главной цели.
Если какое-либо правило никоим образом не "связано" с главной целью (то есть ни прямо,
ни косвенно не являются его пререквизитом), то это правило не обрабатывается.
Чтобы задействовать такие правила, придется явно указать make
на необходимость
их обработки (подобным, например, образом: make clean
).
Перед перекомпиляцией объектного файла, make
рассматривает необходимость
обновления его пререквизитов, в данном случае - файла с исходным текстом и заголовочных
файлов. В нашем make-файле не содержится никаких инструкций по обновлению этих файлов -
файлы с расширениями `.c' и `.h' не являются целями
каких-либо правил. Таким образом, утилита make
не предпринимает никаких
действий с этими файлами. Однако, make
могла бы автоматически обновлять
и исходные тексты, если бы они, например, генерировались с помощью программ, подобных
Bison или Yacc, и для них были бы определены соответствующие правила.
После перекомпиляции объектных файлов, которые нуждаются в этом, make
принимает решение - нужно ли перекомпоновывать файл `edit'. Это нужно
делать, если файла `edit' не существует или какой-нибудь из объектных
файлов по сравнению с ним является более "свежим". Если какой-либо из
объектных файлов только что был откомпилирован заново, то он будет "моложе", чем
файл `edit'. Соответственно, файл `edit' будет перекомпонован.
Так, если мы модефицируем файл `insert.c' и запустим make
,
этот файл будет скомпилирован заново для обновления объектного файла `insert.o', и,
затем, файл `edit' будет перекомпонован. Если мы изменим файл `command.h'
и запустим make
, то будут перекомпилированы объектные файлы
`kbd.o', `command.o' и `files.o', а затем исполняемый файл
`edit' будет скомпонован заново.
В приведенном выше примере, в правиле для `edit' нам дважды пришлось перечислять список объектных файлов программы:
edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o
Подобное дублирование чревато ошибками. При добавлении в проект нового объектного файла, можно добавить его в один список и забыть про другой. Мы можем устранить подобный риск, и, одновременно, упростить make-файл, используя переменные. Переменные (variables) позволяют, один раз определив текстовую строку, затем использовать ее многократно в нужных местах. Переменные подробно обсуждаются в разделе Использование переменных).
Обычной практикой при построении make-файлов является
использование переменной с именем
objects
, OBJECTS
, objs
,
OBJS
, obj
, или OBJ
, которая содержит список
всех объектных файлов программы.
Мы могли бы определить подобную переменную с именем objects
таким
образом:
objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o
Далее, всякий раз, когда нам нужен будет список объектных файлов, мы можем использовать значение этой переменной с помощью записи `$(objects)' (смотрите раздел Использование переменных).
Вот как будет выглядеть наш простой пример с использованием переменной для хранения списка объектных файлов:
objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit $(objects)
На самом деле, нет необходимости явного указания команд компиляции отдельно для
каждого из исходных файлов. Утилита make
сама может "догадаться" об
использовании нужных команд, поскольку у нее имеется, так называемое,
неявное правило (implicit rule)