21 мар. 2009 г.

Linux: Apt-build - Пересобираем World ("мир") и управляем пакетами из исходников в Debian/Ubuntu

Apt-build - мощный инструмент Debian, позволяющий в духе FreeBSD (ну, или Gentoo например) одной командой устанавливать пакеты из исходных текстов (вместо унылого ./configure-make-sudo make install), пересобирать уже установленные пакеты с оптимизацией под используемую архитектуру а также, при наличии желания, пересобрать систему целиком.





# Установка/настройка

panzer@pnz-lin:~$ sudo apt-get install apt-build

В процессе установки будет задано несколько вопросов:

1. Каталог, в который будут качаться исходники и где будут собираться пакеты. По умолчанию это:
/var/cache/apt-build/build

2. Локальный репозиторий, в который сохраняются собранные пакеты. По умолчанию:
/var/cache/apt-build/repository

3. Уровень оптимизации. Лёгкая, средняя, усиленная (CFLAGS -01, -02, -03). По умолчанию предлагается -02

4.Прочие параметры для компиляции. Их в общем случаем можно оставить без изменения.

5. Затем будет предложено добавить строку "deb file:/var/cache/apt-build/repository apt-build main" в /etc/apt/sources.list Не стоит от этого отказываться. Более того, строка должна быть первой в списке репозиториев (критично!).

6. Тип используемого процессора. Думаю, с этим всё понятно.

На этом конфигурирование apt-build закончено. Если в чём-то неуверены, можно просмотреть настройки в файле /etc/apt/apt-build.conf

build-dir = /var/cache/apt-build/build
repository-dir = /var/cache/apt-build/repository
Olevel = -O2
mtune = -mtune=k8
options = "-pipe -fomit-frame-pointer "
make_options = "-j4 "

И либо изменить вручную, либо запустить конфигурирование повторно, используя команду:
panzer@pnz-lin:~$ sudo dpkg-reconfigure apt-build

С первым этапом разобрались. Идём дальше.

Устанавливаем всё необходимое для сборки (на всякий случай, вдруг чего-либо недостаёт):

panzer@pnz-lin:~$ sudo apt-get install libc6-dev g++ gcc

Кроме этого не помешает установить и запустить pbuilder (он может пригодится в ряде случаев, о чём apt-build скажет сам):
panzer@pnz-lin:~$ sudo apt-get install pbuilder && /usr/lib/pbuilder/pbuilder-satisfydepends

! Сразу хочу сказать, что несколько операций с apt-build требуют root-полномочий. Именно root, а не sudoers. Например, при попытке построить индекс пакетов можно наблюдать такую картину:

panzer@pnz-lin:~$ sudo dpkg --get-selections | awk '{if ($2 == "install") print $1}' > /etc/apt/apt-build.list
bash: /etc/apt/apt-build.list: Permission denied

Поэтому тем пользователям Ubuntu, у которых отключена учётная запись root (а по-умолчанию она отключена) рекомендуется включить её и задать пароль. Всё это можно сделать одной командой:
panzer@pnz-lin:~$ sudo passwd root
Введите новый пароль UNIX:

После этого логинимся под root:
panzer@pnz-lin:~$ su
Пароль:

И строим индекс пакетов:
root@pnz-lin:/home/panzer# dpkg --get-selections | awk '{if ($2 == "install") print $1}' > /etc/apt/apt-build.list

На этом предварительное конфигурирование закончено, и можно переходить к использованию.

# Использование

Использование apt-build в общем и целом идентично использованию apt-get:
------------------------------------------------------------------------------
apt-build [options] [command]

Commands:
update - Update package lists
upgrade - Perform an upgrade
install - Build and install new packages
source - Download and extract source in build directory
build-source - Download, extract and build source package
update-source - Update all sources and rebuild them
remove - Remove packages
build-repository - Rebuild the repository
clean-sources - Clean up all object files in source directories
clean-build - Erase downloaded packages and temporary build files
clean-repository - Erase downloaded packages and temporary build files
world - Rebuild and reinstall all packages on your system
info - Build-related package information
------------------------------------------------------------------------------
Поэтому первым делом обновляемся:

