Valery Vachaev
2006-11-28
Проект LFS (Linux from scratch – текущий стабильный релиз 6.2),ставший достаточно популярным в последнее время, предназначен в основном для тех кто попав в мир Linux хочет узнать больше об этой операционной системе, о составляющих ее компонентах и способах оптимизации. Фактически, LFS проект является подробным описанием-инструкцией (LFS-книга другое название от авторов проекта) по сборке операционной системы из пакетов с исходными текстами. Упомянутая книга содержит последовательное описание компиляции и установки каждого пакета включая опции конфигурации и инсталляции, необходимые “заплаты”. Для достижения цели - создания загружаемой базовой операционной системы без поддержки графической подсистемы, пользователю необходимо пройти три основных этапа:
Наиболее трудоемким этапом является второй, на котором непосредственно компилируются
и устанавливаются около 50 различных пакетов, которые и создают базовое окружение для
ядра Linux. Наличие такого количества пакетов вызывает естественное желание применить
менеджер пакетов, что во-первых, позволит впоследствии легко модернизировать базовую
систему, а во-вторых, использование менеджера, как правило, позволяет
автоматизировать процесс сборки системы из пакетов. Авторы проекта также приветствуют
использование системы управления пакетами, но выбор соответствующего менеджера
является прерогативой пользователя. Причина (и уважительная на мой взгляд) -
акцентировать внимание пользователей именно на сборке системы, так как это
является главной задачей проекта.Существуют несколько предложений по использованию
системы управлениями пакетами в LFS, подробное описание которых можно найти в
так называемых хинтах проекта. Например:
package_management_using_trip.txt
more_control_and_pkg_man.txt
rpm.txt
fakeroot.txt
Лично я, попробовав несколько менеджеров пакетов, остановился на pacman, являющимся ядром Arch Build System (ABS) - системе сборки пакетов для операционной системы Arch Linux. Если использовать самое общее определение для ABS, то можно сказать что это менеджер пакетов pacman плюс набор скриптов и правил их создания. Но если pacman является "ответственным" за доставку, установку бинарников и ведение базы данных пакетов, то целью «скриптовой» части системы является создание пакетов из исходников. Нужно также добавить, характеризуя ABS, что это простая, ясно построенная и в тоже время достаточно мощная система. Ну и нельзя не упомянуть, что автором ABS и основателем проекта Arch Linux является Judd Vinet. Более детальную информацию об Arch Linux, pacman и ABS вы можете найти на сайте Arch Linux а также в статьях А.Федорчука на страницах сайта posix.ru: Установка Archlinux: гармония гибкости и простоты. Pacman. Управление пакетами в Archlinux и не только. Archlinux Building System. Портирование портов.
Что-бы понять каким образом мы можем использовать pacman для наших целей, давайте
рассмотрим процесс сборки пакета в Arch Linux. Как известно, одним из компонентов
ABS является так называемое «дерево» ABS – структура каталогов и файлов произрастающее
обычно из каталога /usr/abs и включающее каталоги, соответствующие группам пакетов,
которые в свою очередь содержат подкаталоги, соответствующие конкретным пакетам.
Каждый такой подкаталог идентифицирующий пакет обязательно содержит как минимум
один файл PKGBUILD а также, если это необходимо, другие файлы - «заплаты», файлы
конфигурации и т.д. Так например, каталог /usr/abs/base/tar содержит следующие файлы:
PKGBUILDДавайте взглянем на содержимое файла PKGBUILD:
heap-overflow.patch
tar.1
# $Id: PKGBUILD,v 1.16 2006/10/24 07:16:42 tpowa Exp $
# Maintainer: judd
pkgname=tar
pkgver=1.16
pkgrel=1
pkgdesc="Utility used to store, backup, and transport files"
arch=(i686 x86_64)
url="http://www.gnu.org/software/tar/tar.html"
depends=('glibc' 'bash')
source=(ftp://ftp.gnu.org/gnu/$pkgname/$pkgname-$pkgver.tar.gz \
heap-overflow.patch \
tar.1)
md5sums=('bb9d2a5b87d0ad825fb9d34e1617325d')
build() {
cd $startdir/src/$pkgname-$pkgver
patch -Np0 -i ../heap-overflow.patch || return 1
./configure --prefix=/usr --libexecdir=/usr/lib/tar --bindir=/bin
make || return 1
make DESTDIR=$startdir/pkg install
install -D -m644 ../tar.1 $startdir/pkg/usr/man/man1/tar.1
}
Нетрудно заметить, что файл представляет из себя скрипт, где в первой части переменным
присваиваются параметры текущего пакета такие как имя, номер релиза, источник (URL)
и т.д., а вторая часть, начинающаяся с ключевого слова build, является функцией
реализующей процесс конфигурирования, компиляции и инсталляции пакета в промежуточный
каталог DESTDIR. Для того, чтобы собрать пакет из исходников, пользователь Arch Linux
должен сделать каталог пакета текущим и затем запустить на выполнение скрипт makepkg
без параметров. Вначале makepkg проверяет наличие пакета с исходными текстами в
кеше /var/cache/pacman/src и, если исходники не обнаружены делается попытка получить
их через pacman, который в свою очередь использует для этих целей wget. После того
как пакет с исходниками доставлен, makepkg создает два подкаталога src и pkg в
текущем каталоге пакета. Как следует из их названий, первый предназначен для
распакованных исходников а второй является целевым установочным каталогом DESTDIR
для будущего процесса инсталляции пакета. Итак, если:
а) пакет с исходниками доставлен (или уже положен в кеш) и распакован в каталог src;makepkg производит вызов функции build для того чтобы получить компоненты пакета в каталоге DESTDIR. Ну и последней фазой процесса является архивирование и компрессия компонентов пакета из вышеупомянутого каталога в тарбалл pkg_name_release.pkg.tar.gz. Для установки пакета в систему нужно добавить опцию -i в вызов makepkg или явно вызвать менеджер пакетов:
b) дополнительные файлы существуют и положены в каталог src;
c) «жесткие» зависимости разрешены ( т.е. пакеты, перечисленные в массиве depends установлены в системе),
Теперь давайте рассмотрим типичный процесс сборки и установки пакета в LFS:
1. Распаковка в рабочую директорию.
2. Наложение «заплат» и/или внесение изменений в некоторые файлы, если в этом есть необходимость.
3. Конфигурирование пакета (вызов скрипта configure с определенными опциями).
4. Компиляция пакета(вызов утилиты make).
5. Инсталляция пакета (вызов утилиты make с опцией «install»).
6. Выполнение дополнительных действий, таких как создание символьных ссылок, удаление или перемещение файлов в различные директории и т.д.
Вот конкретный пример создания и установки пакета readline, взятый мной из LFS книги версии 6.2(6.23.1. Installation of Readline).
Upstream developers have fixed several issues since the initial release of Readline-5.1. Apply those fixes:
patch -Np1 -i ../readline-5.1-fixes-3.patch
Reinstalling Readline will cause the old libraries to be moved to .old. While this is
normally not a problem, in some cases it can trigger a linking bug in ldconfig. This can be avoided
by issuing the following two seds:
sed -i '/MV.*old/d' Makefile.in
sed -i '/{OLDSUFF}/c:' support/shlib-install
Prepare Readline for compilation:
./configure --prefix=/usr --libdir=/lib
Compile the package:
make SHLIB_LIBS=-lncurses
The meaning of the make option:
SHLIB_LIBS=-lncurses
This option forces Readline to link against the libncurses (really, libncursesw) library.
This package does not come with a test suite.
Install the package:
make install
Give Readline's dynamic libraries more appropriate permissions:
chmod -v 755 /lib/lib{readline,history}.so*
Now move the static libraries to a more appropriate location:
mv -v /lib/lib{readline,history}.a /usr/lib
Next, remove the .so files in /lib and relink them into /usr/lib:
rm -v /lib/lib{readline,history}.so
ln -sfv ../../lib/libreadline.so.5 /usr/lib/libreadline.so
ln -sfv ../../lib/libhistory.so.5 /usr/lib/libhistory.so
Без особых усилий этот скрипт трансформируется в PKGBUILD скрипт:
pkgname=readline
pkgver=5.1
pkgrel=1
pkgdesc="A set of libraries that offers command-line editing and history \ capabilities"
arch=(i686 x86_64)
url="http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html"
depends=('glibc' 'bash')
source=( http://ftp.gnu.org/gnu/readline/readline-5.1.tar.gz \
heap-overflow.patch \
tar.1)
md5sums=('7ee5a692db88b30ca48927a13fd60e46')
build() {
cd $startdir/src/$pkgname-$pkgver
patch -Np1 -i ../readline-5.1-fixes-3.patch || return 1
sed -i '/MV.*old/d' Makefile.in
sed -i '/{OLDSUFF}/c:' support/shlib-install
./configure --prefix=/usr --libdir=/lib
make SHLIB_LIBS=-lncurses
make DESTDIR=$startdir/pkg install
# Give Readline's dynamic libraries more appropriate permissions:
chmod -v 755 $startdir/pkg/lib/lib{readline,history}.so*
# Now move the static libraries to a more appropriate location:
mkdir -pv $startdir/pkg/usr/lib
mv -v $startdir/pkg/lib/lib{readline,history}.a $startdir/pkg/usr/lib
# Next, remove the .so files in /lib and relink them into /usr/lib:
rm -v $startdir/pkg/lib/lib{readline,history}.so
cd $startdir/pkg/usr/lib
ln -sfv ../../lib/libreadline.so.5 libreadline.so
ln -sfv ../../lib/libhistory.so.5 libhistory.so
}
Таким образом, суммируя все вышесказанное, для того чтобы использовать пакетный
менеджер pacman для управления пакетами в LFS системе, необходимо:
1. Скачиваем дополнительные исходники, необходимые для работы pacman'а и кладем их директорию sources.
Pacman можно скачать отсюда,
libtar берем здесь,
"заплата" для libtar здесь.
2. Создаем каталог lfsbs-6.2 (LinuxFromScratchBuildSystem) и подкаталоги с именами пакетов.
3. Для каждого пакета в соответствующем подкаталоге создаем файл PKGBUILD и заполняем его. Если для пакета существуют «заплаты», также копируем их в подкаталог. Готовые PKGBUILD файлы для стабильного релиза 6.2 можно взять здесь.
4. Выполняем сборку минимальной системы в соответствии с LFS-book пункты 5.1 – 5.30.
5. Устанавливаем три дополнительных пакета zlib, libtar и pacman.
zlib-1.2.3
./configure --prefix=/tools
make
make install
libtar-1.2.11
patch -Np1 -i ../patches/libtar-1.2.11-2.patch
./configure
make
make install
pacman-2.9.8
./configure
make
cp -v pacman scripts/makepkg /tools/bin
cp -v etc/{makepkg,pacman}.conf /tools/etc
В файле /tools/etc/makepkg.conf устанавливаем следующие опции:6. Выполняем пункты 6.1 – 6.6 LFS-книги
7. Создаем каталог /var/cache/pacman/src и копируем туда пакеты с исходникам.
8. Начиная с пункта 6.7 компилируем и устанавливаем пакеты используя подготовленные для этого файлы BUILDPKG:
cd имя_пакета
makepkg -icd -w имя_каталога_для_хранения_пакетов
где опции:
i - инсталлировать собранный пакет
c - удалить временные файлы
d - запретить проверку зависимостей для makepkg, так как пакеты в систему устанавливаются первый раз.
w – устанавить каталог для хранения бинарных пакетов.
9. После пункта 6.57 устанавливаем libtar и pacman точно также как в предыдущем пункте.
10. Продолжаем установку в соответствии с LFS книгой.
Для автоматизированной сборки системы (пункты 6.1-6.57 LFS книги) я использую набор
скриптов, которые находятся в архиве здесь .
Скрипт a1_chroot.sh предназначен для смены корневого каталога. (п.п.6.1-6.4).
Скрипт a2_mkdir.sh создает каталоги, файлы и ссылки (п.п. 6.5-6.6).
Скрипт a3_init_bs.sh создает временные каталоги для сборки системы, устанавливает
переменные, копирует исходники в /var/cache/pacman/src а также создает структуру
каталогов соответствующую устанавливаемым пакетам в /usr/lfsbs.
Скрипт a4_chroot_2.sh предназначен для повторной смены корневого каталога.
Для сборки пакетов используются скрипты b1_xxxxx.sh – b7_xxxxx.sh.
Если конкретизировать процесс сборки по шагам в предположении, что мы имеем раздел с минимальной системой в каталоге $LFS/tools и каталог с исходникам в $LFS/sources, то это будет выглядеть так:
1. Создаем каталог temp и кладем туда скрипты a1_xxx.sh – a4_xxx.sh.
2. Копируем файл lfsbs-6.2.tar.gz в каталог sources.
3. Запускаем скрипт a1_chroot.sh и оказываемся в новом окружении на самом верхнем уровне дерева каталогов.
4. Меняем текущий каталог на /temp.
5. Запускаем скрипт a2_mkdir.sh.
6. Запускаем скрипт a3_init_bs.sh.
Теперь мы имеем дерево каталогов в /usr/lfsbs и можем начать сборку системы.
7. Запускаем скрипты:
b1_build.sh
b2_glibc_post.sh
b3_gcc.sh
b4_build.sh
b5_shadow_post.sh
b6_build.sh
b7_pacman.sh
и контролируем ход сборки и инсталляции пакетов. Так после исполнения скриптов
b2 и b3 следует проверить правильность установки пакетов как это описано в пп. 6.10
и 6.12 соответственно. После исполнения скрипта b7 устанавливаем опции в файле
$LFS/etc/makepkg.conf как было описано выше.