Форумы портала PHP.SU » Разное » Обсуждение статей » Ручная конфигурация и сборка приложений в ОС Linux

Страниц (1): [1]
 

1. EuGen - 15 Марта, 2013 - 12:30:39 - перейти к сообщению
Приветствую, коллеги,


Возможность ручной сборки - не прерогатива Linux

В контексте обсуждения предыдущей статьи, освещавшей историю ОС Linux и её взаимосвязь с GNU, я обещал дополнение в виде обзора ручной конфигурации приложений и их сборки. Эта возможность - не особенность именно системы Linux, это прямое следствие СПО - так как, поскольку код открыт, его можно собирать (компилировать) вручную - так что важно понимать, что Linux в данном случае служит лишь платформой для рассмотрения такой возможности.

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

За и против: что дает ручная сборка?

В чем плюсы данного подхода? Их несколько:
0. Универсальность. В самом деле, мы можем написать код единожды, а компилировать его на разных системах. Сам исходный код будет неизменен, но будет собираться в зависимости от целевой платформы. Для унификации здесь как раз и нужна процедура конфигурации, которая происходит до собственно сборки (подробнее в части, описывающей процесс сборки)
1. Гибкость. Можно настроить все, что позволяет конфигуратор - сделать именно ту сборку, которая требуется под конкретную задачу, можно сделать даже несколько разных сборок и использовать их для разных задач.
2. Нетребовательность к целевой системе. В самом деле - не нужно пакетного менеджера, чтобы установить программу подобным образом. Это, правда, в известной степени лукавство - если сама программа опирается на другие модули, то собрать её без них не получится в любом случае - ручная это сборка или нет.

В чем минусы данного подхода? Их тоже несколько:
0. Отсутствие пакетного контроля. Представим, что мы собрали программу, а автор выпустил обновление. В случае с пакетами достаточно запустить команду на обновление, в случае же ручной сборки - придется пересобирать вручную.
1. Отсутствие централизованной системы контроля за установленными приложениями. Вы не сможете понять, какое приложение вы собирали - и куда оно было помещено. Если часто пользоваться ручной сборкой, то система рискует обрасти такими приложениями, которые будут разбросаны по разным местам. Впрочем, здесь есть выход - придерживаться строгих правил при сборке, структурируя целевые приложения самостоятельно.
2. Затруднительность разрешения зависимостей при сборке. Если у автора есть документация, в которой сказано, какие нужны модули для работы приложения - хорошо. Достаточно установить их, и все. Если же такой документации нет, то все становится печально - при сборке, приложение "натыкается" на отсутствующий модуль - сообщает об этом, и сборка завершается аварийно. Соответственно, установка нужных модулей будет выполнен путем "разведки боем".

О применимости - там, где это нужно на самом деле

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

И как все это, наконец-то, происходит

Речь может, разумеется, идти и не о PHP - а о другом приложении, но я остановлюсь именно на задаче установки двух версий интерпретатора, потому что это имеет наибольшую практическую ценность. Начну с того, что опишу, как вообще происходит сборка. Для того, чтобы это сделать, в большинстве случаев потребуется приложение make. Это - программа, которая на основании специально сформированных файлов MakeFile работает с исходными текстами и компилирует их в файлы динамических библиотек и/или приложений. Файлы MakeFile являются своего рода конфигурационными файлами, сообщающими, что должна сделать make. Теоретически, их можно было бы создавать и вручную, но для сложных приложений это вряд ли возможно - да и незачем, пользователь избавлен от этой процедуры благодаря тому, что практически любая программа, собираемая из исходного кода, имеет поставляемый конфигуратор. Так что мы подошли к важной точке - пониманию того, что собственно сам исходный код нуждается в конфигурации - до сборки.