panzer@pnz-lin:~$ sudo apt-build update && sudo apt-build upgrade
-----> Updating package lists <-----
(Вывод опущен)

Само собой, в /etc/apt/sources.list должны быть подключены репозитории с исходными текстами (те, которые "deb-src http://и т.д."). В Ubuntu они уже присутствуют и их необходимо лишь раскомментировать. В Debian я использую вот эти репозитории:

deb-src http://security.debian.org/ etch/updates main contrib
deb-src http://mirror.yandex.ru/debian stable main
deb-src http://mirror.yandex.ru/debian/ etch main
deb-src http://mirror.yandex.ru/debian etch main non-free contrib
deb-src http://mirror.yandex.ru/debian-security etch/updates main non-free contrib

Надо сказать, что 99,9% случаев основные команды apt-build требуют дополнительных опций:
------------------------------------------------------------------------------
Options:
--reinstall - Re-build and install already installed package
--rebuild - Rebuild package
--remove-builddep - Remove build-dependencies installed by apt-build
--nowrapper - Do not use gcc/g++ wrapper
--purge - Use purge instead of remove
--noupdate - Do not run 'apt-get update' before package installation
--build-command - Use to build package
--patch - Apply patch s before the build
--patch-strip - Striplevel for the patch files
--yes -y - Assume yes
--version -v - Show version and exit
--force-yes - Force yes
--source - Do not download source (sources are extracted already)
--build-only - Do not install any of build dependencies
--build-dir - Specify build dir
--repository-dir - Specify the repository directory
--target-release - Distribution to fetch packages from
--sources-list - Specify sources.list file
--apt-get - Specify an alternative apt-get application to use
--apt-cache - Specify an alternative apt-cache application to use
--config - Specify an alternative configuration file
------------------------------------------------------------------------------
Например, чтобы переустановить из исходников уже установленный пакет, нам понадобится следующая директива:
panzer@pnz-lin:~$ sudo apt-build --rebuild --reinstall --force-yes --yes install mc
-----> Installing build dependencies (for mc) <-----
Чтение списков пакетов... Готово
Построение дерева зависимостей
Чтение информации о состоянии... Готово
(Вывод опущен)
-----> Building mc <-----
dpkg-buildpackage: установка CFLAGS в значение по умолчанию: -g -O2
dpkg-buildpackage: установка CPPFLAGS в значение по умолчанию:
dpkg-buildpackage: установка LDFLAGS в значение по умолчанию: -Wl,-Bsymbolic-functions
dpkg-buildpackage: установка FFLAGS в значение по умолчанию: -g -O2
dpkg-buildpackage: установка CXXFLAGS в значение по умолчанию: -g -O2
dpkg-buildpackage: пакет исходных текстов mc
dpkg-buildpackage: версия исходных текстов 2:4.6.2~git20080311-2
dpkg-buildpackage: исходные тексты изменены root
dpkg-buildpackage: архитектура хоста i386
debian/rules clean
(И т.д.)

В процессе установки/пересборки apt-build сам скачивает нужные ему для компиляции пакеты, поэтому не удивляемся, увидев нечто подобное этому:

---------------------------------------------------------------------------------------------------------------------------------------
-----> Installing build dependencies (for kdesdk) <-----
Чтение списков пакетов... Готово
Построение дерева зависимостей
Чтение информации о состоянии... Готово
НОВЫЕ пакеты, которые будут установлены:
automoc binutils-dev cdbs cmake fdupes hspell kdelibs5-dev kdepimlibs5-dev kdesdk-scripts libacl1-dev libapr1-dev libaprutil1-dev
libasound2-dev libattr1-dev libboost-date-time-dev libboost-date-time1.34.1 libboost-dev libboost-doc libboost-filesystem-dev
libboost-filesystem1.34.1 libboost-graph-dev libboost-graph1.34.1 libboost-iostreams-dev libboost-program-options-dev
libboost-program-options1.34.1 libboost-python-dev libboost-regex-dev libboost-serialization-dev libboost-serialization1.34.1
libboost-signals-dev libboost-signals1.34.1 libboost-test-dev libboost-test1.34.1 libboost-thread-dev libboost-thread1.34.1
libboost-wave-dev libboost-wave1.34.1 libbz2-dev libcups2-dev libdb4.6-dev libgif-dev libgpgme11-dev libicu-dev libilmbase-dev
libjasper-dev libkeyutils-dev libldap2-dev libmysqlclient15-dev libopenexr-dev libphonon-dev libplasma-dev libpth-dev libsasl2-dev
libsoprano-dev libsqlite3-dev libstreamanalyzer-dev libstreams-dev libsvn-dev libtiff4-dev libtiffxx0c2 libxslt1-dev python-dev
python2.5-dev quilt uuid-dev
---------------------------------------------------------------------------------------------------------------------------------------

