Первоисточник http://linux.oreillynet.com/pub/a/linux/2002/01/31/make_intro.html
by Jennifer Vesperman
01/31/2002
Make изначально появилась как система для building компилированного кода. Но, как и любой хороший инструмент, система нашла широкое применение и в других областях. Ее использование оправдано всякий раз, когда изменение в одном файле требует изменений (или действий) в других файлах или каталогах.
Make полезна для системных администраторов и разработчиков. Хотя статья, прежде всего, ориентирована на make в контексте инструмента компиляции, все перечисленное может эффективно использоваться для инсталляции программ или изменений в конфигурации системы.
Make требует наличия конфигурационного файла. После создания такого файла для вашего проекта достаточно ввести "make", и "волшебным" образом произойдет перекомпиляция обновленных и зависимых от них файлов.
"Стандартное" имя такого файла - Makefile
.
Обратите внимание на регистр первой буквы, это "отличительное" свойство для
специальных файлов, типа README
и других.
Когда make введено без параметров, GNU Make ищет конфигурационные файлы с именами
GNUmakefile
, Makefile
и makefile
в
текущем каталоге. Если вы используете файл с другим именем, следует
вызывать Make как make -f filename
.
Следующие примеры makefile достаточно полно демонстрирует возможности make
и при этом не перегружены. По умолчанию выполняется список команд.
Обратите внимание на вызов с ключом make -s
.
|
Примеры из этой статьи написаны для C и генерируют обычный target файл. В общем случае, Make может генерировать любой целевой файл, используя любые shell команды и обрабатывая любые source файлы. Make в большей степени приспособлен к работе с такими языками, в которых компилятор не пытается самостоятельно решать зависимости.
Опытные пользователи Make заметят избыточность в makefile примера. Make заранее
знает, как компилировать некоторые типы файлов, и правила для таких файлов могут
не описываться (так называемые неявные правила [implicit rules
]).
В демонстрационных целях такие правила указаны явно.
|
Make правило представляет собой:
|
Атрибуты генерируемого файла [target] просматриваются на предмет "up to date" и, если файл-предпосылка [prerequisites] "более свежий" или target не существует, выполняется команда.
Make работает с использованием рекурсивного отката, начиная с target первого
правила. В нашем примере это sample
. Make проверяет prerequisites для sample
(в нашем случае main.o и example.o) чтобы увидеть, имеются ли правила для них.
Если такие правила есть, рекурсивно проверяются правила для этих правил...
Make "раскручивает" вниз цепочку рекурсий пока не достигает "дна", то есть находит target, которая не имеет prerequisites или чьи prerequisites не имеют rules. Как только это происходит, начинается откат с копированием цепочки рекурсий и выполнением команд по необходимости. Иначе, создается цепочка рекурсий для каждой prerequisite, с которой сталкивается make (и для которой существует rule).
Как только все необходимые prerequisite rules выполнены, все возвращается к
правилу sample
. Если целевой файл не существует или старее, чем
любой из его файлов-предпосылок (уже после того, как рекурсивно протестирована
вся цепочка правил), выполняется команда и генерируется новый sample
.
В случае с makefile из примера:
sample
.sample
's prerequisites правила.
Есть и не одно.main.o
.main.o
's prerequisites правила. Их нет.main.o
"современным". Если нет,
выполняется команда для генерирования main.o
.example.o
.example.o
's prerequisites правила.
Их нет.example.o
"современным".
Если нет, выполняется команда для генерирования example.o
.sample
's.sample
"современным".
Если нет, выполняется команда для его модификации.Make может выполнять prerequisites в любом порядке. Принципиально только одно - рекурсивный откат от первой target (или от target, переданной команде make в виде параметра) и проверка только тех правил, которые попали в цепочку предпосылок.
Make обрывает компиляцию при возникновении ошибки. Такое поведение очень полезно.
Оно позволяет исправлять обнаруженные компилятором проблемы в цикле
"compile-and-test" без лишних повторов. Ключ -i
сообщает make
необходимость игнорировать ошибки.
В мире software development очень удобно иметь сценарий, который удаляет код старой компиляции и дает возможность пере собрать программу полностью. Кроме того, не будет лишним иметь сценарий для инсталляции. Make позволяет included подобные сценарии в makefile через phony targets. Фальшивые targets могут иметь prerequisites либо сами могут быть prerequisites.
Специальное правило .PHONY
сообщает Make, что ее targets не
являются файлами. Таким способом предотвращаются возможные конфликты с
одноименными файлами, что позволяет "не думать о мелочах".
Если phony target включена как prerequisite для другой target, она будет выполняться при каждом вызове основной. Иначе, для phony target понятия "never up-to-date" не существует.
Чтобы запустить phony target из командной строки, введите Make с именем
phony target, например: make clean
.
|
По мере разрастания проекта добавляются новые и новые файлы. Если требуется во многих местах перечислять файлы целыми списками и при этом не волноваться, что где-то что-то было пропущено, используйте variable. Всего одна переменная может расширяться в целый список и с полной гарантией "донесет" изменения во все места.
Синтаксис для объявления и установки makefile variable следующий:
varname = variable contents
.
Для вызова переменной используется $(varname)
.
|
Имеется несколько мелочей, которые отличают "просто пригодный к использованию" и "профессионально сделанный" makefile. Следующие строки - дополнение к сказанному.
|
Используйте variable для объявления компилятора. Это позволит быстро и безошибочно переделать makefile под другой компилятор.
При вызове Make без rule parameter, выполняется первое встретившееся
правило. Чтобы "облегчить жизнь" тех, кто будет просматривать созданный вами
makefile, принято помечать первое rule. Имя all
- "общепринятый
стандарт" для первого правила.
"Автоматическая" переменная $@
означает "имя target",
automatic variable $+
означает "все prerequisites разделенные
пробелом". Такие переменные предопределены в Make.
Подстановки в правилах используется для сообщения Make как обращаться
с именами файлов при конвертации prerequisite в target.
Символ %
в pattern буквально означает "один или несколько символов",
а применительно к строке, содержащей prerequisite и target - использовать одно имя
с разными суффиксами. Такой специфический pattern сообщает make конвертировать
*.c
файлы в *.o
файлы не меняя имен.
Использование "неявных правил" [implicit rules]. Make имеет встроенные инструкции
[built-in patterns] для конвертирования *.h
файлов в зависимые
*.o
файлы. Такие правила included для объявления prerequisites
для уместных *.o
файлов.
Статья описывает GNU Make. В некоторых Unix системах используются другие версии Make, что предполагает возможные незначительные отличия.
Make имеет множество features, о которых здесь не упоминалось, и которые могут быть очень полезны в отдельных случаях (например, когда зависимости [dependent] файлов могут изменяться). Экспериментируйте и вносите свои интересные features для работы с makefiles.
man make
info make
Jennifer Vesperman likes to think she was born with a silicon wafer attached to her spinal column, but she can't get her parents to admit it. She contributes to open source, mostly as a user and an advocate. Jenn is the current coordinator for Linuxchix.org.
Перевод: Vladimir Kholmanov