Linux Slackware Энциклопедия от А до Я
Сайт посвящен свободно распространяемому ПО и Linux Slackware в частности.
Разделы:
Раздел/Тема
Главная -> Оптимизация -> Написание SlackBuid скрипта.
Оригинал (английский) взят с: http://www.slackwiki.org/Writing_A_SlackBuild_Script
Автор – Florian Mueller (jjdm@jjdm.org)
Английская редакция – Robby Workman (robw810)
Перевод и русская редакция – Danhuu 8-9 декабря 2006 г.

Мне кажется, что тема интересная, а поскольку английский текст «на лету» я не воспринимаю, то решил, что проще перевести. А чтобы труды зря не пропадали, предлагаю их народу, авось кому пригодится. Статья, имхо, в первую очередь рассчитана на создание пакетов для дальнейшего распространения, так что, если просто нужно подогнать пакет под себя, достаточно поправить существующий скрипт, и довольно подробное описание секций может здорово помочь.
Некоторые моменты мне не совсем понятны, так что, кто знает – правьте. В итоге может получиться очень приличная статья. Во всяком случае гуглевание не нашло ничего столь подробного в русской части Сети.

Введение
При использовании Слаквари возможна ситуация, когда вам захочется установить программу, готового пакета для которой нет ни на официальном сайте slackware.com ни в сторонних репозиториях типа linuxpackages.net, или же просто не нравятся они вам. В таком случае существует несколько вариантов как это сделать:
 
  • ./configure && make && make install
  • воспользоваться checkinstall
  • воспользоваться installwatch
  • откомпилировать вручную и воспользоваться makepkg  
  • написать SlackBuild-скрипт

 
Разберём последний вариант – написать SlackBuild-скрипт, который сочетает в себе лучшие стороны вышеперечисленных методов. С помощью SlackBuild-скрипта вы автоматизируете процесс сборки пакета, что позволит в дальнейшем легко обновить или пропатчить пакет.  Официальные пакеты для Слаквари Патрик Волкердинг создаёт как раз методом SlackBuild-скриптов. Если посмотреть различные скрипты из разных источников, можно заметить, что как правило они состоят из зависящей от конкретного приложения и независимой от него части.
Я не смогу научить вас, как создать «идеальный» пакет, т.к. это требует достаточно глубоких знаний о Слаквари. Вам необходимо самостоятельно продумать связи создаваемого пакета с прочими пакетами дистрибутива. Эта статья рассказывает о том, как собрать работающий пакет, применяя классический «Slackware Way».
«Но это так долго!»
На прочтение этой статьи уйдёт около получаса, и ещё минут 15 на создание одного пакета (не считая времени компиляции), но время, которое вы сэкономите в дальнейшем при обновлении или удалении пакета, компенсирует затраченное вначале.
 
Структура пакета Slackware
Я не буду вдаваться в подробности, их можно узнать на linuxpackages.net и в других местах. Ограничусь кратким обзором. Слакваревский пакет – это в основе своей заархивированный tar-ом и сжатый gzip-ом каталог, содержащий как минимум один «особый» каталог. В пакет входят каталоги:
 
Код:
install/
install/slack-desc
[install/doinst.sh]
[usr/]
[usr/doc/]
[etc/]
[var/]
...


 
Каталоги и файлы в квадратных скобках необязательны, в том смысле, что если ничего не предполагается устанавливать в usr/, то вам и каталог usr/ создавать не надо.
install/slack-desc – описание пакета в соответствующем формате. Пример можно посмотреть в любом готовом официальном пакете.
install/doinst.sh Если вы хотите удалить какие-дибо файлы, создать симлинки или ещё что-то до инсталляции пакета, это можно сделать тут. Требует опыта. Никогда не используйте это «от балды».
usr/doc/<название_программы><версия> Вся документация, включаемая в пакет (README, INSTALL, ChangeLog, docs/ и пр.) помещается в этот каталог.
Остальные каталоги – это просто места, куда будут записываться файлы программы.
 
