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

Материал из MediaWiki
Перейти к навигации Перейти к поиску

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

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

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

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

user@linux$ tar zxf program.tar.gz  # или tar jxf program.tar.bz2. А еще можно воспользоваться графическими средствами, в gnome и kde они есть
user@linux$ cd program              # переходим в только что созданный каталог с исходниками
user@linux$ ./configure             # тут можно передать некоторые параметры сборки, см ./configure --help
user@linux$ make                    # компилируем
root@linux# make install            # устанавливаем предварительно получив права root командой su. Либо используем sudo, что в принципе более правильно, а в некоторых дистрибутивах это еще и единственный способ (например Ubuntu)

Поскольку при таком способе установки информация о том, что ставилось и куда, остается только в памяти админа (которая частенько еще какая временная :), лучше для контроля этого процесса использовать 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 | awk -F: '/ELF.+executable/{print $1}' | xargs strip --strip-unneeded 
root@linux# find . | xargs file | awk -F: '/ELF.+shared object/{print $1}' | 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 почти всё вместе.

Я поставил пакет XXX-dev/XXX-devel, а configure все равно говорит, что XXX не установлен

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

Вам нужно искать информацию о происходящей ошибке в файле config.log. Скорее всего, будут какие-то сообщения об ошибках компилятора при сборке тестовых программ.

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

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

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

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

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

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

Помогаем:

  • [1] - русское пошаговое описание для новичков
  • [2] - архив параметров ядра, разница между разными версиями

Если у вас 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

Или можно проще

bzcat mypatch.bz2 | patch -p0

или

zcat mypatch.gz | patch -p0

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

Есть ядро версии 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 из исходников?

Можно использовать jhbuild, для старых версий garnome(web.archive.org с сохранённым ftp-сервером).

Как собрать 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.


Я не успеваю прочитать все сообщения на экране. Похоже там какие-то ошибки

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

Для решения этой проблемы воспользуйтесь командой "script".

script

./configure
make

exit

В текущем каталоге появится файл typescript. Он будет содержать все сообщения которые появлялись на экране. Также можно использовать программу tee.

Как запустить, протестировать, посмотреть программу до установки ее в систему ?

Данное решение работает для множества программ, но не для всех.

Программу можно установить в каталог $HOME/usr. Для этого вместо команды "make install" воспользуйтесь командой

mkdir $HOME/usr
make install DESTDIR=$HOME/usr

Далее нужно изменить файл $HOME/.bash_profile добавив в него эти строки :

export PATH=\
$PATH:\
$HOME/usr/bin:\
$HOME/usr/local/bin:\
$HOME/usr/sbin:\
$HOME/usr/local/sbin

export LD_LIBRARY_PATH=\
$LD_LIBRARY_PATH:\
$HOME/usr/lib:\
$HOME/usr/local/lib

export MANPATH=\
$MANPATH:\
$HOME/usr/man:\
$HOME/usr/share/man:\
$HOME/usr/local/man:\
$HOME/usr/local/share/man

export INFOPATH=\
$INFOPATH:\
$HOME/usr/info:\
$HOME/usr/share/info:\
$HOME/usr/local/info:\
$HOME/usr/local/share/info

export PYTHONPATH=\
$PYTHONPATH:\
$HOME/usr/lib/python2.6/site-packages:\
$HOME/usr/local/lib/python2.6/site-packages

export PKG_CONFIG_PATH=\
$PKG_CONFIG_PATH:\
$HOME/usr/lib/pkgconfig:\
$HOME/usr/local/lib/pkgconfig

export C_INCLUDE_PATH=\
$C_INCLUDE_PATH:\
$HOME/usr/include:\
$HOME/usr/local/include

export CPLUS_INCLUDE_PATH=\
$CPLUS_INCLUDE_PATH:\
$HOME/usr/include:\
$HOME/usr/local/include

export LDFLAGS="\
-L$HOME/usr/lib \
-L$HOME/usr/local/lib \
$LDFLAGS"

После этого вам нужно перелогиниться в систему.

Будет доступен вызов программ, программы смогут найти свои библиотеки, можно будет вызывать их страницы man, info.

Как запустить программу не устанавливая её, сразу же после компиляции ?

Если программа при запуске требует библиотеки из других каталогов, то для этого скомпилированный elf-файл программы и её библиотеки положите в один каталог.

В этой папке создайте такой файл для запуска программы :

