Автор статьи: geekkoo Дата: 31.07.2003
Quick and dirty способ компиляции программ, распространяемых в исходниках, обычно затруднений не вызывает (если коротко
cp foobar.tar.gz /home/usr/src
tar xzvf foobar.tar.gz
cd ./foobar-0.0.1
less README # читаем README
./configure --help | less # изучаем параметры скрипта configure - весьма полезным может оказаться параметр --prefix=<путь к директории в которую будет установлен пакет>
./configure # создаем Makefile
make
make install
)
Недостаток такого подхода заключается в том, что таким образом очень быстро ваш компьютер приходит в состояние файло-помойки. Как правило при установке программы помимо собственно исполняемого устанавливается очень много вспомогательных файлов (библиотек, манов, конфигурационных файлов), и для того чтобы их потом корректно удалить, проапгрейдить, выяснить принадлежность какого-нибудь файла к программному пакету, вам помимо бинарной версии пакета придется хранить и его исходники вместе с Makefile (более продвинутый способ, в архивированном виде). Например, деинсталляция пакета выполняется такими командами
cd foobar-0.0.1
make uninstall
В то же время все современные дистрибутивы имеют инструменты для управлениями бинарными версиями программ (package manager). Использование их дает массу преимуществ - можно собирать пакеты на одном компьютере, а потом уже распространять их на другие компьтеры, где может просто не быть средств для компиляции пакетов (а это, помимо собственно компилятора, включает в себя unstripped версию glibc ~100МБ + хедеры динамических библиотек ~ 20МБ). Я не говорю уже о том, что мощности компьютера, где предполагается использовать программу, может просто не хватить для компиляции более или менее объемного пакета.
Package manager в Slackware
В данном тексте речь пойдет о том как собирать пакеты в Slackware, причем я надеюсь, что кто-нибудь в дальнейшем расскажет как это делается в rpm-based дистрибутивах (RedHat, Mandrake, ALTLinux). Возможно, что и пользователи этих дистрибутивов найдут в этом тексте что нибудь полезное для себя.
Программный пакет в Slackware - это просто tarball (упакованный архив с расширением .tgz), в котором помимо программ находится bash-скрипт, исполняемый при инсталляции пакета (находится в папке install внутри пакета). Устанавливается пакет командой installpkg foobar.tgz. Список установленных пакетов находится в директории /var/log/packages (инсталляционные скрипты - в /var/log/scripts). Команда less /var/log/packages/foobar даст вам краткое описание пакета и список файлов, содержавшихся в нем. Удаление пакета - removepkg /var/log/packages/foobar, апгрейд - upgradepkg foobar-0.0.1%foobar-0.0.2.tgz (или upgradepkg foobar.tgz если старый и новый пакет имеют одинаковое имя). Все эти команды имеют одну весьма полезную опцию -root /other-root, которая позволяет манипулировать пакетами, находящимися на файловой системе, смонтированной под директорией /other-root.
Изготовление пакетов делается скриптом makepkg, котрый просто пакует все содержимое текущей директории (./), для каждого линка добавляет соответствующую строку в инсталляционный скрипт и меняет пермишены на файлах. Все пути к файлам в пакете, собранном таким образом, при сборке "отcчитываются" относительно текущей (./) директории, а при инсталляции - относительно корневой (/) директории. Т.е. команда makepkg, выполненная в директории /home/usr/src, где лежит файл foobar, изготовит пакет, при установке которого будет создан файл /foobar. Packet manager Slackware не отслеживает зависимости между пакетами, и если после установки какого-нибудь пакета вы вдруг обнаружите, что программа из него не запускается, выдавая сообщения libso-and-so.so not found, то скорее всего вам придется устанавливать еще один или несколько пакетов, руководствуясь здравым смыслом, текстом error messages и выводом команды ldd $(which beastly_prog_that_wouldnt_start).
Сборка пакета
Так что теперь 1) нужно сложить файлы, входящие в состав программы, в какую нибудь директорию (пусть это будет /home/user/src), 2) выполнить makepkg и пакет готов! При этом пункт 1) можно выполнить несколькими способами, и как всегда в таких случаях, когда есть несколько решений, ни одно их них не является оптимальным.
Самый прямолинейный и самый неудачный способ. Сконфигурировать программу c опцией --prefix=/home/user/src. Однако надо иметь ввиду, что при компиляции этот параметр может быть жестко прописан внутри программы в качестве абсолютного пути к какому-нибудь из ее компонентов. Поэтому после удаления этой директории, программа, до этого прекрасно работавшая, может начать выдавать сообшения file /home/user/src/usr/share/foo/... not found. Вообщем, так делать очень не рекомендуется.
Самый удачный способ - это воспользоваться программой buildpkg ( ). Это bash-скрипт, который автоматизирует весь процесс сборки пакета и может быть использован также для изготовления .rpm и .deb пакетов. Вначале tarball с исходниками обрабатывается командой mkskel foobar.tar.gz, в результате чего получится файл-шаблон foobar-1.def, который можно отредактировать (по-крайней мере просмотреть) и вписать туда параметры configure на свой вкус. Далее несколько раз нужно вызвать команду buildpkg foobar-1.def - причем каждый вызов этой программы соответствует вызову tar, configure и тд (всего 10 или 12 шагов). Если на каком-то шаге что-то пошло не так, как вам бы хотелось, то - echo $(($(cat foobar-1.status) - 1)) > foobar-1.status (уменьшает на единицу счетчик шагов, хранящийся в файле с расширением ststus) и повторяете buildpkg ...
buildpkg может работать в двух режимах - нормальном и jail ( чему отвечают параметры конфигурационного файла /etc/buildpkg/builpkg.conf INSTALL_MODE = "normal"; AUTO_COLLECT_INSTALLED = "y", с одной стороны, и INSTALL_MODE = "jail", с другой ). В последнем случае в jail (AKA chrooted environment - см. man chroot) перед началом установки копируется набор утилиток, которые могут потребоваться для выполнения make install ( очевидно там должен быть cp, ln, bash ... - полный список см. /etc/buildpkg/buildpkg.jail), которые после завершения установки (в соответствии со списком) оттуда удаляются - так что все что остается в jail будет являться компонентами устанавливаемой программы. Недостатки этого метода связаны с тем, что заранее, как правило (т.е. без внимательного изучения скрипта configure и Makefile, который он создает), не известно какие именно команды потребуются для выполнения make install, и поэтому какой-нибудь нужной утилитки в jail-e в итоге может и не оказаться (команд имеющихся в дефолтном buildpkg.jail с вероятностью ~40% будет не достаточно). В этом случае в процессе инсталляции нужно внимательно отслеживать сообщения buildpkg и при появлении ошибки "такой-то команды не найдено", отредактировать файл buildpkg.jail, добавив туда недостающую команду, и повторить установку. Так что этот метод хотя и надежный, но вам, возможно, придется предпринять несколько итераций, прежде чем пакет будет собран.
В normal mode buildpkg делает снимки файловой системы до и после инсталляции, а их diff затем перекладывается во временную директорию и там пакуется. Минус - если вы компилируете программу, предыдущая версия которой уже имеется на вашей системе и ( более того ) используется в данный момент, то есть большая вероятность того, что при инсталлировании не удастся перезаписать некоторые файлы. Соответственно diff выдаст не полный список установленных файлов, и пакет в итоге получится урезанным.
Ну и напоследок метод который лично мне нравится больше всего - так сказать "административный" способ. Идея в том чтобы отмечать устанавливаемые файлы каким-нибудь флажком - например принадлежностью к какой-нибудь группе. Для этого создаете дополнительную группу с произвольным именем (например, groupadd creators), и добавляете в нее пользователя root (usermod -G $(groups|sed s/" "/,/g),creators root # groups выдает группы, к которым принадлежит root, в виде списка с пробелами в качестве разделителей, поэтому sed-ом заменяем пробел на запятую и добавляем creators). Компилируем как обычно, а команду make install выполняем под группой creators - sudo sg creators "make install". Затем ищем все файлы, принадлежащие группе creators, и переносим их в какую-нибудь из директорий, где и собираем пакет. Вот небольшой bash-скрипт под названием createpkg, который автоматизирует эту задачу:
#!/bin/sh
CREATORS=creators
#group name, change it to your tastes
sg $CREATORS "${1:-make install}";
#pass installation command as first argument, by default it is "make install"
flist=$(find /usr /lib /bin /sbin /var /etc -group $CREATORS)
#find installed components under /usr /lib /bin /sbin /var /etc
mkdir -p /tmp/poligon
cp -dRP $flist /tmp/poligon
#create temporary dir and copy components there recursivly (R) ,preserving links (d) and path (P)
idir=$(pwd)
cd /tmp/poligon
/sbin/makepkg Slack_Pack.tgz
#make pakage with arbitrary name
cp Slack_Pack.tgz ${idir}.tgz
#copy it to one level above current directory, name it with directory name + .tgz
cd $idir
rm -rf $flist
rm -rf /tmp/poligon
#clear all
Использовать его следующим образом - в директории с исходниками, после того как компиляция завершилась, набираете sudo createpkg (если для установки программы требуется команда отличная от make install - что, впрочем, случается не часто, например make client-install, то скармливаете ее в качестве параметра - createpkg "make client-install"). В итоге, рядом с директорией с исходниками появляется пакет с тем же именем и расширением .tgz (заметьте что этот скрипт удаляет установленные файлы и поэтому вам придется еще выполнить installpkg). Поскольку инсталляция происходит в "настоящие" каталоги (т.е. в те где программные файлы и будут расположены после установки), то недостатки этого метода те-же, что и у buildpkg в нормальном режиме. Достоинство, вобщем-то, только одно - простота и прозрачность.
Ну и в заключение еще один совет - если есть возможность достать готовый бинарный пакет, заточенный под ваш дистрибутив, то воспользуйтесь им. Компилирование чужих программ (чем должны заниматься или их разработчики или maintainer-ы дистрибутива) не прибавляет вам ни знаний, ни навыков, а только отнимает время. К рассказам о том, что "После перекомпиляции программы X, она стала работать в n раз быстрее и жрать в m раз меньше ресурсов" следует относится как к рассказам бывалых рыбаков и охотников. Оптимизация работы программы в таких случаях связана обычно с отключением определенной функциональности, и вы не можете гарантировать, что именно эта функциональность не понадобится вам сейчас или через некоторое время.
CopyLeft geekkoo
|