О блоге

Все новые материалы размещаются на Блогосайте alv.me. Старые - в процессе переноса.

16.08.2008

Gentoo: устройство и использование системы портежей

2002-2003 гг

Вступление: эдостаточно древние заметки о портежах; размещаются на предмет коррекции и дополнения. - 2006.03.07

Что такое портежи

Система портежей (Portage) - то, что придает Gentoo Linux своеобразие, обеспечивает гибкость и легкость его использования. Она создавалась (и это явным образом признается авторами) под воздействием портов FreeBSD. Однако идет значительно дальше, пронизывая весь дистрибутив с самого его основания.

Если в двух словах, портежи - система автоматизации установки пакетов из исходных текстов. Посредством соответствующих команд она обеспечивает:

  • получение архивов исходных текстов (тарбаллов) устанавливаемой программы из Сети (с мастер-сайтов разработчиков, их официальных зеркал или серверов Gentoo-проекта);
  • проверку для устанавливаемой программы отношений зависимости от других пакетов или использования оных (см. ниже);
  • скачивание пакетов, от которых зависит устанавливаемая программа, или пакетов, которые она использует;
  • проверку контрольных сумм всех скачанных архивов;
  • декомпрессию и развертывание тарбаллов в специально предназначенный для этого временный каталог;
  • конфигурирование исходных текстов для приведения их в соответствие с реалиями данной системы и, если нужно, наложение патчей, необходимых для сборки и работы именно в Gentoo; патчи эти также получаются из Сети - с сервера проекта;
  • компиляцию как собираемой программы, так и всех пакетов, от которых она зависит или которые использует;
  • установку полученных в результате компиляции бинарных файлов в специальный промежуточный каталог;
  • размещение бинарников в соответствующих ветвях текущей файловой системы, что имеет своим следствием получение работоспособной инсталлированной программы;
  • последнее действие может заменяться (или дополняться) сборкой из временно инсталлированных откомпилированных файлов бинарного пакета в формате *.tbz2 (tar-архива, сжатого компрессором bzip2), пригодного для автономной установки (в т.ч. и на другой машине);
  • регистрацию установленной программы (со всеми пакетами, от которых она зависит или которые использует) в специальной базе данных;
  • переустановку и (или) обновление любого установленного пакета;
  • чистое удаление установленных пакетов, в том числе, при желании - вместе с пакетами, от которых те зависят или которые используют.

