Искусство программирования для Unix - Эрик Реймонд
Шрифт:
Интервал:
Закладка:
realclean
Отбрасывает все, что может быть заново собрано с помощью данного make-файла. Действие может быть таким же, как make distclean, но realclean следует в любом случае включать как отдельное правило для документирования происходящего. Если действие отличается, то обычно оно отличается отбрасыванием файлов, которые являются производными, но (по какой-либо причине), так или иначе поставляются с исходными кодами проекта.
install
Инсталляция исполняемых файлов проекта и документации в системные каталоги таким образом, чтобы они были доступны пользователям (обычно данная операция требует полномочий администратора). Инициализация или обновление баз данных или библиотек, которые необходимы исполняемым файлам для работы.
uninstall
Удаление файлов, установленных в системные каталоги командой make install (обычно данная операция требует полномочий администратора). Эта операция должна быть полностью противоположной make install. Это правило означает подчинение соглашениям, которые ищут опытные пользователи Unix, так как для них они являются подтверждением продуманной конструкции. Напротив, его отсутствие является в лучшем случае небрежностью и (например, когда в ходе инсталляции создаются большие файлы базы данных) может рассматриваться как некомпетентность и невнимательность.
Работающие примеры всех стандартных целей доступны для изучения в make-файле программы fetchmail. Их изучение позволит понять модель и полнее изучить структуру пакета fetchmail. Одним из преимуществ использования данных стандартных правил является то, что они формируют полную схему проекта.
Однако для разработчика нет необходимости ограничивать себя данными правилами. Однажды научившись использовать make, разработчик обнаруживает, что он все чаще использует механизм make-файлов для автоматизации небольших задач, которые зависят от состояния файлов проекта. Make-файл проекта — удобная центральная точка для организации данных задач. Его использование делает их легкодоступными для изучения и позволяет избежать загромождения рабочей области проекта небольшими случайными сценариями.
15.4.4. Генерация make-файлов
Одним из неочевидных преимуществ Unix make по сравнению с базами данных зависимостей, встроенных в многие IDE-среды, является то, что make-файлы представляют собой простые текстовые файлы, т.е. файлы, которые могут создаваться программами.
В середине 1980-х годов в дистрибутивах крупных Unix-программ были достаточно распространены сложные специальные shell-сценарии, которые исследовали окружение и использовали собранную информацию для создания нестандартных make-файлов. Такие специальные конфигураторы достигали абсурдных размеров. Автор данной книги однажды написал такой конфигуратор, состоящий из 3000 строк shell-кода, почти вдвое больше любого отдельного модуля программы, для которой он был предназначен, и это не было необычным.
Однажды было решено положить этому конец, и многие представители сообщества настроились на написание инструментов, которые автоматизировали бы часть или весь процесс сопровождения make-файлов. Данные инструментальные средства обычно были призваны разрешить две проблемы.
Одной из проблем была переносимость на другие платформы. Генераторы make-файлов в большинстве случаев создаются для работы на множестве различных аппаратных платформ и вариантов Unix. Как правило, они пытаются определить параметры локальной системы (включая все от размера машинного слова до инструментов, языков служебных библиотек и даже имеющихся в системе программ форматирования документов). Затем генераторы пытаются использовать полученные сведения для написания make-файлов, которые используют средства локальной системы и компенсируют ее индивидуальные особенности.
Другой проблемой является вывод зависимостей. Существует возможность получить множество сведений о зависимостях в семействе файлов исходного C-кода путем анализа самих файлов (особенно их директив #include). Многие генераторы make-файлов выполняют данные действия для автоматического создания make-зависимостей.
Способы достижения данных целей у всех генераторов make-файлов несколько различаются. Вероятно, использовалось не менее десяти генераторов, но большинство из них оказались неадекватными или слишком сложными в управлении или имели оба этих недостатка. Только несколько конфигураторов до сих пор активно используются. Ниже рассматриваются основные представители этого семейства программ. Все они доступны в Internet в виде программ с открытым исходным кодом.
15.4.4.1. makedepend
Несколько небольших инструментов решают исключительно часть описанной выше проблемы, связанную с автоматизацией правил. Утилита makedepend, распространяемая наряду с системой X Window разработки MIT, является самым быстрым и наиболее полезным из таких инструментов и предустанавливается на все современные Unix-системы, включая все дистрибутивы Linux.
makedepend принимает коллекцию исходных кодов С и генерирует зависимости для соответствующих .о-файлов из их директив #include. Их можно добавлять непосредственно в make-файл, и makedepend фактически предназначена именно для этого.
makedepend бесполезна для проектов, написанных не на С. Утилита не пытается решать несколько частей проблемы создания make-файлов. Однако то, что она делает, она делает особенно хорошо.
Утилита makedepend полностью документирована на соответствующей странице руководства. Команда man makedepend, введенная в терминальном окне, быстро предоставит сведения, необходимые для запуска данной утилиты.
15.4.4.2. Imake
Утилита Imake была написана в попытке автоматизировать создание make-файлов для системы X Window. Она надстраивается на makedepend для решения как проблемы вывода зависимостей, так и проблемы переносимости.
Imake-система эффективно заменяет традиционные make-файлы Imake-файлами, написанными в более компактной и мощной форме, которая (эффективно) компилируется в make-файлы. В процессе компиляции используется файл правил, который считается специфическим для системы и включает в себя множество сведений о локальной среде.
Imake хорошо подходит для разрешения трудностей переносимости и конфигурации, специфических для X, и используется во всех проектах, которые являются частью дистрибутива X Window. Однако за пределами X-сообщества данная утилита не приобрела большой популярности. Она трудна для изучения, использования и расширения, а кроме того, генерирует make-файлы огромных размеров и сложности.
Imake-инструменты доступны на любой Unix-системе, поддерживающей X, включая Linux. Существует один "героический" проект [16], цель которого заключается в "прояснении тайн" Imake для не X-программистов. Вопросы, освещаемые данным проектом, стоит изучить всем, кто собирается заниматься X-программированием.
15.4.4.3. autoconf
Утилита autoconf была написана программистами, которые изучили и отклонили подход Imake. Утилита autoconf генерирует для каждого проекта shell-сценарии configure, которые подобны старомодным специальным конфигураторам, configure-сценарии способны генерировать make-файлы (в том числе).
Утилита autoconf направлена на разрешение проблемы переносимости и вообще не выполняет встроенного вывода зависимостей. Несмотря на то, что данная программа, вероятно, такая же сложная, как Imake, она является гораздо более гибкой и проще расширяется. Вместо использования базы данных правил в системе, утилита генерирует shell-код configure, который осматривает систему, определяя необходимые параметры.
Каждый configure-сценарий создается на основе уникального для проекта шаблона configure.in, который должен написать разработчик. Однажды сгенерированный сценарий configure является самодостаточным и способен конфигурировать данный проект на системах, которые не содержат саму утилиту autoconf(1).
Подход к созданию make-файлов, принятый для autoconf, подобен подходу Imake в том, что разработчик начинает с написания шаблона make-файла для своего проекта. Однако файлы Makefile.in, созданные autoconf, по существу являются просто make-файлами с метками-заполнителями для простой текстовой замены; не существует второй формы записи, которую требуется изучать. Если требуется осуществить вывод зависимостей, то необходимо предпринять явные шаги для вызова makedepend(1) или подобного инструмента, или использовать утилиту automake(1).