#!/bin/sh

export PATH=\
`pwd`:\
$PATH

export LD_LIBRARY_PATH=\
`pwd`:\
$LD_LIBRARY_PATH

./program_name

Что такое сборка с обратной связью (FDO/PGO/LWP) ?

Современные компиляторы (GCC => 4.3 или Intel C/C++) позволяют использовать автоматическое профилирование (в отличие от ручного (с помощью gprof, например) поиска наиболее интенсивно нагружающих процессор функций и их переписывания более оптимальным образом), такая оптимизация называется оптимизацией с обратной связью (feedback directed optimization - FDO), легковесным профилированием (LWP - lightweight profiling, в отличие от "тяжеловесного" с помощью gprof и переписывания кода), оптимизацией ведомой профилем (PGO - profile guided optimization). Процедура состоит из 3 фаз, одна из которых может являться интерактивной, т.е. требующей действий от пользователя.

Этап 1: Сборка инструментированных бинарных файлов

Используются ключи компилятора -fprofile-gen (GCC) или -prof-gen (ICC) , целевые бинарные файлы будут содержать много служебного кода, который будет использоваться для сбора статистики во время выполнения программы, инструментированные бинарные файлы имеют низкую производительность сгенерированного кода.

Этап 2: Интерактивная фаза сбора статистики

Программа устанавливается обычным образом (или в отдельный префикс) и используется пользователем, во время работы программы собирается статистика промахов в кеш процессора, использования или неиспользования функций, переменных и так далее. В эту фазу важно постараться использовать программу максимальным образом, например и кодирование и декодирование разных форматов в случае с медиа кодеками, компрессию и декомпрессию с разными опцииями в случае архиваторов, использовать все пункты в меню и открыть все типы документов в случае программы с графическим интерфейсом, для неиспользованных функций информация по профилю собрана не будет. Файлы статистики обычно пишутся в каталог с файлами исходного кода или можно (например для Gentoo portage, при использовании стандартых ebuild'ов) задавать каталог с помощью ключей -fprofile-dir=путь (GCC) или -prof-dir путь (для ICC) на первом этапе.

Этап 3: Пересборка программы с учетом собранной статистики

Производится очистка собраных объектных файлов и пересборка с использованием собраной статистики, используются ключи компилятора -fprofile-use (GCC) или -prof-use (ICC), результирующие бинарные файлы обычно имеют максимально достигаемую с помощью опций компилятора оптимизацию под процессор. В случае с Mozilla Firefox 3.6 оптимизация сборкой под процессор Intel Pentium IV повышает производительность в тестах Peacekeeper(web.archive.org -- смотреть версии конца 00-х годов) на 10%, в случае использования FDO получаем еще 10%, т.е. суммарное ускорение по тестам достигает 20%, неплохой результат не так ли?


Что говорит против использования FDO для сборки программ ?

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

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

И наконец, какой ужас! Собранные бинарные файлы будут привязаны к типу процессора (конвееру, размеру кешей, конкретным ключам сборки, например -mfpmath=sse) , что может проявиться снижением производительности на других процессорах, особенно с меньшим кешем, типом конвеера (in order execution на Intel Atom например), что существенно ограничивает распространение собранных данным методом программ.

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

Какие пакеты поддерживают легкую сборку с профилированием?(Актуальность раздела не проверялась)

Mozilla Firefox (make profiledbuild), существует также PKGBUILD для Arch Linux и (в багзилле) ebuild для Gentoo

x264 (make fprofiled VIDS="список файлов") интерактивная фаза тут не требует вмешательства пользователя,кодек будет отпрофилирован на указанных пользователем файлах с использованием различных настроек кодирования и декодирования.

GCC (make profiledbootstrap) в процессе сборки GCC будет собран backend компилирующий код на C на 7% быстрее , чем без профилирования (для ветки 4.5 пока не работает)

Другие пакеты вам придется собирать по описанной выше трехэтапной схеме, вручную меняя CFLAGS, CXXFLAGS

Как на 64-битной ОС собирать для 32-битной ?

Обмануть автоматическое определение архитектуры помогает утилита setarch, вызвать ее можно как i386 для установления 32-битности ОС. После вызова нужно заново задать переменные окружения, не забудьте и про добавление -m32 в флаги компилятора , а также другие значения, например --libdir=/usr/lib32 для ./configure (если ваша система содержит 32 битные библиотеки в /lib32)