Терминологическое замечание: здесь и далее различаются "жесткие" и "мягкие" зависимостимежду пакетами. Жесткие зависимости - это когда пакет А для своей установки и функционирования требует обязательного наличия в системе уже установленного пакета Б. Так, интегрированную среду KDE невозможно установить (и запустить), если предварительно не была установлена библиотека Qt, на которой она основана. Или еще проще: ни одно приложение графического режима не может быть установлено без оконной системы Икс (примеры таких зависимостей можно многократно умножить.

Жесткие зависимости контролируются системой портежей автоматически. Так, попытка установить любой оконный менеджер приведет либо к предварительному скачиванию и установки Иксов, либо к сообщению об ошибке. Впрочем, при необходимости контроль зависимостей может быть отключен - если пользователь знает, что делает (и имеет к тому веские причины).

Мягкие зависимости возникают, когда программа А при наличии в системе программы Б может обрести некие дополнительные функции (хотя сама по себе способна функционировать и без этого). Пример - консольные программы типа links или Midnight Commander: при наличии в системе службы консольной мыши gmp в них возможно использование этого устройства как указательно-позиционирующего (подобно принятому в Windows). Хотя и без gpm они вполне способны успешно выполнять свои задачи (на мой взгляд, так более успешно, но это - совсем другая история).

Для управления мягкими зависимостями используется переменная USE, значения которой могут определяться различными способами. Во-первых, некий предопределенный умолчальный набор отношений использования задается глобально при установке системы портежей. Во-вторых, каждый вновь устанавливаемый пакет, который может быть использован другими пакетами для расширения их функциональности, автоматически добавляет в сумму значений переменной USE соответствующие мягкие зависимости. В третьих, мягкие зависимости могут быть явным образом включены или отключены в соответствующем конфигурационном файле. И наконец, в четвертых: переменную USE, как и любую другую, можно определить в командной строке для выполнения текущей команды установки или как переменную окружения для всего сеанса работы.

Таким образом, разделяя жесткие и мягкие зависимости, система портежей сочетает простоту и гибкость использования. То есть она полностью снимает с пользователя заботу о выполнении жестких зависимостей, позволяя в широких пределах настраивать использование (или не-использование) пакетами дополнительных возможностей, обусловленных зависимостями мягкими.

Действительно, пользователь пакетного дистрибутива вынужден в этом отношении целиком полагаться на волю сборщиков соответствующего пакета. Вспомним, как часто установке Midnight Commander из прекомпилированного пакета влечет за собой установку не только Иксов, но и Gtk с GNOME - не потому, что mc жить без них не может, а лишь потому, что так показалось нужным разработчикам дистрибутива. Если же устанавливать в таком дистрибутиве пакеты вручную - потребуется каждый раз указывать в командной строке ./configure опции with/without или enable/disable. Даже в системе портов FreeBSD соответствующие опции отданы на откуп майнтайнеру порта - если требуются нестандартные настройки, процесс портирования приходится разбивать на этапы с ручным конфигурированием.

К слову сказать, это - не единственное отличие портежей Gentoo от портов FreeBSD. В последних предусматривается самостоятельный порт не просто для каждой программы, но и (почти) для каждой ее версии. Так, для примера, для установки текущей версии редактора joe используется одноименный порт, порт же для разрабатываемой версии - самостоятелен, и носит имя joe-devel. В едином же портеже Gentoo мирно уживается несколько версий одного пакета. То есть в каждый момент времени из текущего среза дерева портежей можно установить не только последнюю (или последнюю стабильную) версию данного пакета, но и несколько более ранних (или, напротив, разрабатываемых) версий. Зачем это нужно - думаю, пояснений не требуется: далеко не всегда новая версия, какие бы фронтирные фичи она ни поддерживала, будет столь же стабильна, как проверенная временем.

И, чтобы более к этому вопросу не возвращаться, отметим главное отличие портежей Gentoo от портов FreeBSD: если первые предназначены для установки дополнительных пакетов (то есть выходящих за пределы базовой системы, т.н. Distributions), то весь дистрибутив Gentoo построен на системе портежей. И базовые компоненты Gentoo (включая исходные тексты ядра, компилятор gcc, библиотеку glibc, да и саму систему портежей) устанавливаются, регистрируются, пересобираются и обновляются точно по тому же механизму, что и любые опциональные приложения.

Систему портежей можно разделить на три составные части: собственно дерево портежей, программы для работы с портежами и базу данных портежей.

Дерево портежей

Дерево портежей размещается в каталоге /usr/portage. Он содержит множество подкаталогов - app-admin, app-arch, и т.д. Назначение большинства, как правило, понятно из названия: они объединяют группы пакетов по назначению. Группы эти именуются категориями. В каждой из категорий - подкаталоги более глубокого уровня вложенности, отвечающие уже отдельным пакетам. Так, в каталоге app-editors обнаруживаются каталоги для редакторов emacs, vim, joe и т.д., в каталоге app-shells - подкаталоги для оболочек zsh, tcsh и прочих.

Каталог каждого пакета содержит в обязательном порядке подкаталог files, файл ChangeLog и один или несколько файлов вида имя_пакета-номер_версии.ebuild - как уже говорилось, в составе единого портежа может сосуществовать (и часто сосуществует) несколько версий портированного пакета.

Ясно, что ebuild-файл представляет собой главный компонент портежа - тот самый сценарий, по которому осуществляется установка пакета. Он содержит:

  • краткое описание программы (поле DESCRIPTION);
  • URL домашней страницы проекта;
  • один или несколько адресов для получения исходников пакета;
  • ключевые слова, указывающие на архитектуры, для которых пакет реализован;
  • тип лицензии, под которой пакет распространяется разработчиком (например, GPL-2 или BSD);
  • список пакетов, связанных с данным отношениями зависимости или использования.

Жесткие зависимости описываются следующим образом:

DEPEND=">=категория/пакет-версия"

где символ >= показывает, что для установки данного пакета требуется пакет имя_рек версии, равной или более поздней, чем указано. Мягкие же зависимости описываются несколько иначе:

DEPEND="keyword? ( >=категория/пакет-версия )"

где ключевое слово (keyword) совпадает с соответствующим флагом переменной USE, а в скобках указывается пакет (вместе с его категорией), который отвечает за реализацию этого флага.

Заметим, что поле DEPEND описывает пакеты, необходимые (или желательные) для компиляции данной программы. В ebuild-файлах некоторых пакетов можно увидеть также и поле RDEPEND - в нем приведены пакеты, необходимые для запуска программы (т.н. runtime-зависимости). Формат его аналогичен таковому поля DEPEND. Если поле RDEPEND не определено, это значит, что runtime-зависимости совпадают с отношениями зависимости и использования, устанавливаемыми для компиляции пакета.

Перечисленные выше поля представляют собой переменные ebuild-скрипта. После этих сведений следует собственно сценарий установки - строки, описывающие последовательность действий по конфигурированию, компиляции и установке пакета. Они описываются в терминах функций ebuild-скрипта, например:

  • функция src_unpack отвечает за распаковку архива исходников,
  • функция src_compile - за начальное конфигурирование и компиляцию исходных текстов,
  • функция src_install - за помещение скомпилированных файлов во временный инсталляционный каталог,

и так далее. С форматом ebuild-файла, полным списком его переменных, функций и их описанием можно ознакомиться на странице

$ man 5 ebuild

В подкаталоге files содержатся т.н. дайджест-файлы, которые имеют вид digest-имя_пакета-номер_версии. В каждом таком файле (очевидно, что число их совпадает с количеством ebuild-файлов в родительском каталоге) приведены имя и размер архива исходников для конкретной версии данного пакета, а также - контрольная сумма MD5: именно посредством сверки с дайджест-файлом осуществляется верификация скачанного архива перед его распаковкой.

Наконец, файл ChangeLog, как легко догадаться по его названию, содержит последовательное, от версии к версии, описание изменений, внесенных в пакет разработчиками и майнтайнерами.

Кроме подкаталогов, соответствующих категориям пакетов, в дереве портежей /usr/portage имеется также несколько подкаталогов специального назначения. К ним относятся:

  • distfiles, в который помещаются скачанные из Сети архивы исходников портированных пакетов;
  • eclass, содержащий т.н. eclass-файлы, описывающие общие условия сборки серии родственных пакетов;
  • licenses, в котором собраны тексты всех лицензий (числом более полутора сотен), на условиях которых распространяются портированные программы их авторами;
  • metadata, файлы которого содержат сведения, аналогичные вводной части ebuild-файла (описание зависимостей, URL мастер-сайта и источника архива, краткое описание, и т.д.);
  • profiles, содержащий т.н. профильные файлы системы портежей, о которых речь пойдет в одном из следующих разделов;
  • scripts, содержащий сценарии для автоматизации некоторых действий по установке портежей (например, скрипт bootstrap.sh, обеспечивающий пересборку базовых компонентов системы, и еще несколько).

Кроме всего прочего, в дереве портежей может обнаружиться и каталог packages. Он предназначен для размещения автономных бинарных пакетов и создается автоматически при сборке первого из них. А внутри него - подкаталог All, куда, собственно, и помещается собранный бинарный пакет (вида *.tbz2), и подкаталоги для отдельных категорий. В последних содержатся символические ссылки на файлы пакетов из подкаталога All.

И еще: в каталоге /usr/portage содержатся два скелетных файла, призванных облегчить построение портежей - skel.ebuild и skel.ChangeLog. Нетрудно догадаться, что по образу и подобию первого создается ebuild-файл портируемого пакета, а второго - файл изменений.

Программы для работы с портежами

Для работы с деревом портежей предназначены две основные программы - /usr/bin/emerge и /usr/sbin/ebuild. Обе они выполняют описанный в первом разделе комплекс действий по управлению портированными пакетами, однако реализуются эти действия по разному.

Программа emerge определяется как высокоуровневый интерфейс командной строки для управления портежами. Это сценарий на языке Python, интерпретатор которого запускается модификатором окружения (/usr/bin/env). Устройство его довольно сложное, но доступное для просмотра (в текстовом редакторе или командой less).

Программа emerge - универсальна, предоставляя доступ ко всем возможностям системы портежей, от определения зависимостей единичного пакета до его окончательной инсталляции в системе или сборки автономного бинарника. Это достигается с помощью указания многочисленных опций (options), действий (actions) и путей (ways) программы, о которых речь впереди (и которые описаны на странице man 1 emerge). Пока же отмечу только, что программа merge не требует указания на конкретный ebuild-файл. Данная в форме

$ emerge /usr/portage/категория/пакет

она автоматически выберет последнюю (или последнюю стабильную) версию указанного пакета, автоматически определит для него все отношения зависимости и использования, скачает и установит недостающие пакеты, если таковые потребуются, после чего скомпилирует и установит собственно заказанную программу.

Программа ebuild (скрипт на языке Python, интерпретируемый последним непосредственно) определяется как низкоуровневый интерфейс к системе портежей. Она, напротив, предназначена для работы с единичным ebuild-файлом, отвечающим конкретной версии данного пакета, каковой и требуется ей в качестве аргумента. Она также способна выполнить как установку пакета, так и сборку автономного бинарника. Определяются ею и зависимости, как жесткие, так и мягкие. Однако, в отличие от emerge, ebuild не разрешает нарушения зависимостей автоматически, а просто выдает список недостающих в системе компонентов (естественно, с прекращением своей работы). Это, казалось бы, делает ее менее универсальной. Однако она более гибка в управлении и потому в ряде случаев использование программы ebuild оказывается более удобным. Кроме того, по сравнению с программой emerge, ebuild предоставляет дополнительную возможность - сборку автономных бинарных пакетов в формате rpm, которые могут быть установлены в дистрибутиве Red Hat и других дистрибутивах, таковой использующих.

Программа ebuild будет рассмотрена в одном из следующих разделов. Пока же отметим, что весьма подробные сведения о ней можно почерпнуть со станицы man (1) ebuild, которую не следует путать со станицей man (5) ebuild, описывающей устройство ebuild-скрипта.

Кроме универсальных программ управления портежами, в эту систему входит еще несколько специализированных утилит, имеющих местонахождением каталог /usr/lib/portage/bin (впрочем, и программы emerge и ebuild физически находятся здесь - указанные выше пути ведут к символическим на них ссылкам). Они весьма многочисленны, плохо документированы (man-страниц для них, как правило, нет, в лучшем случае информацию можно почерпнуть, запустив такую утилиту с опцией --help, да и то не всегда). Главное же - у меня пока ни разу не возникла необходимость обращаться к ним. И потому далее о этих утилитах речи не будет. Хотя за любую информацию по сему предмету буду признателен.

База данных портежей

База данных установленных пакетов, создаваемая системой портежей, расположена в каталоге /var/db/pkg. Он устроен по образу и подобию каталога /usr/portage, включая серию подкаталогов, соответствующих категориям пакетов - app-editors, app-shells и т.д. Однако внутри каждой категории можно обнаружить только подкаталоги, содержащие ранее установленные пакеты и одноименные их ebuild-файлам, например, /var/db/pkg/app-editors/joe-2.9.8_pre1 и так далее.

В каждом таком каталоге обнаруживается ebuild-файл, идентичный таковому из каталога /usr/portage, и серия файлов с информацией о пакете:

  • CATEGORY, где приведена категория, к которой отнесен пакет (например, для примера с редактором joe это будет app-editors);
  • CHOST, CFLAGS и CXXFLAGS, указывающие наименование целевой машины, флаги для компиляторов C и C++, соответственно;
  • USE, в котором перечислены значения одноименной переменной, при которых пакет был скомпилирован;
  • LICENSE, указывающий тип лицензии, на условиях которой пакет распространяется;
  • CONTENTS, содержащий список всех файлов пакета, инкорпорированных в текущую файловую систему, и каталогов, куда они были помещены, и COUNTER, в котором приведено общее количество этих файлов;
  • RDEPEND, описывающий зависимости, необходимые для запуска установленного пакета (runtime-зависимости).

Кроме этого, к системе портежей имеет отношение еще несколько подкаталогов каталога /var. Так, важным представляется каталог /var/tmp/portage/ - в него помещаются для временного хранения промежуточные продукты жизнедеятельности системы портежей, используемые как для инкорпорации скомпилированного пакета в текущую файловую систему, так и для построения автономного бинарного пакета, пригодного для самостоятельной установки вне системы портежей. По завершении портирования этот каталог автоматически очищается (по умолчанию, это положение можно изменить), и в нем сохраняются только log-файлы, документирующие выполненный процесс.

И, наконец, в каталоге /var/cache/edb/dep, разбитом на подкаталоги по категориям пакетов, также фиксируется информация об отношениях зависимости и отношениях использования пакетов.

Установка портежей

В прошлой заметке говорилось, что дерево портежей можно обнаружить в каталоге /usr/portage. Однако не факт, что оно появится там само собой - возможно, пользователю придется озаботиться этим самому. То есть - если дерево портежей не было установлено при инсталляции Gentoo, следует его

  • скачать с сервера проекта Gentoo или его зеркал,
  • распаковать и развернуть архив,
  • настроить,
  • и время от времени обновлять.

Архив дерева портежей (тарбалл вида portage-год_месяц_число.tar.bz2) имеет своим местопребыванием каталог snapshots на любом из Gentoo-серверов. И такой тарбалл там не один - обновление их происходит чуть ли не ежедневно, и обычно доступны три последние версии (а на некоторых зеркалах хранятся тарбаллы и за более длительный срок). Скачиваем один из тарбаллов (не последний ли по времени?) посредством, например, ftp-клиента wget из штатного комплекта Gentoo:

$ wget http://[URL]/snapshots/portage-20021217.tar.bz2

Далее тарбалл разворачивается в каталоге /usr:

$ tar xjpvf portage-*.tar.bz2

в результате чего и получаем то самое дерево портежей, о котором говорилось в прошлой заметке.

Дерево портежей - живой и развивающийся организм. Как уже говорилось, новый снапшот появляется на сервере Gentoo чуть ли не ежедневно. Изменения в нем заключаются во включении поддержки а) новых пакетов, б) новых версий ранее портированных программ, в) новых реализаций прежних версий ранее портированных программ, и, наконец, г) просто в исправлении ошибок. Так что есть смысл время от времени дерево портежей обновлять - если уж не ежедневно, то по крайней мере по выходе свежих вариантов критически важного софта.