Настройка среды установки (build environment)
Здесь http://www.slackwiki.org/Build_Environment можно ознакомиться с тем, как это сделали авторы статьи (по-английски).
 
Начало работы
Будем надеяться, что со структурой слакваревых пакетов всё ясно, а удобную среду установки вы уже создали, так что переходим собственно к созданию пакета с помощью SlackBuild-скрипта.
Для примера возьмём latex2html – с его помощью я сделал свою домашнюю страничку.
Во-первых, необходимо создать каталог <build_environment>/latex2html/. Добудьте свежие исходники latex2html и положите их туда.
 
Код:
$ cd <build_environment>
$ mkdir latex2html
$ cd latex2html
$ wget http://saftsack.fs.uni-bayreuth.de/~latex2ht/current/latex2html-2002-2-1.tar.gz # 05.02.2005


 
Разумеется, пользоваться для скачивания wget совсем необязательно, скачайте исходники вашим любимым браузером и переместите в соответствующий каталог.
Затем, с помощью touch создадим другие нужные файлы. Если вы незнакомы с touch, почитайте о нём:
 
Код:
$ man touch


 
Помните, что название SlackBuild-файла должно содержать название приложения, для которого он написан; например, gaim.SlackBuild – это SlackBuild для gaim Улыбка
 
Код:
$ touch latex2html.SlackBuild
$ touch slack-desc


 
Извлеките исходники из архива, т.к., позже нам понадобится посмотреть configure-скрипт, чтобы определить, какие опции ему передавать.
 
Код:
$ tar -xzf latex2html-2002-2-1.tar.gz || exit 1


 
Напишите файл slack-desc. Как это сделать, написано на соответствующей странице SlackWiki – http://www.slackwiki.org/Slack-desc .  
Пишем SlackBuild-скрипт
Эта часть занимает больше всего времени, и мы пройдём её вместе шаг за шагом. Когда вы наберётесь опыта в создании пакетов, возможно, вам проще будет скопировать существующий  SlackBuild-скрипт и отредактировать его. Нужно понимать, что вы можете писать ваш SlackBuild-скрипт разными способами, лишь бы он создавал работающий пакет. Описанный здесь метод более-менее соответствует тому, как это делает Патрик, хотя и он сам пишет официальные SlackBuild-скрипты, пользуясь несколькими разными стилями. Так что, если вы хотите писать по-своему, не стесняйтесь.
 
Начальная установка
Откройте в любом редакторе файл latex2html.SlackBuild. Далее мы пройдём его пошагово. Вы, конечно, можете вставлять предлагаемые кусочки из статьи, но, по мнению автора, если вы будете писать всё сами, то поймёте всё гораздо лучше.
Для начала вам надо определить, какой шелл будет использоваться в качестве интерпретатора. Лучше всего – /bin/sh, т.к., он гарантированно установлен в любом Слакваре, и ваш пакет будет наиболее переносимым. С этой же целью не используйте расширения и/или синтаксис, специфичные для других шеллов (bash, zsh и прочих), иначе интерпретация может быть некорректной.
 
Код:
#!/bin/sh


 
Возможно, вы захотите включить в свой SlackBuild-скрипт какую-нибудь лицензию (желательно, GPL или в стиле BSD). Как минимум, рекомендуется сделать что-то вроде:
 
Код:
#<ваше_имя> revision date yyyy/mm/dd


 
В следующих нескольких строчках мы установим некоторые переменные, которые будут использоваться в скрипте. Первая из них – это CWD; в нашем случае устанавливаем её равной <build_environment>/latex2html/. Также проверим, установлена ли переменная TMP, и, если нет, установим её как /tmp.
 
Код:
#Устанавливаем начальные переменные:

CWD=`pwd`
if [ "$TMP" = "" ]; then
  TMP=/tmp
