Возможность ручной сборки - не прерогатива 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):
скопировать код в буфер обмена
скопировать код в буфер обмена
- wget -Ophp-5.4.13.tar.bz2 http://www.php.net/get/php-5.4.13.tar.bz2/from/de1.php.net/mirror