Для автоматического обновления дерева портежей в этой системе предусмотрен механизм Rsync, выполняющий сию процедуру одной командой:

$ emerge sync

Она скачивает последний по времени снапшот дерева и разворачивает архив в каталоге /usr/portage. Очевидно, что для этого предыдущий вариант дерева портежей должен быть уже установлен. Если использование Rsync почему-либо невозможно (так, судя по документации, этот механизм не работает из-за файрвола) - обновить дерево портежей можно вручную, тем же способом, как оно устанавливалось.

Как уже говорилось, в дереве портежей существует подкаталог distfiles, специально предназначенный для хранения исходных текстов портированных программ. Однако сразу же по установке древа мы его не тут не увидим. Откуда же он берется и каким образом он заполняется?

Каталог /usr/portage/distfiles возникает автоматически при установке первого же портежа. И столь же автоматически в нем появляется исходник устанавливаемого пакета и всех иных пакетов, связанных с ним отношениями зависимости и использования. При одном непременном условии - наличии подключения к Сети в момент установки портежа. Все это понятно из концепции портежей, но вызывает болезненный в постсоветских условиях вопрос - что делать, если подключения к Сети на целевой машине нет.

Подчеркну еще раз - для использования портежей достаточно иметь возможность физического выхода в Сеть вообще (не обязательно с данной машины). То есть можно скачать исходники где угодно, переместить их на любом носителе (CD-R/RW, Zip, съемный диск), а потом скопировать их в каталог /usr/portage/distfiles, созданный командой mkdir, вручную. С точки зрения системы портежей, это ничем не будет отличаться от автоматического получения нужных файлов с помощью соответствующих опций команд emerge или ebuild.

Откуда брать исходники? Да откуда угодно, хоть с мастер-сайтов разработчиков каждой требуемой программы. Но наиболее удобное место - каталог distfiles на серверах проекта Gentoo (или каталог gentoo-src, содержание их идентично). Здесь имеют место быть архивы всех версий каждой из портированных в Gentoo программ. И отсюда их можно скачать оптом и в розницу. Подчеркну - это именно копии авторских исходников, ничем не отличающиеся от тех, которые можно забрать с мастер-сайта разработчика (и практически всегда если не последние, то предпоследние их версии). Ибо все Gentoo-специфичные дополнения, призванные обеспечить корректную установку и работу портированной программы, оформляются в виде патчей.

В отличие от системы портов FreeBSD, Gentoo-специфичные патчи в портежах не входят в состав конкретного порта - их следует искать в том же каталоге distfiles, что и оригинальные исходники. Как правило, попытка установки портежа без патчей вызовет сообщение об ошибке. Хотя отсутствие патча и не помешает собрать пакет вручную (с помощью стандартных ./configure, make, make install etc.), но при этом во многом теряется смысл всей системы.

Как определить, необходимо ли скачать патчи для установки конкретного пакета, и если да - то какие? Универсальный способ для этого будет описан в разделе о командах работы с портежами. Пока же напомню систему именования ebuild-файлов: имя_пакета-номер_версии-[номер_ревизии]. Очевидно, что имя пакета и номер его версии наследуются от именования его разработчиком. И ebuild-файл, номера ревизии не имеющий, скорее всего, дополнительных патчей не потребует (хотя из этого правила есть немало исключений). А вот номера ревизий - это уже дело рук разработчиков Gentoo. И различные ревизии одной и той же версии пакета отличаются друг от друга именно Gentoo-специфичными патчами - ведь сам исходник данной версии, как мы помним, абсолютно идентичен авторскому. То есть установка любого ebuild-файла, имеющего в составе имени компонент -r#, таких патчей потребует с вероятностью сто процентов.

Тем не менее, в крайнем случае можно прибегнуть и к ручной сборке требуемого пакета: такие самосборные пакеты будут существовать в системе на равных правах с установленными портежами. Более того, при определении системой портежей зависимостей они будут благополучно опознаны. Особенность системы портежей в том, что для контроля зависимостей она не только (и даже не столько) проверяет базу данных установленных пакетов /var/db/pkg, сколько выполняет реальное прединсталляционное конфигурирование. То есть делает то же самое, что и скрипт ./configure при ручной сборке. И потому в Gentoo не придется сталкиваться с обычной для многих пакетных дистрибутивах ситуацией, когда самосборный пакет, от которого зависит вновь устанавливаемый, не опознается системой управления пакетами (типа rpm сотоварищи).

Я столь подробно остановился на проблеме получения исходников и их ручной сборки потому, что ее касается большинство вопросов от начинающих пользователей. И действительно, вопросы эти - весьма актуальны в условиях, когда поголовная телефонизация страны (не говоря уж о ее о-Сетенении) выглядит столь же недостижимой, как коммунизм в 1980 году; или - как отдельная квартира для каждой семьи, обещанная... не помню уж, к какой дате.

Так вот, поскольку от решения проблемы исходников зависит возможность применения дистрибутива Gentoo вообще, подчеркну еще раз со всей определенностью: для использования системы портежей необходимо и достаточно иметь машину с подключением к Сети в пределах физической досягаемости. Финансовой стороны вопроса касаться не буду - но желательно, чтобы за трафик при этом платил кто-нибудь другой, например, госбюджет (не из наших ли налогов он образуется?).

А уж на худой конец, как говаривала одна дама, у нас есть вареные яйца. То есть - исходники, прилагаемые к большинству хороших CD-изданий всамделишних пакетных дистрибутивов. Нужно лишь вытащить его из SRPM или из deb-пакета. Возможно, там не окажется последней версии нужной программы - не беда, в том-то и сила системы портежей, что она поддерживает серию сосуществующих реализаций. Быть может, не хватит какого-либо Gentoo-специфичного патча - но его можно выкачать и по модему (благо патчи такие обычно тянут на килобайты или первые их десятки). И нельзя исключить, что такой пакет что-то потеряет в функциональности - это сполна перекроется тем, что собран он будет с вашими настройками и под вашу конкретную машину. А уж то, что каждое приложение и каждая утилита в системе будет установлена осознанно и целенаправленно - не измеримо никакими деньгами.

Принципы настройки системы портежей

Однако я отвлекся. Пора переходить к настройке системы портежей - это первый шаг после развертывания их древа.

Настройка портежей под индивидуальные требования основана на концепции профильных файлов (profile, что часто транскрибируется просто как профайлы - последуем и мы этому примеру). Это - некий набор конфигурационных файлов, описывающих (с помощью соответствующих переменных окружения) условия сборки портированных программ, а именно:

  • пути для поиска компонентов системы портежей;
  • условия получения исходных текстов пакетов;
  • условия их прединсталляционного конфигурирования;
  • условия компиляции.

Значения переменных путей поиска указывают на каталоги, где по умолчанию размещаются а) сама система портежей (PORTDIR=/usr/portage), исходные тексты пакетов (DISTDIR=${PORTDIR}/distfiles), промежуточные продукты компиляции (PORTAGE_TMPDIR=/var/tmp) и так далее.

Переменные условий получения исходников включают в себя базовый URL сервера, адрес, используемый механизмом Rsync, ftp-клиент, вызываемый для получения исходников и для продолжения оборванного скачивания.

Переменные условий конфигурирования представлены одной единственной переменной - USE.

Наконец, переменные условий компиляции - это указания на хост-машину и флаги оптимизации.

Предусмотрено три уровня профайлов (в порядке возрастания приоритета):

  • /etc/make.globals, глобально определяющий переменные условий сборки;
  • /etc/make.profile/make.defaults, определяющий умолчальные значения переменных условий сборки;
  • /etc/make.conf, в который заносятся пользовательские переменные условий сборки.

Первые два файла генерируются автоматически, изменять их не рекомендуется. Да в этом и нет необходимости: любые изменения, сделанные в файле /etc/make.conf (а он именно для пользовательского редактирования и предназначен), перекроют глобальные и умолчальные значения переменных условий сборки.