fi


 
Некоторым нравится собирать в подкаталог типа /tmp/build, но это – дело личное.
 
Код:
# Версия из названия файла приложения
VERSION=2002-2-1

# Если название версии конфликтует со стандартом пакетов Slackware,
# напр., дефис ("-") в строке VERSION не допускается,
# вы можете установить значение PKG_VERSION отличным от VERSION
PKG_VERSION=2002.2.1 # версия названия пакета

ARCH=${ARCH:-i486} # архитектура, на которой вы хотите собирать свой пакет

# Первый знак – это номер сборки, он определяет, сколько раз собирали пакет.
# Дальше пишется инициалы автора, обычно три
BUILD=${BUILD:-1_rlw}

# Название приложения
APP=latex2html

# Каталог установки пакета (где будет создана его структура каталогов)
PKG=$TMP/package-$APP



Устанавливаем SLKCFLAGS (используются и для CFLAGS и для CXXFLAGS). Если в вашей системе установлена версия gcc, более ранняя, чем 3.4.x, необходимо использовать "-mcpu" вместо "-mtune".
 
Код:
if [ "$ARCH" = "i386" ]; then
  SLKCFLAGS="-O2 -march=i386 -mtune=i686"
 elif [ "$ARCH" = "i486" ]; then
  SLKCFLAGS="-O2 -march=i486 -mtune=i686"
 elif [ "$ARCH" = "x86_64" ]; then
  SLKCFLAGS="-O2 -fPIC"
fi


 
В данном разделе мы покончили с определением пременных, специфичных для приложения. Если вы соберётесь создать пакет для другого приложения, обычно достаточно изменить эти переменные, и большая часть скрипта (Прим. переводчика: создание которого будет рассмотрено далее) будет работать автоматически.
 
Извлечение исходников
 
Код:
# Удаляет каталог, оставшийся от предыдущей сборки (если он был)
# и (пере-)создаёт каталог пакета
rm -rf $PKG
mkdir -p $TMP $PKG
rm -rf $TMP/$APP-$VERSION

# Переходим в каталог TMP
cd $TMP || exit 1

# Распаковываем исходники в TMP
# Если они были в tar.bz2, используйте tar -jxvf
tar -zxvf $CWD/$APP-$VERSION.tar.gz || exit 1

# Переходим в каталог распакованных исходников
cd $APP-$VERSION || exit 1

# Меняем владельца и права доступа, если надо.
# Это не всегда необходимо, но в любом случае не повредит
chown -R root.root .
chmod -R u+w,go+r-w,a-s .



Конфигурируем и компилируем
 
Код:
# Устанавливаем опции настройки
# Если ваше приложение написано на C++, необходимо также добавить
# строку для CXXFLAGS
CFLAGS="$SLKCFLAGS" \
  ./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var \
  --with-perl=/usr/bin/perl \
  --enable-eps \
  --enable-gif \
  --enable-png \
  --build=$ARCH-slackware-linux \
  --host=$ARCH-slackware-linux

# компилируем, но в случае ошибки прекращаем это дело
make || exit

# Устанавливаем в каталог пакета, но в случае ошибки прекращаем это дело
make install DESTDIR=$PKG || exit



Я обычно устанавливаю три опции настройки:
 
    Код:
--prefix=/usr
   --sysconfdir=/etc
   --localstatedir=/var

 
 
Таким образом, файлы конфигурации помещаются в /etc, файлы состояния (например, логи) помещаются в /var, а остальные – в /usr. Это обычный для Слаквари вариант, но система ваша, и вы можете установить всё в /usr/local или куда-нибудь ещё. Подробности о «правильном» размещении файлов раличных типов можно узнать на официальном сайте Filesystem Hierarchy Standard http://www.pathname.com/fhs/ .
Вы могли заметить, что в конфигурационном скрипте есть и другие опции. Необходимо разобраться с этими опциями для каждого приложения, которое вы компилируете – поэтому и надо было распаковать исходники раньше. Просто перейдите в распакованный каталог и выполните:
 