В конце установки/пересборки apt-build напомнит, что нужно удалить пакеты, использовавшиеся для сборки:

---------------------------------------------------------------------------------------------------------------------------------------
Чтение списков пакетов... Готово
Построение дерева зависимостей
Чтение информации о состоянии... Готово
Следующие пакеты устанавливались автоматически и больше не требуются:
automoc binutils-dev cdbs cmake fdupes hspell kdelibs5-dev kdepimlibs5-dev kdesdk-scripts libacl1-dev libapr1-dev libaprutil1-dev
libasound2-dev libattr1-dev libboost-date-time-dev libboost-date-time1.34.1 libboost-dev libboost-doc libboost-filesystem-dev
libboost-filesystem1.34.1 libboost-graph-dev libboost-graph1.34.1 libboost-iostreams-dev libboost-program-options-dev
libboost-program-options1.34.1 libboost-python-dev libboost-regex-dev libboost-serialization-dev libboost-serialization1.34.1
libboost-signals-dev libboost-signals1.34.1 libboost-test-dev libboost-test1.34.1 libboost-thread-dev libboost-thread1.34.1
libboost-wave-dev libboost-wave1.34.1 libbz2-dev libcups2-dev libdb4.6-dev libgif-dev libgpgme11-dev libicu-dev libilmbase-dev
libjasper-dev libkeyutils-dev libldap2-dev libmysqlclient15-dev libopenexr-dev libphonon-dev libplasma-dev libpth-dev libsasl2-dev
libsoprano-dev libsqlite3-dev libstreamanalyzer-dev libstreams-dev libsvn-dev libtiff4-dev libtiffxx0c2 libxslt1-dev python-dev
python2.5-dev quilt uuid-dev
Для их удаления используйте 'apt-get autoremove'.
---------------------------------------------------------------------------------------------------------------------------------------

Свидетельством удачной установки/пересборки будет следующее:

---------------------------------------------------------------------------------------------------------------------------------------
обновлено 0, установлено 0 новых пакетов, переустановлено 1 переустановлено, для удаления отмечено 0 пакетов, и 0 пакетов не обновлено.
(Чтение базы данных... на данный момент установлено 247145 файлов и каталогов.)
Подготовка к замене пакета gimp 2.6.3-1ubuntu1~intrepid1 (используется файл .../gimp_2.6.3-1ubuntu1~intrepid1_i386.deb)...
Распаковывается замена для пакета gimp ...
Обрабатываются триггеры для man-db ...
Обрабатываются триггеры для menu ...
Настраивается пакет gimp (2.6.3-1ubuntu1~intrepid1) ...
Обрабатываются триггеры для menu ...
Обрабатываются триггеры для libc6 ...
ldconfig deferred processing now taking place
---------------------------------------------------------------------------------------------------------------------------------------

Тоже самое для установки пакета:
panzer@pnz-lin:~$ sudo apt-build install --yes --force-yes gpicview

Иными словами, ключи "--yes --force-yes" - это то, что нужно использовать постоянно.

# "Замораживаем" пакеты

Для того, чтобы собранные нами пакеты не были заменены обычными версиями при первом же обновлении, необходимо их "заморозить".
Для этого существует два способа. Первый из них описан в документации к apt-build и заключается в внесении в файл /etc/apt/preferences сведений о "замороженных" пакетах в таком формате::