Кроме этого, переменные условий сборки могут задаваться в командной строке (как переменные оболочки, в виде ПЕРЕМЕННАЯ="значение", так и как переменные окружения, в виде export ПЕРЕМЕННАЯ="значение". Заданные таким образом значения имеют высший приоритет, перекрывая не только глобальные и умолчальные значения, но и пользовательские настройки в файле /etc/make.conf.

Рассмотрим вкратце содержание профайлов системы портежей, начав с наиболее глобального (но и наименее приоритетного) - /etc/make.globals.

Во первой строке его (после комментариев, предупреждающих о нежелательности редактирования) задается порядок просмотра значений переменной USE:

USE_ORDER="env:conf:auto:defaults"

Значения этой переменной перечислены в порядке уменьшения приоритета. Значение env указывает, что наиболее приоритетными выступают значения USE, заданные как переменные (оболочки или окружения). То есть команда

$ USE="-gnome"

данная перед исполнением программы emerge или ebuild, отключит поддержку GNOME в собираемом в данный момент пакете (и только в нем), даже если таковая была включена в каком-либо из профильных файлов. А команда

$ export USE="-gnome"

сделает то же самое для всего текущего сеанса работы.

Значение conf предписывает, что в случае отсутствия явно определенных значений переменной USE, таковые берутся из строки USE="..." файла /etc/make.conf, о чем подробнее будет сказано ниже.

Далее легко догадаться, что если требуемых значений переменной USE не обнаружено ни в оболочке или окружении, ни в файле /etc/make.conf, в силу вступает значение auto. Auto-значения переменной USE перечислены в файле /etc/make.profile/use.default. Он содержит список ключевых слов (флагов) переменной USE, соответствующих отвечающим за них пакетам. И смысл его в том, что если такой пакет установлен в системе, обеспечиваемая им опция рассматривается как автоматически включенная, вне зависимости от того, перечислена ли она в строке USE файла /etc/make.profile/make.defaults. То есть если мы установили пакет gpm, поддержка службы консольной мыши станет доступной для всех приложений (для которых она предусмотрена разработчиком).

Ну а значение defaults именно из строки USE файла /etc/make.profile/make.defaults и берется.

Далее в файле /etc/make.globals указываются базовый URL проекта и адрес источника для синхронизации дерева портежей

GENTOO_MIRRORS="http://www.ibiblio.org/pub/Linux/distributions/gentoo"
SYNC="rsync://rsync.gentoo.org/gentoo-portage"

и тип хост машины, например,

CHOST=i686-pc-linux-gnu

В следующих строках описываются пути поиска компонентов системы портежей - каталога для временных файлов, создаваемых при сборке пакетов

PORTAGE_TMPDIR=/var/tmp

корневого каталога дерева портежей

PORTDIR=/usr/portage

и его подкаталогов, предназначенных для хранения архивов исходников, автономных бинарных пакетов и rpm-пакетов (буде таковые образуются):

DISTDIR=${PORTDIR}/distfiles
PKGDIR=${PORTDIR}/packages
RPMDIR=${PORTDIR}/rpm

Следующие строки перечисляют каталоги, конфигурационные файлы в которых защищены от изменения при установке новых пакетов

CONFIG_PROTECT="/etc /var/qmail/control /usr/share/config
/usr/kde/2/share/config /usr/kde/3/share/config"

и файлы в защищенных каталогах, которые, напротив, должны изменяться в этой ситуации

CONFIG_PROTECT_MASK="/etc/gconf"

Здесь в отдельных версиях вклинивается строка

MAKEOPTS="-j2"

отвечающая за поддержку мультипроцессорности.

В следующих строках описываются переменные условий получения исходников, то есть ftp-клиент, запускаемый по умолчанию для скачивания исходников (и продолжения оного) вместе с необходимыми опциями, включая каталог для размещения полученных файлов:

FETCHCOMMAND="/usr/bin/wget -t 5 --passive-ftp ${URI} -P ${DISTDIR}"
RESUMECOMMAND="/usr/bin/wget -c -t 5 --passive-ftp ${URI} -P ${DISTDIR}"

Затем - флаги оптимизации для компилятора:

CFLAGS="-O2 -mcpu=i686 -pipe"
CXXFLAGS=${CFLAGS}

и еще некоторые опции (типа очистки временного каталога по завершении сборки, и т.д.).

Повторю еще раз - если какие-то значения переменных в файле /etc/make.globals пользователя не устраивают, в редактировании его необходимости нет: требуемые настройки могут быть сделаны в файле /etc/make.conf. Так, в последнем есть закрытые комментариями примеры изменения ftp-клиента по умолчанию, не говоря уж о значениях переменной USE и флагах оптимизации. Нет противопоказаний и для задания в нем иных поисковых путей - для архивов исходников, например, или каталога для временных файлов.

Каталог, в котором расположен файл make.defaults, /etc/make.profile, на самом деле представляет собой символическую ссылку на один из каталогов профайлов в дереве портежей - /usr/portage/profiles, создаваемую автоматически в соответствие с архитектурой машины и номером версии дистрибутива - вроде /usr/portage/profiles/default-x86-XXXX. Теоретически источник ссылки можно бы и изменить, хотя необходимости в том я не вижу.

Соответственно, когда речь идет о файле /etc/make.profile/make.defaults, в действительности рассматривается содержимое файла /usr/portage/profiles/default-x86-XXXX/make.defaults. Каковое ограничивается а) перечислением умолчальных значений переменной USE, указанием архитектуры машины (x86 для PC) и версии компилятора gcc.

В каталоге /usr/portage/profiles/default-x86-XXXX (или, что равнозначно, в каталоге /etc/make.profile) есть еще несколько профайлов системы портежей. О файле use.defaults речь уже была - это автоматически обновляемый список мягких зависимосте (сиречь включенных значений переменной USE). Профайл packages.build содержит маски пакетов базовой системы (то есть сокращенные имена типа sys-apps/bash, которые можно использовать в качестве аргументов команды emerge), а профайл packages, плюс к таким маскам - еще и указание на версии (или диапазон версий), которые подпадают под маскирование.

О файле /etc/make.conf разговор пойдет в следующих двух разделах. Остается лишь добавить, что здесь можно переопределить все переменные из файла /etc/make.globals, которые чем-то не приглянулись. Ну а к установке переменных условий сборки в командной строке мы еще вернемся, когда речь дойдет до практического использования системы портежей.

Подробнее о переменной USE

Итак, настройка портежей под задачи пользователя осуществляется редактирование файла /etc/make.conf. И первое, что в нем можно увидеть - это переменная USE. Что она делает?

Все, кому приходилось самостоятельно собирать программы из исходников, знают, что процесс этот начинается (за исключением уж совсем простых программ) с запуска сценария конфигурирования в корне дерева исходных текстов:

./configure

Многие (и вы, мои читатели, в их числе, не так ли?) предваряют этот процесс изучением тех возможностей настройки, которые автор заложил в этот сценарий:

./configure --help

Вывод подсказки в ответ на эту команду может быть более или менее полным. Однако в нем практически всегда можно увидеть такие опции, как --with-ИМЯ_ПАКЕТА и --without-ИМЯ_ПАКЕТА, а также --enable-ИМЯ_ФИЧИ и --disable-ИМЯ_ФИЧИ. На счет "всегда" - это я несколько преувеличил, но в подсказке такие строки встречаются часто А иногда даже подробно расписывается их возможное конкретное содержание.

Первая пара опций разрешает (или, соответственно, запрещает) использование данной программой какого-либо пакета из числа установленных в системе, а вторая, как нетрудно догадаться, позволяет включить (выключить) какие-либо дополнительные возможности. Например, команда

./configure --with-x

для консольной программы сконфигурирует ее так, что после сборки она сможет не просто работать в системе X, но использовать дополнительные возможности, ею предоставляемые (шрифты, цветовые схемы и т.д.). А команда

./configure --enable-postscript

обеспечит собираемой программе поддержку печати на PostScript-принтерах.

Опции with/without и enable/disable специфичны для каждой программы. Очевидно, что включать поддержку PostScript для программы, которая не предусматривает печати вообще - бессмысленно. Обычно разработчик программы устанавливает (или, напротив, отключает) поддержку неких пакетов и возможностей (а наиболее альтруистичные из них - еще и описывают, каких именно) по умолчанию. Разумеется, чтобы воспользоваться дополнительными возможностями, нужно иметь соответствующие пакеты установленными, а фичи - поддерживаемыми системой.

Поскольку система портежей дистрибутива Gentoo автоматизирует процесс сборки программ из исходников, она, прежде чем начать собственно компиляцию заказанной программы, она выполняет ее конфигурирование. То есть явным образом запускает сценарий ./configure. Однако любая автоматизация имеет свою оборотную сторону. И в данном случае она выражается в том, что пользователь лишен возможности указать, какие опции собираемой программы он хотел бы видеть включенными, а какие - выключенными.

И вот тут ему на помощь приходит переменная USE. Именно из нее берутся значения для опций with/without и enable/disable при конфигурировании любой программы. И вместо того, чтобы каждый раз задавать их вручную в командной строке, пользователь может определить их единожды и навсегда в файле /etc/make.conf. Или, напротив, варьировать эти значения в зависимости от ситуации при установке группы программ.

Формат переменной USE прост:

USE="name1 name2 -name3 -name4"

Легко догадаться, что name1 и name2 включают, а -name3 и -name4 - отключают поддержку поименованных пакетов и возможностей. При начальной установке Gentoo действует предопределенный по умолчанию набор значений USE, о чем говорилось выше. Он выглядит примерно так:

USE="x86 oss 3dnow apm arts avi berkdb \
crypt cups encode gdbm gif gpm gtk imlib \
java jpeg kde gnome libg++ libwww mikmod \
mmx motif mpeg ncurses nls oggvorbis \
opengl pam pdflib png python qt qtmt \
quicktime readline sdl slang spell ssl \
svga tcpd truetype X xml2 xmms xv zlib"

Символ \ в этом примере показывает, что на самом деле значения переменной даются одной строкой, без переносов.

Из приведенного списка можно видеть, что по умолчанию все программы собираются с поддержкой почти всего, чего только можно. Конечно, в том случае, если это имеет физический смысл (изначально закладываемый разработчиком программы): смешно было бы думать, что включение опции quicktime волшебным образом добавит в консольный текстовый редактор возможность просмотра анимаций...