Код:
./configure --help


 
Вы получите страницу (или несколько) информации о различных опциях, специфичных для конкретного приложения. Прочтите её и разберитесь, что вам понадобится. Я предпочитаю вывести всё это на принтер, но можно воспользоваться и любым pager-ом:
 
Код:
./configure --help | lpr
./configure --help | less


 
Переменная DESTDIR очень важна, она указывает, в какой каталог будут устанавливаться файлы. Она всегда должна совпадать с нашим установочным каталогом ($PKG). К сожалению, не во всех приложениях Makefile-ы поддерживают переменную DESTDIR, и в таких случаях ей воспользоваться не удастся. С помощью простой команды типа
 
Код:
grep DESTDIR Makefile*


 
запущенной из каталога исходников, можно выяснить, поддерживается ли она в данном случае. Если на выходе вы получили строки, содержащие $DESTDIR, значит, всё в порядке. Если же ничего нет, значит, этот Makefile не поддерживает переменную DESTDIR.
Маленький совет: ВСЕГДА выполняйте ./configure && make && make install DESTDIR=/какой-то_каталог вручную и ПОД ОБЫЧНЫМ ЮЗЕРОМ ДО ТОГО, как запустите ваш SlackBuild-скрипт. Есть немало приложений, которые пытаются сотворить во время инсталляции нечто забавное.
Например, apcupsd попытается пропатчить вам /etc/rc.d/rc.M скрипт инициализации. Конечно, можно обойти это с помощью опций настройки, но не факт, что вы поймёте, что это надо сделать, пока не посмотрите Makefile-ы apcupsd или не пронаблюдаете процесс инсталляции.
В любом случае, запустив процесс из-под юзера, вы увидите ошибки типа «Permission Denied», если инсталляционный процесс попытается записать что-то куда не положено.
 
Установка документации
 
Код:
# Создаем каталог для документации
mkdir -p $PKG/usr/doc/$APP-$VERSION

# Копируем документацию туда и устанавливаем права доступа
cp -a BUGS Changes FAQ INSTALL LICENSE MANIFEST README TODO docs/ $PKG/usr/doc/$APP-$VERSION
find $PKG/usr/doc/$APP-$VERSION -type f -exec chmod 644 {} \;


 
Я (robw810) также создаю копию своих скриптов в этом каталоге
 
Код:
cat $CWD/$APP.SlackBuild > $PKG/usr/doc/$APP-$VERSION/$APP.SlackBuild


 
Удостоверьтесь, что вы копируете реально существующую документацию, т.к., в некоторых приложениях часть помянутых выше файлов может отсутствовать, а в других могут быть дополнительные файлы. Короче, не надо тупо вставлять куски кода из примера, обязательно пишите эту секцию в соответствии с конкретным приложением.
 
Последние штрихи
 
Код:
# Создаем каталог ./install и копируем туда slack-desc
mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc


 
ВНИМАНИЕ: В некоторых случаях после установки содержимого пакета надо выполнить дополнительные действия. Для этого надо создать файл doinst.sh в каталоге $CWD, в котором прописываются эти действия, и сжать его при помощи gzip. SlackBuild-скрипт проведёт над ним zcat (т.е. gunzip и затем cat его содержимое), а результат запишет в doinst.sh в каталоге $PKG/install.
 
Код:
# Добавляем doinst.sh в пакет (если есть)
if [ -e $CWD/doinst.sh.gz ]; then
  zcat $CWD/doinst.sh.gz > $PKG/install/doinst.sh
fi


 
По возможности сэкономим дисковое пространство: почистим библиотеки и бинарники от отладочной информации и сожмём маны gzip-ом. Обратите внимание, что с этой целью можно использовать make install-strip вместо приведённого в примере make install.
 
