Сборка из исходников
Rapira собирается из исходников на Linux и macOS. Самостоятельная сборка закрывает те случаи, которые не покрывают готовые бинарники со страницы Установка, а единственное требование сверх обычных инструментов Rust и C — это PHP, который Rapira сможет встроить.
Когда собирать из исходников
- Для вашей платформы нет готового бинарника — необычная архитектура процессора или дистрибутив на musl вроде Alpine.
- Дистрибутив старше, чем поддерживают пакеты. Релизы собраны под glibc 2.34, так что самые старые системы, куда они встанут, — это Debian 12, Ubuntu 22.04 и RHEL 9 (подробности на странице Установка).
- Нужен другой набор расширений PHP. В релизные сборки вложен PHP, собранный по списку флагов из
ci/php-configure-flags.txt, а список этот намеренно короткий: session, mbstring, OPcache, OpenSSL, curl, семейство XML, PDO с SQLite. Если приложению нужныpdo_mysql,intlилиgd, соберите Rapira с тем PHP, где они есть. - Вы дорабатываете саму Rapira или хотите то, что ещё не попало в релиз.
Инструменты сборки
Кроме привычного набора для сборки понадобятся три вещи:
- Rust, стабильный канал. Версия закреплена в
rust-toolchain.tomlв репозитории, поэтому rustup сам выбирает нужный тулчейн. - Компилятор C и
pkg-config. Часть сборки написана на C — небольшие прослойки, которые компилируются с заголовками PHP. - libclang — привязки к Zend API генерирует bindgen прямо во время сборки. Пакет называется
libclang-devв Debian/Ubuntu,clang-develв Fedora иclangв Arch.
PHP с embed SAPI
Rapira линкует интерпретатор прямо в свой процесс, а не обращается к нему через сокет, поэтому PHP должен существовать в виде разделяемой библиотеки: версия 8.4 или 8.5, сборка NTS (непотокобезопасная), собранная с --enable-embed=shared — именно этот флаг и даёт libphp.so (на macOS — libphp.dylib).
Сборки ZTS отвергаются
Потокобезопасный (ZTS) PHP валит сборку с внятной ошибкой: Rapira работает только с NTS, потому что держит по одному интерпретатору на процесс-воркер. Если PHP в вашем PATH собран как ZTS, поставьте сборку NTS и укажите на неё через PHP_CONFIG (см. ниже).
В нескольких дистрибутивах embed SAPI уже лежит в пакетах:
sudo apt install php8.4-dev libphp8.4-embed # Debian/Ubuntu (deb.sury.org / ppa:ondrej)
sudo dnf install php-devel php-embedded # Fedora/RHEL
sudo pacman -S php php-embed # Arch
sudo apk add php84-dev php84-embed # AlpineВ macOS готового embed SAPI нет
Формула php в Homebrew собрана без него, так что линковаться просто не с чем. На macOS придётся собрать PHP из исходников.
Самостоятельная сборка PHP
Собирайте PHP сами, если в дистрибутиве нет пакета с embed SAPI, если вы работаете на macOS или если в пакетной сборке нет расширений, которые нужны вашему приложению.
Эталонная строка configure лежит в репозитории — это ci/php-configure-flags.txt, тот самый список, по которому собираются релизы. Передайте его в configure в распакованных исходниках PHP и допишите расширения, которые нужны вашему приложению:
./configure --prefix="$HOME/.local/php-nts" $(tr '\n' ' ' < /path/to/rapira/ci/php-configure-flags.txt)
make -j"$(getconf _NPROCESSORS_ONLN)"
make installНа macOS сначала поставьте зависимости (brew install pkg-config openssl@3 curl oniguruma libxml2 sqlite), добавьте их каталоги lib/pkgconfig в PKG_CONFIG_PATH, а после файла с флагами допишите --with-iconv="$(xcrun --show-sdk-path)/usr": голый --with-iconv там libiconv не находит, а в autoconf побеждает последнее вхождение.
Простое имя libphp.so
Сборка линкуется с -lphp и ищет библиотеку только в lib и lib64 внутри префикса PHP, поэтому файл ровно с именем libphp.so (или libphp.dylib) должен лежать в одном из них. Debian и Ubuntu кладут только версионный libphp8.4.so, у Alpine имя простое, но сам файл лежит в lib/phpXX, который сборка не просматривает. И там, и там линковка падает, пока вы не положите в lib или lib64 префикса симлинк с простым именем:
sudo ln -sf /usr/lib/libphp8.4.so /usr/lib/libphp.so # Debian/Ubuntu
sudo ln -sf /usr/lib/php84/libphp.so /usr/lib/libphp.so # AlpineЕсли прав root нет, сделайте симлинк в своём каталоге и покажите на него и линковщику, и загрузчику:
mkdir -p ~/.local/phplib
ln -sf /usr/lib/libphp8.4.so ~/.local/phplib/libphp.so
export RUSTFLAGS="-L native=$HOME/.local/phplib"
export LD_LIBRARY_PATH="$HOME/.local/phplib:/usr/lib"Сборка Rapira
Когда PHP на месте, дальше всё как в любом проекте на Rust — обычная сборка через cargo:
git clone https://github.com/rapira-rs/rapira.git
cd rapira
cargo build --releaseГотовый бинарник окажется в target/release/rapira.
PHP находится через php-config. Если тот, что лежит в PATH, — не та сборка, которую вы хотите встроить, укажите нужную явно:
PHP_CONFIG=$HOME/.local/php-nts/bin/php-config cargo build --releasemake test прогоняет наборы тестов и сам определяет пути к библиотекам: находит embed-библиотеку внутри префикса php-config (lib, lib64, lib/phpXX, простое или версионное имя) и приводит её к простому имени, которого ждёт линковщик. Запустите make test, чтобы проверить окружение, прежде чем полагаться на собственную сборку.
Запуск собранного бинарника
Во время работы Rapira подгружает libphp.so (на macOS — libphp.dylib) динамически. Если библиотека лежит в стандартном месте, делать ничего не нужно; если нет — укажите загрузчику путь к ней:
LD_LIBRARY_PATH="$HOME/.local/php-nts/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" ./target/release/rapira serve worker.php # Linux
DYLD_LIBRARY_PATH="$HOME/.local/php-nts/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" ./target/release/rapira serve worker.php # macOSВ результате получается тот же сервер, что ставится из пакетов: Быстрый старт проведёт через первый скрипт, Командная строка перечисляет всё, что принимает serve, а Конфигурация разбирает rapira.toml.
Разработка самой Rapira
make test прогоняет оба набора тестов — внутрипроцессный и сквозной, который запускает настоящий бинарник; make stubs перегенерирует заголовок с arginfo из crates/php_sys/rapira.stub.php; а CI на каждый пул-реквест собирает проект и гоняет cargo fmt, clippy и покрытие.