Однако кое-какие из умолчальных возможностей могут показаться (данному конкретному) пользователю излишними. Пара простых примеров из собственной практики. Согласно списку значений USE, консольные приложения через систему портежей Gentoo будут собираться с поддержкой службы консольной мыши - gpm (если таковая, конечно, установлена). Это, конечно, хорошо, товарищи: в собранных с поддержкой gpm приложениях типа links или Midnight Commander мышью можно пользоваться как обычным указательным устройством - для выбора URL или пунктов меню, например (ну в точь как в Windows).

Но это... нехорошо, товарищи. Поскольку при этом блокируются стандартные для консолей Linux функции выделения мышью экранных блоков, помещения их в буфер и вставки щелчком средней клавиши. И потому первое, что я делаю перед установкой приложений из Portage - отключаю поддержку gpm в файле /etc/make.conf:

USE="-gpm"

С другой стороны, сколь бы ни был полон умолчальный список значений переменной USE, наверняка в нем не отыщется чего-то нужного. Например, среди фигурирующих в нем графических форматов бесполезно было бы искать tiff. А можно ли представить себе работу в том же GIMP без возможности работы с tiff-файлами?

По аналогии с другими, поддерживаемыми по умолчанию, графическими форматами можно догадаться, что для поддержки tiff-файлов нужно включить соответствующее слово в строку

USE="-gpm -gtk tiff"

Однако, а) остается сомнение в правильности догадки, и б) просыпается любопытство - а какие же еще возможности конфигурирования кроются в переменной USE? Чтобы рассеять первое и удовлетворить второе, рассмотрим основные значения переменной USE. На основании обеспечиваемых функций ими функций можно выделить следующие их группы:

  • флаги указания на архитектуру;
  • флаги поддержки аппаратуры;
  • флаги поддержки экрана;
  • флаги поддержки рабочих сред;
  • Флаги поддержки графических библиотек
  • флаги поддержки мультмедийных библиотек;
  • флаги поддержки сетевых служб;
  • флаги обеспечения безопасности;
  • почтовые флаги;
  • флаги, специфичные для браузера Mozilla;
  • флаги, имеющие отношение к офисным приложениям;
  • флаги, имеющие отношение к языкам (программирования, об обычных - ниже);
  • флаги, связанные с базами данных;
  • флаги поддержки файловых систем;
  • прочие пользовательские флаги.

Не все из этих флагов одинаково важны для пользователя. Я подробно рассмотрю те из них, которые мне таковыми показались; и в которых я поэтому попробовал разобраться:-).

Флаги указания на архитектуру, как несложно догадаться, изменению не подлежат, устанавливаясь автоматически в каждом профильном файле, соответствующему одной из поддерживаемых архитектур. Однако для полноты картины - они следующие: x86, ppc, sparc, sparc64, alpha. Комментарии, думается, излишни.

Флаги поддержки аппаратуры - это в первую очередь флаги поддержки расширений наборов команд для различных процессоров: mmx (для процессоров Pentium-MMX, включая Athlon), 3dnow (набор команд, специфичный для процессоров AMD, начиная с K-6) и sse (команды, реализованные в Pentium-III и выше).

Далее - флаги поддержки видеокарт. Их - три, 3dfx, voodo03 и matrox. Очевидно, что включать эти флаги нужно при наличии соответствующего видеоадаптера.

Группа флагов связана с поддержкой ноутбуков и КПК. Это - apm (поддержка энергосбережения), pcmcia (для работы с одноименными устройствами), pnp (для горячего подключения pcmcia-устройств), pda (обеспечивающий интерфейс с PalmPilot и иными карманными устройствами).

Флаг gphoto2 включает возможность взаимодействия цифровой камеры с графическими приложениями. Ну а флаг cups обеспечивает программам поддержку этой системы печати. Разумеется, только тем, которые вообще способны печатать...

Флаги поддержки экрана связаны преимущественно с оконной системой X. О флаге x, обеспечивающим использование ее возможностей консольными приложениями, мы уже говорили. Впрочем, без этого флага оказывается невозможным собрать любое X-приложение (включая саму систему XFree86). Флаг dga обеспечивает оптимизацию с учетом т.н Direct Graphic Access (что требует поддержки соответствующей опции ядром), флаг opengl отвечает за поддержку библиотеки OpenGL (приложениями, которые в состоянии ее использовать). А флаг xv включает поддержку расширения XVideo (в частности, он очень рекомендуется для сборки Mplayer).

Два флага - fbcon и directfb, - обеспечивают поддержку Frame Buffer. При установке первого в консольных приложениях задействуются возможности графической консоли. Второй же обеспечивает сборку X-приложений в том случае, если в Иксах используется не стандартный SVGA-сервер, а сервер DirectFB (это требуется, если SVGA-сервер не работает с видеосистемой машины).

Флаги поддержки рабочих сред обеспечивают сборку приложений для работы в интегрированных средах - KDE и GNOME. Поддержка первой обеспечивается флагами kde (для включения общей ее поддержки), qt (для линковки с библиотекой Qt, на которой KDE основано), qtmt (для линковки с многопоточной версией этой библиотеки) и arts (для поддержки звуковой системы KDE). Очевидно, при использовании KDE-приложений включение этих флагов необходимо (кроме qtmt). И наоборот, они весьма полезны для запуска сторонних приложений внутри KDE. А вот тем, кто эту среду использовать не желает, их лучше отключить.

Для сборки GNOME и его приложений требуются флаги gnome и один из двух флагов - gtk или gtk2 (для соответствующих версий библиотеки GTK). Впрочем, поддержка одной из последних требуется и другими приложениями, например, GIMP.

Для GNOME-приложений дополнительно можно включить и еще несколько флагов: bonobo (для поддержки одноименного CORBA-интерфейса), evo (для поддержки Evolution), gb (поддержка языка Gnome Basic) и gtkhtml (поддержка библиотеки GTK-HTML).

Флаги поддержки графических библиотек:

  • motif - поддержка известного тулкита OpenMotif, на котором основаны многие оконные менеджеры и X-приложения;
  • tcltk - поддержка языка Tcl и его расширения Tk;
  • aalib - поддержка т.н. ASCII-графики;
  • imlib - поддержка библиотеки считывания и рендеринга изображений;
  • ncurses - поддержка одноименной библиотеки, используемой очень многими консольными приложениями;
  • readline - также включает соответствующую консольную библиотеку;
  • sdl - поддержка библиотеки Simple Direct Layer media (что такое - не знаю; в руководстве сказано, что используется многими играми);
  • svga - поддержка библиотеки SVSAlib, альтернативного (относительно системы X) способа реализации графического режима в Linux; насколько я знаю, кроме игр, используется только в zgv - графическом вьювере;
  • lcms - система управления цветом для универсального пакета неинтерактивной обработки изображений, imageMagick;

Сюда же включаются и флаги поддержки разнообразных растровых графических форматов, как то: gif, jpeg, png, tiff (для поддержки библиотек giflib, libjpeg, форматов PNG и TIFF, соответственно). И, наконец, gd - база данных библиотек проекта GNU, - также оказывается в этой группе.