Код:
# Чистим библиотеки и бинарники
( cd $PKG
   find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
   find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
)

# Сжимаем маны, если есть
if [ -d $PKG/usr/man ]; then
  ( cd $PKG/usr/man
  find . -type f -exec gzip -9 {} \;
  for i in `find . -type l` ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
  )
fi

# Сжимаем info pages, если есть, и стираем файл dir
if [ -d $PKG/usr/info ]; then
  gzip -9 $PKG/usr/info/*.info
  rm -f $PKG/usr/info/dir
fi



 
Сборка пакета
 
Код:
# Собираем пакет
cd $PKG
/sbin/makepkg -l y -c n $TMP/$APP-$PKG_VERSION-$ARCH-$BUILD.tgz


Кой-какие дополнения
Недоступна опция DESTDIR
Как упоминалось выше, существует немало приложений, в которых Makefile-ы не поддерживают опцию DESTDIR. Лучшее, что можно сделать в этой ситуации, – это написать патч для Makefile.in и отправить его разработчикам, чтобы его включили в пакет исходников, но, как выяснилось, не все это умеют Улыбка . Ещё можно написать разработчикам и попросить их включить эту полезную опцию в новые версии. А пока предлагаю несколько идей…
В большинстве случаев можно сделать так:
 
Код:
./configure --prefix=$PKG/usr


 
и аналогично в других опциях настройки. Тогда всё содержимое пакета установится в этот каталог. Если пакет создаёт каталоги $PKG/usr/etc, $PKG/usr/var и т.п., которые должны реально быть в другом месте, попробуйте просто переместить их куда положено в пределах дерева каталогов пакета, и всё будет хорошо. Также подобные феньки можно сделать и с другими опциями настройки.
 
Код:
./configure --prefix=$PKG/usr \
   --sysconfdir=$PKG/etc \
   --localstatedir=$PKG/var


 
Однако, бывают приложения, у которых конфигурационные файлы «hard-code» (прим. перев.: шоб я знал, что это такое!) основаны на параметрах configure/Makefile. В таком случае вам понадобится понять, как пропатчить конфиг до того, как его запаковать, или, на худой конец, включить инструкции для конечного юзера, как сделать необходимые изменения.
 
Патчим исходники
Рано или поздно может понадобиться пропатчить исходные коды перед сборкой пакета, и хорошо бы делать это автоматически.
Добываем патч
В большинстве случаев патчи предоставляются авторами исходных кодов, так что здесь мы не будем обсуждать как создавать патчи. Загрузите патч и поместите его в каталог со SlackBuild-скриптом, файлом slack-desc и прочими (в примере – в $CWD)
 
Код:
$ wget http://someapplication.org/files/patches/bigsecuritypatch.diff


 
следующий шаг необязателен, но, поскольку разработчики обычно стараются сэкономить место, принято делать так:
 
Код:
$ gzip -9 bigsecuritypatch.diff


 
Получится новый файл bigsecuritypatch.diff.gz – его-то мы и будем использовать в SlackBuild-скрипте.
 
Применяем патч
Теперь надо поправить ваш <application>.SlackBuild скрипт так, чтобы он использовал патч до запуска configure, make, и make install. Для этого надо запустить до конфигурирования скрипта, но после распаковки исходников что-то в этом роде:
 
Код:
zcat $CWD/bigsecuritypatch.diff.gz | patch -p1 || exit


 
В зависимости от того, как был создан патч, можно использовать другой patchlevel, например:
 
Код:
zcat $CWD/bigsecuritypatch.diff.gz | patch -p0 || exit


 
Это несколько выходит за рамки данной статьи, но по сути -p# определяет число trailing каталогов, которые будут пропущены при поиске патч-файла. Часто (но не всегда, отсюда  -p0) нужно пропускать каталог самого верхнего уровня.

 
Шаблон слакбилд скрипта.
Danhuu 25.12.2006