Package: * (обязательно в формате "имя-версия")
Pin: release o=apt-build
Pin-Priority: 990

Второй способ - специально для любителей "экстрима". Особенно пригодится для тех пакетов, пересобирать которые мы не планируем ещё долго.
-> С помощью apt-build source качаем исходники нужного пакета.
-> Перемещаемся в каталог с исходниками
-> Набираем:
root@pnz-lin:/var/cache/apt-build/build/gpicview-0.1.10# dch -i

Меняем версию на бОльшую. Сохраняемся. Собираем/ставим пакет. После этого "морозим" версию:
panzer@pnz-lin:~$ sudo aptitude hold gpicview

# Пересборка системы:

В общем и целом для полной пересборки системы понадобится всего одна команда:
panzer@pnz-lin:~$ apt-build world

Однако ньюанс заключается в том, что во-первых, не всё ПО, установленное на машине является свободным, и во-вторых, даже будучи свободным, для того или иного пакета могут отсутствовать прописанные в /etc/apt/sources.list репозитории с исходниками. В этом случае весь процесс пересборки остановится на таком пакете. Чтобы этого не случилось, нужно отредактировать файл /etc/apt/apt-build.list, исключив из него проприетарное ПО и ПО с отсутствующими в пределах досягаемости apt-build репозиториями исходных текстов. Ну а после этого запускать apt-build world и ждать. Долго и мучительно:-)

По окончании процесса перезагружаемся и делаем:
apt-build upgrade

# Очистка

И наконец, не забываем очищать соответствующие каталоги от исходников и собранных пакетов, т.к. при постоянном использовании apt-build они отъедают значительный объём дискового пространства:
panzer@pnz-lin:~$ sudo apt-build clean-sources && apt-build clean-repository


# Вместо заключения

Apt-build на мой взгляд является полезной и интересной утилитой.
В качестве заключения опишу несколько важных моментов, связанных с её использованием.

->Плюсы:
Плюсы очевидны: поскольку при установке/пересборке пакеты компилируются под конкретную архитектуру, увеличение быстродействия видно невооружённым глазом (точных замеров производительности не делал, извините уж:-))

->Минусы:
Компиляция занимает гораздо больше времени, нежели чем обычная установка через apt-get install. Тоже самое можно сказать и о пересборке. Поэтому следует запастись терпением.
Система, собранная из исходных кодов требует гораздо больше внимания. Тем более, изначально для этого не предназначенная (такая как Ubuntu).
Обычное обновление системы через apt-get upgrade порушит все наши труды по сборке и оптимизации. Поэтому во-первых см. пункт "Заморозка" пакетов", и во-вторых следует выработать собственный график оптимизации системы (например, через некоторое время после очередного релиза).

->Возможные проблемы:
Несмотря на то, что по идее apt-build сам скачивает и устанавливает всё необходимое для компиляции, иногда при сборке можно увидеть ошибку, связанную с неудовлетворёнными зависимостями. В общем и целом удаётся просто установить нужное через apt-build install. В "сложных" случаях пригодится команда:
apt-get build-dep package_name

Также в некоторых случаях apt-build по неизвестным мне причинам отказывается видеть в /etc/apt/sources.list строчку с собственным локальным репозиторием, вследствие чего отказывается устанавливать только что собранный пакет. Что интересно, если в случае с пересборкой уже установленного пакета запустить apt-get update && apt-get upgrade - свежесобранный пакет будет предложен к обновлению. Как раз из локального репозитория.
Это все проблемы, с которыми я столкнулся в процессе использования apt-build.

И в заключение самое главное: если кто-то надумает попробовать apt-build - помните: ВСЕ ДЕЙСТВИЯ ВЫ ПРОИЗВОДИТЕ НА ВАШ СТРАХ И РИСК:-) Но на мой взгляд, оно того стоит. Главное - понимать что ты делаешь.
...

P.S. Вот за такие штуки я и люблю Debian и его потомков:-)

Источник

Комментариев нет: