Сборка программ

Contents


Зачем мне (не)нужно собирать программу из исходников ?

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

Как собрать программу из исходников? Как установить программу из tar.gz/tar.bz2?

Скорее всего в tar.gz/tar.bz2 лежит не программа, а ее исходники. Прежде чем ее поставить, необходимо ее собрать. Для этого нужно выполнить (не бросайтесь сразу это делать):

user@linux$ ./configure
user@linux$ make
root@linux# make install

Если после любого из пунктов возникли сообщения об ошибках, значит не все вышло так, как хотелось. Можно попробовать ./configure --help для вывода опций настройки и попробовать использовать некоторые из них.

Поскольку при таком способе установки информация о том, что ставилось и куда, остается только в памяти админа (которая частенько еще какая временная :), лучше для контроля этого процесса использовать checkinstall или похожие программы (почему выше и мы говорили не выполнять команды сразу). После того, как вы, прочитав документацию, установите ее и настроите конфиг, на этапе установки программного обеспечения вместо make install будете писать checkinstall. Checkinstall соберет "настоящий" пакет для указанной (tgz, rpm и deb в зависимости от настроек), установит его в систему и поместит в указанный в конфигурационном файле каталог (удобно для централизованного обновления нескольких машин). Удаление установленных таким образом программ осуществляется стандартными средствами дистрибутива, например, removepkg для Slackware или dpkg для Debian/Ubuntu.

В rpm-based дистрибутивах собирайте программы из srpm или с использованием spec-файлов (для создания rpm). Не превращайте свою систему в помойку. В Slackware программы легко и непринуждённо собираются с помощью простого скрипта SlackBuild. Да и в потомках Debian'a тоже есть штатная система сборки программ в дистрибутивные пакеты и лучше пользоваться ей.

Как удалить программу, собранную из исходников?

Это неоднозначный вопрос. Дело в том, что если вы просто собрали программу с помощью ./configure && make && make install, то все зависит лишь от того, позаботился ли автор об удалении.

Для того, чтобы удалить программу, нужно зайти в каталог ее исходников, из которого она собиралась, и сделать make uninstall. Если каталог не сохранился, распакуйте исходники, запустите ./configure с теми же параметрами, с которыми собирали программу, и выполните make uninstall. А чтобы не полагаться на приличия автора, рекомендуется посмотреть предыдущий вопрос.

Почему после ручной сборки из исходников у программ получается большой размер?

По умолчанию программы собираются с отладочной информацией. Это, соответственно, увеличивает их размер, но на быстродействие и занимаемую оперативную память не влияет.

Можно собрать программу без отладочной информации, указав соответствующий ключ - ./configure --disable-debug

Удалить секции с отладочной информацией из уже собранной программы можно командой strip progfile. Посмотреть, что вышло можно командой file progfile, она напишет - stripped или not stripped.

А можно сделать более правильно:

root@linux# find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 
root@linux# find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded

Что прописать в настройках rpm, чтобы для всех собираемых программ выполнялся strip?

Создаем файл /etc/rpm/macros с таким содержанием:

%debug_package %{nil}
%_missing_doc_files_terminate_build 0
%_unpackaged_files_terminate_build 0
%__os_install_post    \
        /usr/lib/rpm/redhat/brp-compress \
        /usr/lib/rpm/redhat/brp-strip %{__strip} \
        /usr/lib/rpm/redhat/brp-strip-shared %{__strip} \
        /usr/lib/rpm/redhat/brp-strip-static-archive %{__strip} \
        /usr/lib/rpm/redhat/brp-strip-comment-note %{__strip} %{__objdump} \
%{nil}

В будущем при смене версии rpm, не придется ничего править в самих макросах из rpm.

Что делать если configure говорит, что XXX не установлен, а на самом деле он установлен?

Для сборки нужны заголовочные файлы (headers). Во многих дистрибутивах библиотеки и программы поделены на два пакета - foo и foo-devel (Fedora, Mandriva) или foo-dev (Debian, Ubuntu). Соответственно нужно поставить foo-devel (foo-dev). Иногда надо вручную запустить ldconfig чтобы увиделись свежеустановленные библиотеки.

Примечание: в пакетах Slackware почти всё вместе.

Как собрать rpm пакет из src.rpm (srpm)?

В зависимости от дистрибутива rpm --rebuild название_пакета.src.rpm или rpmbuild --rebuild название_пакета.src.rpm

Кроме того ALT'овцы рекомендуется не собирать пакеты на работающей системе, а использовать hasher

Если вместо ожидаемого результата, на экран выводится список параметров командной строки, нужно установить rpm-devel. Ну а если все получилось, то пакеты будут лежать в /usr/src/название_дистрибутива/BUILD/название_архитектуры_процессора, например /usr/src/redhat/BUILD/i386.

Помогите собрать ядро

Помогаем:

  • http://kernel.xc.net/ - архив параметров ядра, разница между разными версиями

Если у вас rpm-based дистрибутив, то тогда прочитайте следующий вопрос.

Как собрать ядро из src.rpm? Как собрать собственное ядро из src.rpm?

Поскольку у меня (jackill) Fedora, то рассматривать мы будем именно ядра этого дистрибутива. Для других дистрибутивов чуть-чуть будут отличаться пути в /usr/src и, возможно, названия spec-файлов.

Самый простой случай

Мы скачали пакет вида kernel-2.x.x-1.xxx.src.rpm. Нас устраивает конфигурация по умолчанию, но не устраивает сборка под i386. Поэтому пишем:

root@linux# rpmbuild --rebuild --target=i686 

и забираем готовый пакет из /usr/src/redhat/RPMS/i686

Собираем собственное ядро

Распакуем srpm:

root@linux# rpm -i kernel-2.x.x-1.xxx.src.rpm

Далее перейдем в каталог /usr/src/redhat/SPECS и распакуем сами исходники, наложив при этом все патчи:

root@linux# rpmbuild -bp --target=i686 kernel-2.x.spec

Теперь переходим в каталог /usr/src/redhat/BUILD/kernel-2.x/linux-2.6, это исходники ядра с соответствующим конфигом. Здесь выполним две команды:

root@linux# make oldconfig
root@linux# make menuconfig

Теперь мы можем выставить желаемые параметры. В качестве помощи можете воспользоваться этим разделом. Я обычно включаю поддержку NTFS, выбираю свой тип процессора, убираю поддержку 4ГБ памяти, ставлю соответствующие параметры для samba, а если машина в домене MS Windows 2003, то добавляю поддержку CIFS, а лишнее убиваю.

После того, как вы закончили выставлять параметры, мы переименовываем наш файл конфигурации .config, например в kernel-2.6.8-i686.config и переписываем в каталог /usr/src/redhat/SOURCES.

Далее в kernel-2.x.spec выставляем какое нам нужно собрать ядро (обычное или smp), нужно ли собирать пакет с исходниками и пакет с документацией:

Summary: The Linux kernel (the core of the Linux operating system)

# What parts do we want to build?  We must build at least one kernel.
# These are the kernels that are built IF the architecture allows it.

%define buildup 1
%define buildsmp 0
%define buildsource 1
%define builddoc 0

После делаем как обычно.

Если нужно добавить патч

Алгоритм простой:

Накладываем этот патч на распакованные исходники, конфигурируем ядро, переписываем так же получившийся конфиг, затем прописываем патч в kernel.spec (в двух местах: в одном сам патч, например Patch10002: vesafb-tng-0.9-rc4-r3-2.6.9-rc3.patch, во втором способ его наложения, например, Patch10002 -p1 - все увидите и сделаете по аналогии).

Если после этого на сборке ядро вылетает, придется сделать make oldconfig для всех файлов конфигурации (повод научиться писать скрипты ;), или убить все конфиги, кроме нужного вам, после чего повторить сборку.

Правда все просто?

Как накладывать патчи? Как накладывать патчи на ядро? (patch, diff)? Как убирать патчи?

Вообще было бы неплохо просто сделать man patch и все стало бы ясно (кстати, сделайте). А как накладывать патчи на ядро написано в самом README к ядру. Тем не менее.

Несжатый патч:

patch -p1 < my_patch.patch

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

Сжатый патч. Это патчи вида mypatch.gz и mypatch.bz2, соответственно:

bzip2 -dc mypatch.bz2 | patch -p0

или

gzip -cd mypatch.gz | patch -p0

Чтобы откатить патч, нужно добавить в команду ключик -R

Нужно ли накладывать промежуточные патчи на ядро?

Есть ядро версии 2.6.6. Нужно получить ядро 2.6.9. Нужно ли накладывать ли patch-2.6.7 и patch-2.6.8? Нужно.

Есть ядро версии 2.6.17.3. Нужно получить ядро 2.6.17.5. Надо откатится обратно до 2.6.17 (patch -p1 -R) и наложить патч до 2.6.17.5

При сборке ядра make menuconfig ругается, что ncurses не установлен.

Установите ncurses-devel или как он там называется в вашем дистрибутиве.

Зачем собирать модули? Почему бы не сделать монолит?

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

У модулей, однако, есть преимущество. Модулю можно передать параметры. Яркий пример - модуль bttv. В случае монолитного ядра параметр придется передавать через загрузчик. Модули так же можно выгружать.

Как правильно собрать Gnome из исходников?

Можно использовать garnome.

Как собрать KDE из исходников?

В первую очередь убедитесь что у Вас установлены достаточно новые версии пакетов Qt , soprano, akonadi, boost , также могут потребоваться (для плазмоидов) Google Gadgets, для графического пакета потребуется exiv2, для pim (почтовый клиент, адресная книга и.т.п) - gpg, gpgme,

Большую часть исходников для предзависимостей КДЕ (KDE4) можно скачать с SVN командой

svn co svn://anonsvn.kde.org/home/kde/tags/kdesupport-for-4.3/kdesupport

Также Вам потребуется cmake

Порядок сборки - kdelibs , kdepimlibs , kdebase-runtime , kdebase-workspace , все остальные пакеты можно собирать в произвольном порядке.

собирается достаточно тривиально:

распаковываем пакет

tar -xvf kdelibs-4.3.2.tar.gz создаем папку для сборки внутри распакованой папки

cd kdelibs-4.3.2 mkdir builddir

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

cmake ..

команда cmake в отличие от ./configure воспринимает параметры в виде -DCMAKE_INSTALL_PREFIX=/usr (например вместо --prefix=/usr), можно также воспользоваться ccmake или cmake-gui

дальше обычная сборка (-j2 - использовать два потока сборки, для четырехъядерных процессоров можно задавать -j4 и так далее)

make -j2

после чего можно установить собраные программы с помощью

make install или make install DESTDIR=/путь/установки для последующего создания пакета

Что делать если программа не имеет скрипта configure?

Часто бывает так, что исходный код, загруженный из систем контроля версий не содержит скрипта configure. Иногда его нет и в обычных тарболлах, но есть autogen.sh. Запускаем сначала его, а потом при необходимости - ./configure. Если же отсутствует и он, но есть файлы configure.ac, Makefile.am, Makefile.in., то можно сделать так - autoreconf -v --install

Возможно, что программа использует другую систему сборки, например, scons или qmake (в случае qmake в исходниках будут присутствовать файлы .pro). Если используется cmake , то присутствует CMakeLists.txt и конфигурирование осуществляется командой cmake . (путь к исходникам обязателен, в случае если Вы собираете в корне распакованых исходников текущий путь указывается просто точкой, впрочем, некоторые программы Вам это сделать не дадут и попросят создать отдельный каталог.)

Читайте документацию, она рулит, скорее всего всё, что нужно, написано в README.