Таким образом, если представить себе "чистый" исходный код - вряд ли из него получится собрать приложение. Конфигуратор нужен, чтобы создать требуемые MakeFile - на основании тех параметров, которые задаст пользователь. Это очень удобно - в самом деле, ведь можно использовать одну копию исходного кода, из которой затем собрать сколько угодно раз нужное приложение с нужными настройками. Классически, конфигуратор представляет из себя sh-скрипт, который, как правило, принимает параметры пользователя и создает файлы для make. В общем случае конфигуратор может быть даже бинарным файлом - но я такого не встречал (поскольку, очевидно, есть риск того, что бинарный файл не сможет запуститься на целевой системе). Итак, предположим, что мы сконфигурировали наше приложение, указав нужные ключи и модули для сборки, процесс прошел успешно и MakeFile создались. Что дальше? Дальше, очевидно, нужно скомпилировать программу. Это и делает команда make, Запуск её приведет к началу процесса сборки приложения. Хорошо, предположим, собрали. Что дальше? Дальше нужно установить готовое приложение в систему. Делает это все та же make, но запуск происходит так: make install - после этого приложение будет помещено в целевой каталог с бинарными файлами, его модули - в соответствующие каталоги библиотек системы и т.п. "Целевой каталог" - как правило, задается на этапе конфигурации.
Как итог, сборка программы - это:

0. Конфигурация для сборщика.
1. Сборка в соответствии с конфигурацией
2. Установка готового приложения
- рассмотрим каждый из этих этапов на примере сборки PHP.

Конфигурация
Прежде всего, что такое "исходные коды"? Они предоставляются разработчиком и, как правило, могут быть скачаны с открытого ресурса. Например, будем собирать php версии 5.4.13. На момент написания этой строки у меня установлено 5.4.10 - заодно и обновлюсь. Что я буду делать? Прежде всего, я скачаю архив с исходным кодом с php.net:
CODE (bash):
скопировать код в буфер обмена
  1. wget -Ophp-5.4.13.tar.bz2 http://www.php.net/get/php-5.4.13.tar.bz2/from/de1.php.net/mirror

- я получу файл php-5.4.13.tar.bz2 - и распакую его:
CODE (bash):
скопировать код в буфер обмена
  1. tar -xjf php-5.4.13.tar.bz2

- теперь-то я и получу заветный каталог с исходными кодами. Перейдя в него:

я могу сразу же приступить к конфигурации. Однако же помнить все ключи конфигуратора невозможно, да и бессмысленно (поскольку они могут меняться от версии к версии и у каждого приложения - свои). Но зато почти всегда у конфигуратора есть ключ --help - он сообщит список ключей, либо даст информацию о пользовании конфигуратором. Пример вывода (для php этот вывод очень объемен, потому ограничусь несколькими первыми строками):
Спойлер (Отобразить)

Выше я не упомянул, как запускать конфигуратор. В примере это видно: классически поставляется sh-скрипт с именем configure. Иногда бывает, что скрипт есть, а исполнить его не удается. Как правило, достаточно смены разрешений (выдачи разрешения на исполнение файла configure).
Что же я могу сделать? Во-первых, стоит позаботиться о том, чтобы программа соответсвовала моему правилу ручной сборки - а именно, я помещаю все собранные вручную программы в каталог /opt У php есть соответствующий ключ: --prefix Далее, стоит вспомнить о том, что в php есть большой набор модулей. Их-то мне и предстоит сконфигурировать. в ./configure --help все они даны в виде списка:
Спойлер (Отобразить)

Во-вторых, поразмыслив немного, я сам для себя решаю, какие модули мне нужны. Вот что в итоге у меня получилось:
CODE (bash):
скопировать код в буфер обмена
  1. ./configure --prefix=/opt/php-5.4.13  --exec-prefix=/opt/php-5.4.13 --with-apxs2 --with-openssl  --with-zlib  --enable-bcmath  --with-bz2 --enable-calendar --with-curl --enable-exif --enable-ftp --with-gd --with-gettext --with-gmp --with-mhash --enable-intl --with-ldap --with-ldap --enable-mbstring --with-mcrypt --with-mysql --with-mysql-sock --with-mysqli --enable-pcntl --with-pdo-mysql --with-readline --enable-shmop --with-snmp --enable-soap --enable-sockets --with-tidy --with-xmlrpc --with-xsl --enable-zip

Отмечу ключ --with-apxs2, указывающий, что я хочу собрать php как модуль для Apache 2.x
Если конфигурация будет успешной (то есть все заявленные модули могут быть собраны, поскольку необходимые библиотеки в системе присутствуют), то в конце выдастся сообщение наподобие
Спойлер (Отобразить)

