Добавить в избранное | Сделать стартовой страницей

Большая Linux библиотека для пользователей OS Linux и ПО для нее
Есть что сказать? Нужен совет? Посети наш форум.




Как собираются Linux'ы.

Автор : Алексей Федорчук

В одной из недавних своих заметок  [1] я рассматривал вопрос, из чего же сделаны Linux'ы. Как оказалось – из очень немногого, полусотни пакетов, обеспечивающих, с одной стороны, функционирование системы «в себе» и «для себя», с другой – позволяющих выполнять внутри этой системы некоторые пользовательские задачи, и совсем не обязательно – элементарные; плюс к чему – дающих возможность практически неограниченного наращивания системы.

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

Иными словами, пред пользователем встает, как призрак отца Гамлета, один из вечных вопросов – что первично, курица или яйцо. Конечно, для пользователя пакетного дистрибутива вопрос этот, можно сказать, выеденного яйца не стоит. Ведь некий добрый дядя уже решил его в меру своего разумения, неким (не суть важно, каким) образом собрав бинарные пакеты, которые остается только развернуть, используя прилагаемые штатные средства – будь то rpm, apt-get или что иное.

А как решается вопрос яйца и курицы в дистрибутивах Source Based, в которых все компоненты по определению а) должны собираться из исходников, и б) под полным (в идеале) контролем со стороны пользователя)? Как легко догадаться – по разному. И дистрибутивы, рассмотренные нами ранее на этих страницах, демонстрируют несколько примеров решения сакраментальной проблемы.

Начнем с Gentoo – не потому, что он был первым в нашем списке  [2], а поскольку подход его наиболее традиционен. Действительно, здесь все базовые компоненты просто-напросто разворачиваются из трех прекомпилированных тарбаллов, примерно так же, как это происходит в его прототипе – FreeBSD (с той лишь разницей, что в последнем случае базовые тарбаллы нарезаны на большое количество мелких файлов – дань эпохе, когда большинству пользователей во всем мире о быстром коннекте приходилось только мечтать). Правда, лишь первый из штатных тарбаллов устанавливается с фатальной неизбежностью – два прочих могут быть синхронизированы с их последними версиями на сайте, актуализированы и пересобраны (с заданным уровнем оптимизации) уже на стадии инсталляции. При наличии подключения к Сети, разумеется.

Иной подход реализуется в дистрибутиве Sorcerer и его производных (одним из которых является описанный ранее SourceMage  [3]). Здесь прекомпилированные базовые компоненты системы «в лоб» переписываются с инсталляционного диска, который представляет собой не просто LiveCD, а полноценную рабочую систему (включающую, помимо прочего, все необходимое для сборки программ). А первое, что предлагается сделать после установки – это полный их rebuild, выполняемый в автоматическом режиме штатной утилитой sorcery. И действительно, она волшебным образом позволяет пересобрать весь набор base Linux в соответствии с настройками, заданными пользователем (вплоть до оптимизации под конкретный процессор в экстремальном режиме). Правда, и здесь очень желательно подключение к Сети, хотя есть и альтернатива – предварительное скачивание исходников этого самого base и их размещение в должном месте.

Третий подход мы видим в LRs-Linux  [4]. Здесь не найти ни одного прекомпилированного пакета, все, от base Linux до XFree86, собирается, казалось бы, с нуля, в соответствие с выбором пользователя и его установками (вплоть до экстремальной оптимизации). Однако если во время этого процесса (весьма длительного) не дремать, а попивать пиво, посматривая на экран, можно обратить внимание, что ряд компонентов базового набора (таких, как gcc и средства его поддержки, объединенные в пакет binutils, например) собирается дважды – в самом начале установки и ближе к ее завершению.

Причина этого явления становится понятной из великого мемуара Герарда Бикманса Linux from Scratch (LFS  [5]). И действительно, ведь все компоненты base Linux требуют для своего функционирования поддержки со стороны системных библиотек (как минимум, glibc), с коими они могут быть слинкованы как динамически, так и статически. Для рабочей Linux-системы традиционным является первый способ связывания (что имеет глубокое внутреннее обоснование, на котором я здесь задерживаться не буду). Однако в момент инсталляции корневая файловая система, таковую обеспечивающая, не существует реально (располагаясь на виртуальном диске в оперативной памяти). И потому конфигурирование исходников отыскивает линкуемые компоненты относительно оной (а не той файловой системы, которая будет корневой после установки). А в результате попытка динамической линковки компонентов base Linux приведет к тому, что после перезапуска системы требуемые библиотеки просто не будут найдены.

Как же решает проблему «курицы и яйца» сам автор LFS? Да именно двухэтапностью сборки. Сначала под управлением любой ранее установленной Linux-системы возводится, так сказать, «нулевой цикл». Он включает в себя создание и монтирование специального раздела для новой системы, разворачивание в нем архивов исходников и компиляцию «системы жизнеобеспечения»: оболочки bash, средств сборки (gcc, binutils, make) и работы с файлами (fileutils, grep, gawk, архиватор tar и компрессоры gzip, bzip2). Все они статически линкуются с библиотекой glibc материнской системы, а в качестве префиксного каталога при сборке выступает точка монтирования раздела для системы дочерней. Порядок сборки при этом не имеет значения – она обеспечивается средствами материнского Linux'а (хотя, теоретически рассуждая, собрать систему from Scratch можно, вероятно, и под управлением FreeBSD). Нет необходимости и в оптимизации компилируемых пакетов – все равно они будут пересобраны в ходе второго цикла.