Флаги поддержки мультмедийных библиотек для поддержки видео и анимации: avi (обеспечивает поддержку видеобиблиотек, вплоть до кодеков Win32), mpeg (для поддержки библиотеки libmpeg3) и quicktime (поддержка Macintosh'евской анимации).

Далее - флаги поддержки аудиобиблиотек, alsa, esd, mikmod, oss и nas.

И наконец - прочие мультимедийные флаги:

  • ggi - поддержка неиксовых видеодрайверов для воспроизведения анимаций;
  • dvd - поддержка воспроизведения и снятия защиты DVD-дисков с использованием библиотеки libcss;
  • xmms - ну кто нынче не слышал о X MultiMedia System;
  • oggvorbis - поддержка Ogg Vorbis - истинно свободного аудиоформата;
  • flash - как сказано, поддержка создания файлов flash-анимации;
  • encode - для декодирования различных мультимедийных форматов.

Флагов поддержки сетевых служб - три, ipv6 (поддержка протокола IPv6, который, как говорят, придет на смену IPv4), snmp (протокол SNMP -Simple Network Management Protocol, для управления удаленными машинами) и ggz (поддержка GNU Gaming Zone).

Флаги обеспечения безопасности таковы: pam, ssl, crypt, socks5.

Почтовые флаги обеспечивают поддержку почтовых протоколов (imap и ldap), стилей спулинга почты (maildir - в каталог ~/.maildir, и mbox - в каталог /var/spool/mail), TCP-wrapp'инга (tcpd), почтовых отправлений sylpheed (xface).

Флаги, специфичные для браузера Mozilla - это в первую очередь mozilla - поддержка этого браузера прочими приложениями. При установке Mozilla действенны следующие флаги: mozaccess-builtin, mozctl (модуль Pango), mozirc (модуль IRC), mozxmlterm (xterm-подобный терминал с поддержкой XML).

В группе флагов, имеющих отношение к офисным приложениям, можно видеть:

  • spell - для поддержки проверки орфографии посредством ispell, aspell или pspell;
  • truetype - для шрифтовой поддержки через FreeType и FreeType2;
  • xml - для поддержки библиотеки XML (версия 1);
  • xml2 - то же, но для библиотеки GNOME's XML (версия 2);
  • pdflib - добавление поддержки PDF;
  • plotutils - добавление поддержки plotting'а в gnuplot;
  • tetex - поддержка TeTeX.

Флаги, имеющие отношение к языкам программирования - следующие:

  • guile - поддержка интерпретатора Guile для языка Scheme;
  • java - поддержка одноименного языка; если ее выключить, собранная из исходников Mozilla будет спотыкаться на каждом третьем современном сайте, требуя скачать plug-in;
  • perl, python, ruby - понятно из названий (или - не понятно, но тогда и понимать не нужно, оставляем по умолчанию);
  • slang - поддержка интерпретируемого языка S-Lang, задействованного во многих консольных приложениях (например, в редакторе Jed);
  • libwww - общая поддержка web api;
  • libg++ - добавление модулей C++;
  • atlas - поддержка ATLAS (Automatically Tuned Linear Algebra Software);
  • pic - аналогично предыдущему пункту;
  • zeo - поддержка объектов Zope, насколько я понимаю, нечто связанное с управлением сайтами и языком Python.

Флаги, связанные с базами данных, обеспечивают выбор типа управления базами данных, для которого хотелось бы получить поддержку, из стаких вариантов: berkdb, mysql, postgres, oci8, odbc, innodb, gdbm.

Флаги поддержки файловых систем: acl - поддержка утилит dump/restore для файловой системы XFS, afs - поддержка файловой системы OpenAFS , samba - поддержка доступа к ресурсам Windows-сетей посредством SAMBA.

Прочие пользовательские флаги, понятное дело, объединяют все, что не вохло в ранее перечисленные группы. Один из важнейших для нас - nls, то есть поддержка национальных языков (NLS - Native Language Support), реализуемая посредством gettex. Близко к этому лежат флаги cjk (поддержка китайской, японской и корейской специфики), canna (поддержка конверсии Кана-Кандзи (это две такие японские письменности) и freewnn (имеет отношение к тем же Кана-Кандзи), а также mule - включение многоязыковой поддержки в XEmacs.

Флаг gpm - поддержка той самой консольной мыши, о которой я столько говорил ранее, флаг cdr - поддержка железа для записи CD-R (в большинстве случаев можно обойтись без нее, требуется, как можно понять из документации, только для koncd). И, наконец, zlib - поддержка одноименной библиотеки (о которой столь много говорили весной) для компрессии/декомпрессии.

Внимательный читатель наверняка заметил в изложенном выше некоторое противоречие. Например, предлагается отключить поддержку системы X при сборке консольных приложений. И в то же время утверждается, что при значении переменной USE="-x" ни одно X-приложение собрать невозможно.

Противоречия такого рода (а случай с x - не единственный) можно разрешить различными способами. Например, временной правкой файла /etc/make.conf, или созданием двух альтернативных файлов конфигурации. Наиболее же простой способ - задание значений USE в командной строке, - будет описан в разделе об использовании системы портежей. Однако предварительно, в следующей статье Gentoo-цикла, будет описана настройка этой системы на предмет оптимизации.

Вопросы оптимизации

Переменная USE - эффективный способ настройки Gentoo под задачи пользователя. Однако редактированием файла /etc/make.conf можно добиться большего - задать глобально условия компиляции. То есть, по простому говоря, те флаги компилятора gcc, которые при ручной сборке программ обычно задаются в командной строке утилиты make.

Рассмотрение флагов компилятора gcc само по себе далеко выходит за рамки этой заметки. Наша сегодняшняя цель сугубо практическая - рассмотреть рецепты, позволяющие добиться наибольшей оптимизации как базовой системы, так и всех компилируемых приложений под конкретное железо.

Для чего возвращаемся к файлу /etc/make.conf, в котором видим три строки, описывающие флаги компиляции. По умолчанию, в свежеустановленной из тарбаллов, системе они имеют вид вроде:

CHOST='i686-pc-linux-gnu'
CFLAGS='-march=pentium4 -mcpu=pentium4 -O3 -pipe'
CXXFLAGS='-march=pentium4 -mcpu=pentium4 -O3 -pipe'

Первая строка определяет архитектуру хост-машины, то есть компьютера, на котором компиляция выполняется. А поскольку, если иное не указано явным образом, тип целевой машины принимается совпадающим с хостом, то характеризует и компьютер, для которого компилируется система. Исключение - случаи кросс-платформенной компиляции, тогда и host, и target нужно определять отдельно. С типом все просто - для всех процессоров от PentiumPro и выше (включая Athlon'ы разного рода и Pentium4) строка по умолчанию отражает действительность. Для Pentium просто здесь следовало бы поставить

CHOST='i586-pc-linux-gnu'

и так далее, но собирать на таких машинах Gentoo - занятие весьма скучное.

А следующие две строки и содержат флаги, определяющие условия оптимизации для неких процессоров. Верхняя из них действенна для сборки исходников на Си просто, нижняя - для Си++.

Рассмотрим эти флаги в обратном обычному порядке (справа налево). Флаг -pipe предписывает использовать при компиляции т.н. программные каналы вместо временных файлов для передачи данных между разными стадиями компиляции. Она не влияет на быстродействие генерируемого кода, но способствует ускорению самого процесса компиляции. И, следовательно, лишней не будет.

Флаг -O# задает собственно уровень оптимизации - от самого низшего, O (или O1, что идентично) до высшего - O3 (уровень O0 означает отсутствие всякой оптимизации). Собственно, каждый из этих флагов - некая совокупность опций, способствующих быстродействию сгенерированного кода, но для нас это не существенно.

Как можно видеть, по умолчанию в Gentoo предписывается самый высокий уровень оптимизации (O3). С чем, казалось бы, трудно не согласиться - какой же русский не любит быстрой езды. Правда, у быстрой езды есть оборотная сторона - не каждое приложение обязано собираться при высшей степени оптимизации. Кроме того, на самом деле ощутимый прирост быстродействия сгенерированного кода происходит при уровне O2 - повышение его в некоторых случаях способно даже замедлению работы.

Переходим к двум следующим флагам. Смысл их близок и сводится к указанию конкретного процессора, под который производится сборка. В качестве значения обоих флагов могут выступать абсолютно все Intel-совместимые процессоры, от i386, K6, Duron до Athlon-XP, -MP и Pentium4. Полный список поддерживаемых камней можно посмотреть в комментариях к файлу /etc/make.conf или, еще лучше - на man (1) gcc.

В чем различие флагов -march и -mcpu? Первый генерирует код с учетом особенностей указанного процессора, без возможности запуска на более младших моделях. Второй делает то же самое, но сохраняет совместимость с братьями меньшими. То есть при сборке системы на настольной машине и для нее же представляется избыточным. Так что в реальности можно ограничиться указанием лишь -march=модель.

В принципе, этими тремя флагами можно и ограничиться. Однако существуют и многие другие флаги, из которых к числу "безопасных" (safe) отнесен -fomit-frame-pointer, что его наличие способствует исключению некоторых необязательных команд и таким образом также способствует быстродействию. Так что, вероятно, пренебрегать им нет оснований.

В итоге строки с gcc-флагами оптимизации для Pentiun4 (например) примут следующий вид:

CFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"

Каковой и можно принять как оптимальный в обычных условиях. В случае реликтового (по цене, но не по производительности) Pentium-III, значение -march следует изменить на pentium3, для Athlon разных видов - на athlon (athlon-tbird, athlon-xp, athlon-mp), и так далее.

Существуюти предложения более жесткой оптимизации, а именно - указание флагов -ffast-math (оптимизация с нарушением некоторых правил ANSI и IEEE), -fforce-addr, -funroll-loops и некоторые другие. За отсутствием собственного опыта, не могу ничего сказать об их действенности. Но то, что они не отнесены к safe-флагам, говорит, что использовать их следует осторожно. И не особо удивляться, получив сообщение об ошибке после пары часов сборки какого-либо тяжелого приложения.

Использование портежей: программа emerge

Наступило время поговорить о практическом использовании системы портежей. А это, в первую очередь - программа emerge. Как уже было сказано, она определяется как универсальный интерфейс к системе портежей.

В элементарном виде использование emerge просто до безобразия. Так, чтобы установить некий пакет, достаточно дать команду

$ emerge категория/имя_пакета

При этом обычно не обязательно указывать имя ebuild-файла, номер версии и прочие уточняющие моменты - программа сама решит, что ей ставить. Однако в не-элементарном виде использование emerge может быть весьма сложным, что обусловлено именно ее универсальностью, и потребует изучения документации - man (1) emerge.

Настоящая заметка на роль исчерпывающего руководства не претендует. Я попробую только прокомментировать формат вызова программы, описать наиболее употребимые функции и дать примеры практического применения, в том числе - и в сочетании с переменной USE, определяемой в командной строке.

Синтаксис команды для вызова программы emerge в общем виде может показаться непривычным, так как включает три различных компонента (кроме имени программы, разумеется). В обобщенном виде он выглядит так:

$ emerge [options] [action] [argument1] ... [argument#]

Options - это обычные опции, такие же по смыслу, как в любой Unix-команде. Action - переведем это как действие, ибо именно действия в отношении портежа этим компонентом и описываются (например, search - поиск по ключевому слову); обращаю внимание, что слово action дано здесь (как и в оригинальной man-странице) в единственном числе - такое действие с emerge в отношении данного портежа может быть выполнено за раз только одно. И, наконец, аргументы - это объекты, к которым применяются опции команды emerge или выполняются ее действия.

Аргументы команды для вызова программы emerge можно задать одно из четырех способов - в виде ebuild, tbz2file, class и dependency. Начнем с первого из них, ebuild.

В общем случае аргумент ebuild - это имя пакета, который требуется установить. Оно может быть задано в различных формах. Например, просто как имя пакета, без номера версии или указания категории:

$ emerge joe

Хотя и уточнение в виде категории - не возбраняется:

$ emerge app-editors/joe

В обоих случаях по такой команде emerge отыщет в каталоге /usr/portage/app-editors/joe ebuild-файл, соответствующий либо наиболее свежей, либо последней стабильной версии, и выполнит над ним некие заданные действия или применит к нему указанные опции (в данном примере, по умолчанию, просто соберет и установит пакет).

Какая именно версия поименованного пакета будет установлена - определяется майнтайнером конкретного портежа. В указанном выше примере с редактором joe ею окажется именно последняя стабильная версия (хотя в дереве портежей имеется и ebuild-файл для разрабатываемой ветки. А в иных случаях случае указание соответствующего ebuild'а без уточнения версии может привести к установке пререлизной, а не стабильной версии.

Такая ситуация может не устраивать пользователя - ведь вполне вероятно, что в одном случае ему потребуется гарантированная стабильность финального релиза, в другом же - дополнительные возможности development-варианта. Однако проблема эта легко решаема - достаточно дать полную спецификацию ebuild-файла (теперь уже - с обязательным указанием его категории). Так, возвращаясь к примеру с редактором joe, для установки разрабатываемой его версии программу emerge следует дать в такой форме:

$ emerge app-editors/joe/joe-2.9.8.ebuild

Подчеркну, что, вне зависимости от текущего каталога, аргумент ebuild может указываться в приведенной форме. Из чего становится ясным, что мы указываем не путь к ebuild-файлу (хотя, конечно, и указание полного пути в абсолютной или относительной форме не возбраняется), а зарезервированную последовательность ключевых слов - имя категории, имя пакета, имя конкретного ebuild'а.

Аргумент tbz2file - имя автономного бинарного пакета, собираемого из исходников и имеющего форму *.tbz2. Каковой представляет собой tar-архив, компрессированный утилитой bzip2 и содержащий в конце некоторую дополнительную информацию.

Очевидно, что в отношении такого пакета можно выполнить две манипуляции - либо его создать, либо - установить. И то, и другое осуществляется программой emerge с помощью некоторых определенных действий или опций, о которых я скажу чуть позже.

Аргумент class - это условное сокращение для крупных групп пакетов. Таковых в текущей версии системы портежей существует два - system и world.

Класс system включает в себя пакеты (общим числом чуть больше двадцати), необходимые для запуска системы. Список их можно просмотреть при установке Gentoo - сразу после развертывания тарбалла stage3, - с помощью команды

$ emerge -p system

Класс world

Класс world включает в себя все пакеты класса system, а также пакеты, установленные дополнительно через систему портежей; список последних содержится в файле /var/cache/edb/world.

В отношении обоих классов можно выполнить лишь одно действие - их обновление (включающее перекомпиляцию) - именно это мы проделывали над классом system после развертывания тарбаллов при установке Gentoo. Ну а обновление класса world - это полная пересборка системы, аналогичная процедуре make buildworld в BSD-системах.

И, наконец, аргументы команды для вызова программы emerge можно задать в форме dependency (зависимостей). Эта форма (которую не следует путать с отношениями зависимости пакетов) определяет верхнюю или нижнюю границу диапазона версий устанавливаемого пакета. Для указания граничной версии используются стандартные символы >имя_пакета-номер_версии (выше указанной версии), >=имя_пакета-номер_версии (начиная с указанной версии и выше), <имя_пакета-номер_версии (ниже указанной версии), <=имя_пакета-номер_версии (начиная с указанной версии и ниже). Например, командой

$ emerge ">app-shell/tcsh/tcsh-6.11"

будет установлена последняя из доступных (в текущем дереве портежей) версий командной оболочки, выше версии 6.11, и так далее.

Обратим внимание на двойные кавычки, в которые заключен dependency-аргумент данного примера. Они появились здесь от того, что большинство командных оболочек интерпретируют символы типа < или > (да, впрочем, и = тоже) как специальные, тогда как нам нужно их "буквальное" понимание. Поэтому для таких символов следует тем или иным образом экранировать их специальное значение, а предварением ли символом обратного слэша , заключением в одинарные или двойные кавычки - это определяется правилами конкретной командной оболочки, используемой как login shell.

В командной строке вызова программы emerge можно указывать более одного аргумента (в принципе - сколько угодно). Однако, хотя это в документации прямо не запрещается, лучше не смешивать в одной команде аргументы разных форм. Дело в том, что по умолчанию в отношении аргументов разных форм предполагаются различные действия. И, кроме того, некоторые опции и действия применимы только к аргументам отдельных типов.

Теперь о действиях (actions). Собственно говоря, важнейшим из них, пожалуй, является отсутствие указания действий (No action). В этом случае в силу вступают умолчания программы emerge, различные, как уже было сказано, для аргументов разных форм. Так, при указании аргумента типа ebuild -

$ emerge имя_пакета

будет выполнена сборка и инкорпорация пакета в файловую систему. Если в качестве аргумента задать тип tbz2file

$ emerge /path/пакет.tbz2

то указанный автономный бинарник будет развернут в соответствующих каталогах файловой системы (примерно также, как это происходит при установке из бинарных rpm- или deb-пакетов).

А указание аргумента в форме class, как то

$ emerge system

или

$ emerge world

приведет к обновлению, пересборке и переустановке базовой системы или системы целиком, соответственно. Однако возможности программы к этому не сводятся, позволяя выполнять и другие операции. Для чего и предназначаются дополнительные действия (action). Значение каждой action задается в командной строке в виде соответствующего ключевого слова, после которого следует аргумент команды вызова emerge или критерий действия, например:

$ emerge clean ebuild_аргумент

или

$ emerge search ключевое_слово

Кроме этого, некоторые (но не все) действия могут вызываться и в краткой, односимвольной, форме, предваряемой символом дефиса, например, -c вместо clean или -s вместо search. Что делает их внешне похожими на опции (для которых тоже допустима односимвольная форма), но путать эти компоненты интерфейса emerge не следует.

Доступные для emerge действия можно разделить на три группы:

  • действия информационного характера;
  • действия по синхронизации;
  • действия по удалению.

Рассмотрим эти группы действий последовательно.

Действия информационного характера - это help (-h), info (краткой формы не имеет) и searce (-s).

Действие help, как легко догадаться, предназначено для получения подсказки по программе emerge. Начать с того, что это действие срабатывает либо в краткой форме

$ emerge -h

либо предваряемое удвоенным символом дефиса

$ emerge --help

что, впрочем, указано в самом начале man-страницы. Зато в ответ на это она выводит аналог последней, но - более подробный и более часто (согласно документации) обновляемый. Кроме того, добавление к этому действию одного из двух возможных аргументов (config или system) позволяет получить весьма подробные сведения о переменной CONFIG_PROTECT и об использовании emerge с классом system, соответственно.

Не менее полезным видится действие info, аргументов не требующее (как и предваряющих дефисов). В ответ на команду

$ emerge info

последует вывод всех сведений о настройке системы портежей, как то:

  • действующих в текущий момент значений переменной USE, аккумулирующих умолчальные установки, настройки в файле /etc/make.conf и заданные в командной строке;
  • указания на архитектуру, целевую машину и версию компилятора;
  • флаги оптимизации для компилятора;
  • список защищенных от изменения конфигурационных каталогов (значения переменной CONFIG_PROTECT) и подкаталогов в них, для изменения разрешенных (CONFIG_PROTECT_MASK);
  • URL источника синхронизации (значение переменной SYNC) и базового сервера проекта (переменная GENTOO_MIRRORS).

Иными словами, с помощью emerge info всегда можно определить, каковы нынче условия работы системы портежей.

Цель действия search - поиск пакетов, вернее, просмотр дерева портежей на предмет совпадения имен файлов с указанным в качестве аргумента шаблоном. Поэтому, хотя в качестве такого шаблона поиска можно ввести любую последовательность символов, целесообразно ограничиться лишь именем пакета. Зато после нахождения оного будут выведены интересные о нем сведения. Например, в ответ на

$ emerge search joe

последует что-нибудь вроде:

Searching...
[ Results for search key : Joe ]
[ Applications found : 1 ]

* app-editors/joe
Latest version available: 2.9.5
Latest version installed: 2.9.8_pre1
Size of downloaded files: 204 kB
Homepage: http://sourceforge.net/projects/joe-editor/
Description: A free ASCII-Text Screen Editor for UNIX

В качестве шаблонов поиска можно использовать регулярные выражения, привязывающие искомый шаблон к началу или к концу имени пакета. Например, командой

$ emerge search "^gnome"

отыщет все пакеты, начальный компонент имени которых показывает их принадлежность к семейству GNOME (app-editors/gnome-chord, app-text/gnome-spell и т.д.). А с помощью команды

$ emerge search "gnome$"

напротив, будут отысканы пакеты с именами, на gnome заканчивающиеся (app-doc/ebook-libgnome, dev-java/java-gnome, etc.). Обратим внимание на двойные кавычки в приведенных примерах: спецсимволы из регулярных выражений нуждаются в экранировании (каковым опять же может выступать предварение обратным слэшем или заключением во всякого рода кавычки всего шаблона). Заодно заметим, что в шаблоне не различаются регистры символов: командой

$ emerge search "^W"

будут найдены как пакет app-admin/watchdog, так и пакет x11-wm/WindowMaker.

Действий по синхронизации в программе emerge предусмотрено два - rsync и sync. Оба они предназначены для обновления дерева портежей с сервера, определенного в качестве значения переменной SYNC - того самого, которое мы установили посредством команды emerge info.

А вот действий по удалению - изрядное количество: clean (-c) и depclean, prune (-P) и unmerge (-C).

Назначение действия clean (-c) - удаление пакетов (старых их версий или версий, явным образом указанных) без влияния на функциональность системы. В качестве аргумента при этом действии могут выступать типы ebuild, class или dependencie.

Суть действия depclean (не требующего аргументов) - в выявлении не-необходимых для функционирования системы пакетов и, после запроса на подтверждение, их удалении. Очень зависит от установленных значений переменной USE.

Действие prune (-P), в аргументах которого могут фигурировать типы ebuild, class или dependence, потенциально опасно. Оно заключается в удалении старых версий всех указанных в аргументах пакетов. Зависимости при этом не проверяются, и в результате могут быть удалены компоненты, важные для запуска других программ.

Аналогично и с действием unmerge (-C)- это просто удаление указанных в аргументах (в форме ebuild, class или dependence) пакетов, также без проверки зависимостей от них других пакетов.

Наконец, есть еще одно действие, которое я затрудняюсь отнести к какой-либо из перечисленных групп. Это - inject (-i). Она позволяет зарегистрировать в базе данных определенную версию некоего пакета без его установки. Ее можно применить, если, скажем, после очередного выполнения rsync вы проверили результат


emerge -pu world

и в целом вам все нравится, вот только вы не хотите выполнить обновление какого-то определенного пакета. Тогда его можно просто принудительно включить в дазу данных как обновленный, выполнив команду


emerge inject =pkg-PV-PR

и затем спокоино выполнять


emerge -u world

Естественно, при этом желательно знать, что и зачем делается). Впрочем, если такой принудительно включенный пакет был жесткой зависимостью для какого-то другого, это будет обнаружено при компиляции. Но зато такой способ позволяет обходить узкие места, если, скажем, новая версия какой-то библиотеки конфликтует с чем-либо необходимым, а старая позволяет установить все остальное.

Многочисленные опции командной строки вызова программы emerge придают ей дополнительную гибкость. Рассмотрим те из них, которые наиболее важны для пользователя.

Комплекс действий по предварительной подготовке к установке пакета обеспечивается опциями --searchdesc (-S), --pretend (-p), --fetchonly (-f) и --onlydeps (-o).

Первое, что обычно требуется - это разыскать нужный пакет в дереве портежей. Помнится, это можно было сделать посредством акции search - однако только по имени. Опция же --searchdesc (-S) выполняет поиск заданной последовательности символов также и в описании пакета - строке Description, которую мы уже видели в выводе команды emerge search.

Следующая по очередности применения - и очень важная, - опция --pretend (-p), которая может сопровождаться аргументами любого типа. Она выводи список пакетов, необходимых для установки заданного пакета, класса или dependency, причем - именно в том порядке, в каком они должны устанавливаться. Каждый из выводимых пакетов маркируется следующим образом: N - новый (то есть отсутствующий в системе, U - нуждающийся в обновлении до указанной версии, R - заменяющий ранее установленный пакет, B - блокирующий ранее установленный пакет.

Опция --pretend определяет не только жесткие зависимости, но и мягкие, а следовательно - ее вывод очень зависит от текущих кумулятивных значений переменной USE (которые мы получаем командой emerge info, не так ли?). Так что если нам покажется, что устанавливаемый пакет предъявляет аппетиты не по чину - самое время перед собственно установкой подкорректировать эту переменную, хотя бы в командной строке:

$ USE="-то -это -и_вот_это" emerge --pretend ebuild-аргумент

для приведения его аппетитов в соответствие с реальностью.

Опция --fetchonly (-f) с указанием ebuild-аргумента предназначена для скачивания пакета, указанного в командной строке, и всех тех, с которыми он связан отношениями зависимости и использования. Ее использование может быть полезно, если скачивание производится не с целевой машины для сборки, при модемном подключении (иначе придется устанавливать соединение в самый неподходящий момент), или просто при желании ознакомиться с исходными текстами перед установкой.

При указании опции --onlydeps (-o) (с ebuild-аргументом) производится скачивание, сборка и установка только тех пакетов, с которыми указанный в командной строке связан зависимостями, но не его самого. В сочетании с опцией --fetchonly обеспечивается только получение всех необходимых пакетов (на случай. например, если исходники самого заказанного пакета на целевой машине уже имеются).

Для контроля над процессом сборки и установки пакетов предназначены опции --nodeps, --noreplace (-n), --oneshot, --update (-u).

Указание опции --nodeps вместе с ebuild-аргументом приводит к тому, что собирается и устанавливается (с предварительным скачиванием, если таковое не имело места ранее) только заказанный пакет, без всех компонентов, с которыми он связан отношениями зависимости и использования. По вполне понятным причинам не исключено (более того, очень даже вероятно), что сборка при этом завершится сообщением об ошибке - если были нарушены какие-либо жесткие зависимости (типа X-сервера от xlib).

Как говорилось ранее, в командной строке вызова emerge можно указать более одного аргумента (например, ebuild-файла). А поскольку от склероза никто не гарантирован, нельзя исключить возможности того, что какой-то из заказанных пакетов был установлен ранее. По умолчанию произойдет пересборка и переустановка такого пакета (что в случае Иксов или KDE займет многие часы). Во избежание такой ситуации и предусмотрена опция --noreplace - указание ее предотвратит пересборку уже установленных пакетов.

Назначение опции --oneshot - весьма специфично. Она запрещает добавление установленного пакета в список составляющих класса world. В результате при полной пересборке системы такой пакет обновлен не будет. Это может потребоваться в том случае, если требуется жестко специфическая версия некоей программы.

Смысл опции --update (-u) более чем понятен из ее названия: это обновление пакета до последней доступной в текущем дереве портежей версии. Правда, пакетов, с которыми заказанный связан отношениями зависимости или использования, она не обновляет - и в этом ее отличие от автоматического обновления через emerge system или emerge world.

Работа с автономными пакетами

Сборка программ из исходников - основной способ их установки в дистрибутиве Gentoo. Однако в нем предусмотрена и возможность создания и установки автономных бинарных пакетов (в формате *.tbz2, или, как он именуется в документации, улучшенном *.tar.bz2). По сути своей они ничем не отличаются от компонентов любого пакетного дистрибутива (rpm, deb, tgz). И включают в себя расписанные по каталога (bin, lib, etc и т.д.) откомпилированные программные компоненты и некоторую метаинформацию для их корректной установки в текущей файловой системе. Так вот, именно для работы с такими пакетами в emerge предусмотрено две специальные опции - --buildpkg (-b) и --usepkg (-k).

Опция --buildpkg (-b)

Опция --buildpkg (-b), и это ясно из ее названия, предназначена для создания таких автономных бинарных пакетов. Она требует исключительно ebuild-аргумента (аргументов) - построить пакета для класса system или world, к сожалению, на текущий момент нельзя. Не создаются ею и автономные бинарники для пакетов, с которыми заказанный связан зависимостями. Однако все остальное - получение исходников, их распаковку, компиляцию, установку во временный каталог и итоговую сборку файла *.tbz2), - она производит вполне исправно.

Собранные бинарные пакеты по умолчанию располагаются в каталоге /usr/portage/packages/All; кроме того, в каталогах /usr/portage/packages/имя_категории на них создаются символические ссылки.

После того, как автономный бинарный пакет создан, его следует установить. И именно для этого предназначена опция --usepkg (-k), в качестве аргумента которой указывается tbz2file. Ее указание приводит к тому, что бинарный архив разворачивается, и его компоненты встраиваются в соответствующие ветви файловой системы (в /usr/bin - исполнимые файлы, в /usr/lib - разделяемые библиотеки, в /usr/share/man - страницы документации, и т.д.).

С помощью команды emerge --usepkg устанавливаются прекомпилированные бинарные пакеты, распространяемые с текущим релизом Gentoo. Поскольку они уже оптимизированы для основных типов архитектур, их использование способствует как быстродействию системы, так и экономии времени при ее развертывании.

Опции --buildpkg (-b) и --usepkg (-k) могут использоваться совместно. В этом случае заказанные пакеты сначала будут собраны в виде автономных архивов *.tbz2, а затем инкорпорированы в файловую систему. Именно это рекомендуется сделать при построении собственной системы, оптимизированной, с одной стороны, под данную архитектуру, с другой - способную к автономному распространению:

$ emerge -bk xfree kde gnome openoffice-bin mozilla