Что ж, отлично, приступим ко второму шагу:

Сборка
Это - самый долгий этап, поскольку происходит связывание и компиляция. Тем не менее, как правило, этот этап прост - достаточно выполнить
CODE (bash):
скопировать код в буфер обмена
  1. make

- в том каталоге, где велась конфигурация - и готово. Сборка занимает несколько минут, а иногда и более часа, если приложение достаточно сложное. На более слабых машинах несколько лет назад сборка занимала у меня до половины суток. Описывать здесь, пожалуй, нечего, за исключением возможных ошибок. Ошибка на стадии сборки - исправляется значительно труднее, чем на стадии конфигурации, потому что ошибка при конфигурации почти всегда означает отсутствие требуемых модулей/библиотек в системе, что приводит к логически простому решению - или отключить модуль программы, который требует отсутствующих библиотек, или же установить эти библиотеки. Со сборкой же все сложнее. Это может быть и ошибочная работа библиотек в системе и просто ошибка в исходном коде программы. Сказать честно - у меня нет серебряной пули на этот случай. Я всегда решал такие проблемы путем поиска в одном небезызвестном ресурсе. Это одна из неприятных сторон работы со сборкой - если что-то идет не так, то отсутствие возможности отладки оставляет вас на милость поисковика. Разумеется, если вы - профессиональный разработчик и можете самостоятельно разобраться в исходном коде, а так же исправить то, в чем ошибся программист, его написавший - вам будет легче. Как бы там ни было, моя сборка завершилась успешно: я увидел
Спойлер (Отобразить)

Интереса ради я посмотрел время:
CODE (text):
скопировать код в буфер обмена
  1. Fri Mar 15 13:29:57 MSK 2013

до,
CODE (text):
скопировать код в буфер обмена
  1. Fri Mar 15 13:54:48 MSK 2013

- после сборки (справедливости ради, отмечу, что я одновременно собирал версии 5.4 и 5.3)
Теперь я перешел к

Установка
Самый простой этап - команда
CODE (bash):
скопировать код в буфер обмена
  1. make install

- сделает все самостоятельно. Помним о том, что я указал префикс установки. Я получил готовую сборку:
CODE (bash):
скопировать код в буфер обмена
  1. root@host:~/install/php/php-5.4.13# ls -la /opt/php-5.4.13/
  2. total 0
  3. drwxr-xr-x 7 root root 168 Mar 15 13:55 ./
  4. drwxr-xr-x 7 root root 208 Mar 15 13:29 ../
  5. drwxr-xr-x 2 root root 280 Mar 15 13:55 bin/
  6. drwxr-xr-x 2 root root  80 Mar 15 13:55 etc/
  7. drwxr-xr-x 3 root root  72 Mar 15 13:55 include/
  8. drwxr-xr-x 3 root root  72 Mar 15 13:55 lib/
  9. drwxr-xr-x 3 root root  72 Mar 15 13:55 php/

- все почти готово. Почти - потому что, так как я собрал php с нестандартным префиксом, нужно указать системе, что у меня есть php. Сделать это можно несколькими способами, я выберу, наверное, самый простой - просто создам символическую ссылку:
CODE (bash):
скопировать код в буфер обмена
  1. ln -s /opt/php-5.4.13/bin/php /usr/bin/php

- и получу таким образом рабочий php 5.4.13:
CODE (text):
скопировать код в буфер обмена
  1. root@host:/usr/lib/httpd/modules# php -v
  2. PHP 5.4.13 (cli) (built: Mar 15 2013 14:16:59)
  3. Copyright (c) 1997-2013 The PHP Group
  4. Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies


Хорошо, а если..
.. требуется два интерпретатора разных версий? Никаких трудностей. Проделываем то же самое для, например, php 5.3, получая в /opt/php-5.3.23 готовую версию для 5.3. Помним о том, что собственно, сам исполняемый CLI-файл у нас - это символическая ссылка. Переместив её на php 5.3 - получим, что в системе команде php будет соответствовать уже версия 5.3
Теперь про модуль веб-сервера. Идея примерно такая же - поскольку нам известно, где находится нужный модуль, ничто не мешает сделать его ссылкой:
CODE (bash):
скопировать код в буфер обмена
  1. root@host:/usr/lib/httpd/modules# mv libphp5.so libphp5.4.so
  2. root@host:/usr/lib/httpd/modules# ln -s libphp5.4.so libphp5.so