Каковой начинается с определения дочернего каталога как корневого (командой chroot). В нем, с опорой на новообразованные gcc и средства его поддержки, собирается библиотека glibc. А потом – сборка (и пересборка) абсолютно всех компонентов base Linux, которые теперь динамически линкуются с glibc дочерней системы. На этот раз сборка происходит уже в определенном порядке, более или менее жестко задаваемом зависимостями компонентов base Linux. Так, например, очевидно, что терминальная библиотека ncurses должна компилироваться раньше, чем использующий ее редактор vim. Ну и, конечно, при сборке следует задать все требуемые опции оптимизации – не ради этого ли затевалась вся катавасия?

Интересно, что ядро системы должно быть собрано во время «нулевого цикла». Казалось бы, необходимости в этом нет – второй цикл начинается без перезагрузки системы и также обеспечивается ядром материнской системы. Для его правильного выполнения требуются заголовочные файлы ядра системы дочерней, и пути к ним отсчитываются от корневого каталога последней. Однако, если компилятор материнской системы не позволяет задать требуемого уровня оптимизации (например, оптимизация под Pentium-4 по уму поддерживается только начиная с gcc версии 3.1), никто не помешает пересобрать ядро в ходе второго цикла.

Завершающие штрихи – установка средств загрузки системы, в том числе стартовых сценариев, и их конфигурирование. Каковое призвано обеспечить перезагрузку уже в дочерней системе – средствами Lilo, GRUB или иного мультисистемного загрузчика.

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

Собственно говоря, LRs-Linux и представляет из себя попытку такой «дистрибутивизации» LFS. Недостаток ее – в достаточно жесткой программе установки, не позволяющей ни вернуться к какой-либо из пройденных стадий, ни напротив, пропустить одну из грядущих. Фактически, при любой ошибке установку LRs приходится начинать почти заново.

Однако сама по себе установка компонентов LFS не требует никакой программы инсталляции. Для ее успешного выполнения достаточно (и – необходимо):

  • загрузочного CD (изготовленного, например, средствами syslinux), обеспечивающего корневую файловую систему оперативной памяти;
  • размещения на нем средств компиляции и ее обеспечения – то есть, в сущности, полноценной RAM-based системы;
  • исходных текстов base Linux (и – любых дополнительных компонентов, хотя последние и не обязаны располагаться на установочном диске);
  • подробной (и доступной во время установки) экранной документации с примерами действий в типичных обстоятельствах.

При выполнении этих условий все действия по сборке могут быть выполнены любым пользователем с должным опытом работы в Unix-системах. Кроме того, потребуется время – существенно большее, чем для развертывания пакетного дистрибутива, достаточно мощной машины с изрядным объемом памяти и большим диском (иначе требуемое время грозит приобрести астрономический масштаб), и, конечно же, интерес к процессу. Взамен предлагается – оптимизация системы для конкретного «железа» и конкретных задач, полная свобода в выборе стартовых скриптов – и не обязательно писать их с нуля собственноручно, достаточно адаптировать любую подходящую из существующих схем.

Возникает вопрос – а кому и за каким такой дистрибутив нужен? Ясно, что не конечному пользователю, цель которого – скорейшее начало работы в офисном пакете. С другой стороны, и системный администратор, сколь бы опытен и квалифицирован ни был, при необходимости развертывания сети на сотни рабочих мест, предпочтет быстроту развертывания пакетной системы – сисадмины ведь тоже люди, и ничто человеческое им не чуждо. Иными словами, такая система собирается один раз, и только для себя, любимого. Подобно лошади, взятой жеребенком, которого растишь в собственном доме, кормишь с руки, кутаешь в морозы в свой тулуп.

Однако две сферы применения дистрибутива штучной сборки я вижу. Первая это системы под одну задачу, причем ресурсоемкую, где требуется быстродействие любой ценой. Например, счетные задачи т.н. инженерно-научного характера, ГИС и имидж-процессинг, 3D-рендеринг, и т.д.

А вторая сфера приложения систем штучного разбора – образовательная. Причем не только (и даже не столько) для тех, кто образовывается – их целью подчас может быть получение базовых практических навыков. Но и, вероятно, в первую очередь, для тех, кто образовывает. Ведь для того, чтобы передать те самые базовые практические навыки, им потребуется понимание их подоплеки: ведь «чем больше число дистрибутивов, их версий и, вообще, программных продуктов, тем труднее запастись конкретными рекомендациями на все случаи жизни»  [6].


[1] http://www.softerra.ru/freeos/19466/ [обратно к тексту]

[2] О дистрибутиве Gentoo – http://www.softerra.ru/freeos/18909/ [обратно к тексту]

[3] О дистрибутиве SourceMage – http://www.softerra.ru/freeos/19247/. От своего прототипа – Sorcerer (http://sorcerer.wox.org) он отличается лишь некоторыми непринципиальными деталями. [обратно к тексту]

[4] О дистрибутиве LRs-Linux – http://www.softerra.ru/freeos/19045 [обратно к тексту]

[5] http://www.linuxfromscratch.org. [обратно к тексту]

[6] Владимир Попов. Init... etc. – http://www.softerra.ru/freeos/19771. [обратно к тексту]


Обсудить данную тему на нашем форуме "Все о Linux"