Как скомпилировать Dev-сборку Phalcon?
После запуска русского чата на gitter.im выяснилось, что большинство людей не понимают, как устроен build phalcon, почему существует папка build, что такое компиляция из исходного кода (папки ext), и не знакомы с процессом сборки проекта, написанного на си. Эти вопросы мы затронем в данной статье. Процесс компиляции си-проекта я попытаюсь осветить полностью, чтобы убрать всю тень, покрывающую данный процесс.
Немного о настройке, препроцессоре, компиляции и линковке проекта.
Для тех, кто никогда не писал и не разбирался в си, я расскажу, из каких этапов состоит процесс сборки проекта.
Настройки
Этот этап присутствует только при работе с большими приложениями и в Phalcon он сведен к минимуму. Внутри php присутствует утилита для настройки компиляции, и называется она phpize, а также есть утилита php-config, которая может рассказать нам обо всех настройках в php.
Для того что бы настроить компиляцию нашего расширения, нужно зайти в папку расширения и выполнить:
cd ext
phpize
После запуска будет подготовлено окружения для компиляции PHP-расширения.
А теперь нужно сконфигурировать флаги для компилятора и препроцессора (пример для production компиляции):
./configure CFLAGS="-O2 -finline-functions -fomit-frame-pointer -fvisibility=hidden"
-O2
Она управляет включением уровня оптимизации. Существует семь видов настроек переменной -O
: -O0
, -O1
, -O2
, -O3
, -Os
, -Og
, и -Ofast
. Уровень O2 считают более оптимальным и принято за практику использовать его.
-finline-functions
Оптимизация для функций с модификатором inline.
-fomit-frame-pointer
Отключения отображения указателя в регистре, по умолчанию включена в уровне оптимизации -O
, -O2
, -O3
, -Os
.
-fvisibility
Области видимости.
Пример конфигурации для разработчика или отладки:
./configure CFLAGS="-g3 -O1 -fno-delete-null-pointer-checks -Wall -fvisibility=hidden"
-g3
Включения debug среды для показа более подробной информации в gdb.
-fno-delete-null-pointer-checks
Проверка на указатели.
-Wall
Включения повышенного режима обнаружения ошибок.
Препроцессор
Препроцессор — это компьютерная программа, принимающая данные на входе и выдающая данные, предназначенные для входа другой программы (например, компилятора). О данных на выходе препроцессора говорят, что они находятся в препроцессированной форме, пригодной для обработки последующими программами (компилятор). Результат и вид обработки зависят от вида препроцессора; так, некоторые препроцессоры могут только выполнить простую текстовую подстановку, другие способны по возможностям сравниться с языками программирования. Наиболее частый случай использования препроцессора — обработка исходного кода перед передачей его на следующий шаг компиляции. Языки программирования C/C++ и система компьютерной вёрстки TeX используют препроцессоры, значительно расширяющие их возможности. Данный текст я скопировал с википедии, но давайте возьмем пример. Я буду пользоваться компилятором g++.
Создадим файл example.cpp с содержанием
#include <cstdlib>
#include <iostream>
#define MY_TEXT 1
#define SIMPLE_MACROS(a, b) { \
cout << a << a << endl; \
cout << b << b << endl; \
}
using namespace std;
int main()
{
cout << MY_TEXT << endl;
SIMPLE_MACROS("1", "b");
return 1;
}
И запустим компилятор с флагом препроцессора
g++ -E example.cpp > output
А теперь просмотрим файл output. Мы видим, что строки вида
#include <cstdlib>
#include <iostream>
были заменены на контент данных файлов.
В строке с cout MY_TEXT был заменен на 1.
cout << 1 << endl;
А вызов макроса в строке изменен на код самого макроса:
{cout << "1" << "1" << endl; cout << "b" << "b" << endl;};
Это был небольшой пример работы препроцессора, в будущем обязательно вернусь к данной теме, но уже более подробно.
Компиляции и линковка
Компиляция — это процесс преобразования (трансляции) нашего исходного кода компилятором в эквивалентную программу на низкоуровневом языке. Так как программа состоит из множества файлов, то и компилируются они все по раздельности в бинарные файлы с расширениями .o. После того как программа скомпилировала все файлы, ей необходимо совместить все бинарные файлы, а это и называется линковкой. Так как для сборки расширения мы используем систему сборки проекта make, то нам просто нужно запустить команду без параметров и дождаться конца выполнения программы.
make
Установка
Вот и все. Наше расширение скомпилировано, и осталось его только установить. Благодаря тому, что для си-проектов используется система сборки make, нам лишь осталось просто запустить make с определенным файлом и дождаться конца копирования нашего расширения.
make install
Вы скажете, вроде бы все, а нет. Мы забыли самую простую часть нашего пути. Осталось дать настройку нашему php, прописав в ini-файл название расширения.
Пример редактирования файла конфигурации через редактор nano:
nano /etc/conf.d/phalcon.ini
И указать само название расширения:
exstension=phalcon.so
Что такое build?
Build – это склеенные си-файлы в один с дополнительными правками под битность системы. Они нужны для более быстрой компиляции и более мощных преобразований на уровне компилятора. Собираются они через скрипт, лежаший в ./build/gen-build.php, обычно за генерацией билдов следит человек из phalcon team (niden, phalcon, sjinks).
Так в итоге, как же скомпилировать Dev-сборку в 1 строку?
cd ext && phpize && ./configure CFLAGS="-g3 -O1 -fno-delete-null-pointer-checks -Wall -fvisibility=hidden" && make clean && make -B && sudo make install
Ну и все, наверное, что бы хотелось отметить по данной теме. Этой статьей я подвожу вас к понятиям компиляции, для того что бы в следующей статье поднять тему об оптимизациях и исполнении кода.