То же самое относится и к файлу php.ini, расположенному в /etc/httpd/php.ini в моей системе. Скорее всего, следует написать простой скрипт, меняющий ссылки для всех нужных файлов, однако я оставлю это читателю.
Вместо заключения, добавлю, что в подавляющем большинстве случаев ручная сборка не потребуется, достаточно удобно будет пользоваться тем, что предоставляет система. Если же вы решили собирать программы вручную, то вам придется четко понимать, для чего вы это делаете, а так же придерживаться некоторой структуры, чтобы не превратить систему в беспорядочный набор приложений. Например,
CODE (bash):
скопировать код в буфер обмена
  1. root@host:/opt# ls -la
  2. total 1
  3. drwxr-xr-x  7 root root 208 Mar 15 13:29 ./
  4. drwxr-xr-x 22 root root 536 Mar  6 10:37 ../
  5. drwxr-xr-x  5 root bin  152 Nov 22 15:55 cisco-vpnclient/
  6. drwxr-xr-x  4 root root  96 Oct 31 17:04 openoffice.org/
  7. drwxr-xr-x  5 root root 208 Oct 31 17:04 openoffice.org3/
  8. drwxr-xr-x  2 root root  48 Mar 15 13:29 php-5.3.23/
  9. drwxr-xr-x  7 root root 168 Mar 15 13:55 php-5.4.13/

- как видите, достаточно удобно хранить данные в определенном месте. Надеюсь, данный материал окажется доступным и полезным для решения задач по тонкой настройке системы для решения некоторых задач.
2. DeepVarvar - 15 Марта, 2013 - 16:53:51 - перейти к сообщению
Круто Теперь очередь за мной Закатив глазки
3. EuGen - 15 Марта, 2013 - 21:00:28 - перейти к сообщению
Если будет интересно, могу дополнить материалом по slack-билдам (впрочем, это актуально только для пользователей дистрибутива Slackware, которых я не встречал уже много лет)
4. DeepVarvar - 15 Марта, 2013 - 21:07:08 - перейти к сообщению
EuGen пишет:
которых я не встречал уже много лет
У меня земляк, которого я не встречал уже много лет, как оказалось на слаке сидит. Мне было бы интересно приобщиться слегка к "землячеству".
5. EuGen - 18 Марта, 2013 - 12:38:50 - перейти к сообщению
Дополнение - для пользователей дистрибутива Slackware и производных от него (наподобие Zenwalk, впрочем, я не использовал оные кроме как для тестов).
Немного предыстории - в Slackware всегда существовал пакетный менеджер, программа pkgtool - однако же, она работала не с репозиторием пакетов а с пакетами локальной машины. С недавнего же времени в Slackware существует пакетный менеджер slapt-get, который очень схож по функционалу с привычными, например, для Debian, apt-get.
Работа с этим пакетным менеджером не отличается от того же apt-get, потому не буду останавливаться на этой процедуре (кратко сводящейся к получению индекса с предопределенного списка зеркал и установке/обновлению пакетов по индексу).
Иногда же приходится работать с пакетами вне репозитория. Приведу пример - при работе мне требуется Cisco IPSec (cipsec), для соединения с дата-кластером продуктовой DMZ. Стандартно в Slackware, начиная с версии 14, присутствует портированный для KDE пакет NetworkManager, предоставляющий нативные средства для хранения профилей сетевой конфигурации и управления сетью. В целом, эта программа удобна для меня именно первым, потому что управлять сетью мне привычнее через консоль.
Закончив с этим отступлением, вернусь к VPN-модулю, который мне требуется - в NetworkManager это решается установкой плагина. Для того, чтобы это сделать, можно попытаться найти этот модуль через slapt-get - у меня не получилось (поскольку, вероятно, пакет не входит в стандартную поставку). После этого всегда остается возможность ручной сборки пакета. Для этого нужно:
0. Скачать slack-билд с ресурса, который их предоставляет. Здесь есть несколько вариантов, я остановился на slackbuilds.org - поскольку предоставляется простой интерфейс с поиском нужного, без излишеств (как, наверное, и все в Slackware).
1. После скачивания, требуется всего-навсего, запустить инсталационный скрипт. Например, я скачал исходные коды и slack-билд:
CODE (bash):
скопировать код в буфер обмена
  1. root@host:~/install/NetworkManager/NetworkManager-vpnc# ls -la
  2. total 352
  3. drwxr-xr-x 2 root root    280 Nov 20 11:45 ./
  4. drwxr-xr-x 3 root root     88 Nov 20 11:45 ../
  5. -rw-r--r-- 1 root root 336796 Nov 20 11:42 NetworkManager-vpnc-0.9.4.0.tar.xz
  6. -rwxr-xr-x 1 root root   2979 Oct  1 05:07 NetworkManager-vpnc.SlackBuild*
  7. -rw-r--r-- 1 root root    363 Sep 29 08:34 NetworkManager-vpnc.info
  8. -rw-r--r-- 1 root root     38 Sep 29 08:34 README
  9. -rwxr-xr-x 1 root root    320 Oct  1 05:07 doinst.sh*
  10. -rw-r--r-- 1 root root    787 Dec 11  2011 slack-desc

- как видно, файл NetworkManager-vpnc-0.9.4.0.tar.xz - это исходные данные для сборки пакета, а NetworkManager-vpnc.SlackBuild - это инсталяционный скрипт. Его-то и нужно запускать. После этого произойдет стандартная компиляция исходных кодов, и, если все было успешно, система сообщит целевой путь к готовому пакету:
CODE (bash):
скопировать код в буфер обмена
  1. install/
  2. install/doinst.sh
  3. install/slack-desc
  4. WARNING:  zero length file usr/doc/NetworkManager-vpnc-0.9.4.0/README
  5.  
  6. Slackware package /tmp/NetworkManager-vpnc-0.9.4.0-i486-2_SBo.tgz created.

2. Сборка на этом завершена, появился готовый пакет /tmp/NetworkManager-vpnc-0.9.4.0-i486-2_SBo.tgz:
CODE (bash):
скопировать код в буфер обмена
  1. root@host:~/install/NetworkManager/NetworkManager-vpnc# ls -la /tmp/NetworkManager-vpnc-0.9.4.0-i486-2_SBo.tgz
  2. -rw-r--r-- 1 root root 174268 Mar 18 14:26 /tmp/NetworkManager-vpnc-0.9.4.0-i486-2_SBo.tgz

остается только лишь установить его, это делается просто - достаточно перейти в каталог с пакетом и запустить команду installpkg:
CODE (bash):
скопировать код в буфер обмена
  1. root@host:~/install/NetworkManager/NetworkManager-vpnc# cd /tmp
  2. root@host:/tmp# installpkg NetworkManager-vpnc-0.9.4.0-i486-2_SBo.tgz

3. Все готово. Проверить установленный пакет можно с помощью все той же pkgtool:
Спойлер (Отобразить)
6. DeepVarvar - 18 Марта, 2013 - 12:55:15 - перейти к сообщению
EuGen пишет:
в Slackware всегда существовал пакетный менеджер, программа pkgtool - однако же, она работала не с репозиторием пакетов а с пакетами локальной машины.
EuGen пишет:
installpkg
Видимо это аналогия с dpkg в Debian.
CODE (bash):
скопировать код в буфер обмена
  1. # dpkg -i ./p/d/package-name.deb

Ключик -i не что иное как install.
По средствам сборки *deb-пакетов в/для Debian я никогда не пользовался,
поэтому надо гуглить.
Однако могу точно сказать что они есть - ведь пакеты как-то делаются Улыбка
7. EuGen - 18 Марта, 2013 - 13:00:34 - перейти к сообщению
Верно. Обзор, впрочем, был предоставлен с целью показать, как это происходит в Slackware. Сравнение с Debian - интересная и полезная идея. Соглашусь, что пакеты не сами по себе появляются, поэтому необходимость подобных инструментов очевидна.
Существенное отличие, что встроенного "централизованного" пакетного менеджера до некоторых пор в Slakware не было.

 

Powered by ExBB FM 1.0 RC1