Files
archived-frankenphp/build-static.sh
Kévin Dunglas 6268015b3a ci: fallback on static-php.dev mirror when php.net is down (#2233)
Unfortunately, GitHub Actions is often blocked by the php.net CDN. This
patch adds a fallback to use GitHub to try to determine the PHP version
to use. This is less ideal because PHP currently doesn't use GitHub
extensively, and distribution archives aren't available in the GitHub
releases, only on php.net.
2026-03-05 17:50:21 +01:00

239 lines
7.7 KiB
Bash
Executable File

#!/bin/bash
set -o errexit
set -x
if ! type "git" >/dev/null 2>&1; then
echo "The \"git\" command must be installed."
exit 1
fi
CURRENT_DIR=$(pwd)
arch="$(uname -m)"
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
[ "$os" = "darwin" ] && os="mac"
# Supported variables:
# - PHP_VERSION: PHP version to build (default: "8.4")
# - PHP_EXTENSIONS: PHP extensions to build (default: ${defaultExtensions} set below)
# - PHP_EXTENSION_LIBS: PHP extension libraries to build (default: ${defaultExtensionLibs} set below)
# - FRANKENPHP_VERSION: FrankenPHP version (default: current Git commit)
# - EMBED: Path to the PHP app to embed (default: none)
# - DEBUG_SYMBOLS: Enable debug symbols if set to 1 (default: none)
# - MIMALLOC: Use mimalloc as the allocator if set to 1 (default: none)
# - XCADDY_ARGS: Additional arguments to pass to xcaddy
# - RELEASE: [maintainer only] Create a GitHub release if set to 1 (default: none)
# - SPC_REL_TYPE: Release type to download (accept "source" and "binary", default: "source")
# - SPC_OPT_BUILD_ARGS: Additional arguments to pass to spc build
# - SPC_OPT_DOWNLOAD_ARGS: Additional arguments to pass to spc download
# - SPC_LIBC: Set to glibc to build with GNU toolchain (default: musl)
# init spc command, if we use spc binary, just use it instead of fetching source
if [ -z "${SPC_REL_TYPE}" ]; then
SPC_REL_TYPE="source"
fi
# init spc libc
if [ -z "${SPC_LIBC}" ]; then
if [ "${os}" = "linux" ]; then
SPC_LIBC="musl"
fi
fi
# init spc build additional args
if [ -z "${SPC_OPT_BUILD_ARGS}" ]; then
SPC_OPT_BUILD_ARGS=""
fi
if [ "${SPC_LIBC}" = "musl" ] && [[ "${SPC_OPT_BUILD_ARGS}" != *"--disable-opcache-jit"* ]]; then
SPC_OPT_BUILD_ARGS="${SPC_OPT_BUILD_ARGS} --disable-opcache-jit"
fi
# init spc download additional args
if [ -z "${SPC_OPT_DOWNLOAD_ARGS}" ]; then
SPC_OPT_DOWNLOAD_ARGS="--ignore-cache-sources=php-src --retry 5"
if [ "${SPC_LIBC}" = "musl" ]; then
SPC_OPT_DOWNLOAD_ARGS="${SPC_OPT_DOWNLOAD_ARGS} --prefer-pre-built"
fi
fi
# if we need debug symbols, disable strip
if [ -n "${DEBUG_SYMBOLS}" ]; then
SPC_OPT_BUILD_ARGS="${SPC_OPT_BUILD_ARGS} --no-strip"
fi
# php version to build
if [ -z "${PHP_VERSION}" ]; then
get_latest_php_version() {
input="$1"
json=$(curl -fsSL "https://www.php.net/releases/index.php?json&version=$input" 2>/dev/null || curl -fsSL "https://phpmirror.static-php.dev/releases/index.php?json&version=$input")
latest=$(echo "$json" | jq -r '.version')
if [[ "$latest" == "$input"* ]]; then
echo "$latest"
else
echo "$input"
fi
}
PHP_VERSION="$(get_latest_php_version "8.5")"
export PHP_VERSION
fi
# default extension set
defaultExtensions="amqp,apcu,ast,bcmath,brotli,bz2,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,ftp,gd,gmp,gettext,iconv,igbinary,imagick,intl,ldap,lz4,mbregex,mbstring,memcached,mysqli,mysqlnd,opcache,openssl,password-argon2,parallel,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,pgsql,phar,posix,protobuf,readline,redis,session,shmop,simplexml,soap,sockets,sodium,sqlite3,ssh2,sysvmsg,sysvsem,sysvshm,tidy,tokenizer,xlswriter,xml,xmlreader,xmlwriter,xsl,xz,zip,zlib,yaml,zstd"
defaultExtensionLibs="libavif,nghttp2,nghttp3,ngtcp2,watcher"
if [ -z "${FRANKENPHP_VERSION}" ]; then
FRANKENPHP_VERSION="$(git rev-parse --verify HEAD)"
export FRANKENPHP_VERSION
elif [ -d ".git/" ]; then
CURRENT_REF="$(git rev-parse --abbrev-ref HEAD)"
export CURRENT_REF
if echo "${FRANKENPHP_VERSION}" | grep -F -q "."; then
# Tag
# Trim "v" prefix if any
FRANKENPHP_VERSION=${FRANKENPHP_VERSION#v}
export FRANKENPHP_VERSION
git checkout "v${FRANKENPHP_VERSION}"
else
git checkout "${FRANKENPHP_VERSION}"
fi
fi
if [ -n "${CLEAN}" ]; then
rm -Rf dist/
go clean -cache
fi
mkdir -p dist/
cd dist/
if type "brew" >/dev/null 2>&1; then
if ! type "composer" >/dev/null; then
packages="composer"
fi
if ! type "go" >/dev/null 2>&1; then
packages="${packages} go"
fi
if [ -n "${RELEASE}" ] && ! type "gh" >/dev/null 2>&1; then
packages="${packages} gh"
fi
if [ -n "${packages}" ]; then
# shellcheck disable=SC2086
brew install --formula --quiet ${packages}
fi
fi
if [ "${SPC_REL_TYPE}" = "binary" ]; then
mkdir -p static-php-cli/
cd static-php-cli/
if [[ "${arch}" =~ "arm" ]]; then
dl_arch="aarch64"
else
dl_arch="${arch}"
fi
curl -o spc -fsSL "https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-${dl_arch}"
chmod +x spc
spcCommand="./spc"
elif [ -d "static-php-cli/src" ]; then
cd static-php-cli/
git pull
composer install --no-dev -a --no-interaction
spcCommand="./bin/spc"
else
git clone --depth 1 https://github.com/crazywhalecc/static-php-cli --branch main
cd static-php-cli/
composer install --no-dev -a --no-interaction
spcCommand="./bin/spc"
fi
# turn potentially relative EMBED path into absolute path
if [ -n "${EMBED}" ]; then
if [[ "${EMBED}" != /* ]]; then
EMBED="${CURRENT_DIR}/${EMBED}"
fi
fi
# Extensions to build
if [ -z "${PHP_EXTENSIONS}" ]; then
# enable EMBED mode, first check if project has dumped extensions
if [ -n "${EMBED}" ] && [ -f "${EMBED}/composer.json" ] && [ -f "${EMBED}/composer.lock" ] && [ -f "${EMBED}/vendor/composer/installed.json" ]; then
cd "${EMBED}"
# read the extensions using spc dump-extensions
PHP_EXTENSIONS=$(${spcCommand} dump-extensions "${EMBED}" --format=text --no-dev --no-ext-output="${defaultExtensions}")
else
PHP_EXTENSIONS="${defaultExtensions}"
fi
fi
# Additional libraries to build
if [ -z "${PHP_EXTENSION_LIBS}" ]; then
PHP_EXTENSION_LIBS="${defaultExtensionLibs}"
fi
# The Brotli library must always be built as it is required by http://github.com/dunglas/caddy-cbrotli
if ! echo "${PHP_EXTENSION_LIBS}" | grep -q "\bbrotli\b"; then
PHP_EXTENSION_LIBS="${PHP_EXTENSION_LIBS},brotli"
fi
# The mimalloc library must be built if MIMALLOC is true
if [ -n "${MIMALLOC}" ]; then
if ! echo "${PHP_EXTENSION_LIBS}" | grep -q "\bmimalloc\b"; then
PHP_EXTENSION_LIBS="${PHP_EXTENSION_LIBS},mimalloc"
fi
fi
# Embed PHP app, if any
if [ -n "${EMBED}" ] && [ -d "${EMBED}" ]; then
# shellcheck disable=SC2089
SPC_OPT_BUILD_ARGS="${SPC_OPT_BUILD_ARGS} --with-frankenphp-app='${EMBED}'"
fi
SPC_OPT_INSTALL_ARGS="go-xcaddy"
if [ -z "${DEBUG_SYMBOLS}" ] && [ -z "${NO_COMPRESS}" ] && [ "${os}" = "linux" ]; then
SPC_OPT_BUILD_ARGS="${SPC_OPT_BUILD_ARGS} --with-upx-pack"
SPC_OPT_INSTALL_ARGS="${SPC_OPT_INSTALL_ARGS} upx"
fi
export SPC_DEFAULT_C_FLAGS="-fPIC -O2"
if [ -n "${DEBUG_SYMBOLS}" ]; then
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS} -fPIE -g"
else
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS} -fPIE -fstack-protector-strong -O2 -w -s"
fi
export SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS
if [ -z "$SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES" ]; then
export SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
fi
# Build FrankenPHP
${spcCommand} doctor --auto-fix
for pkg in ${SPC_OPT_INSTALL_ARGS}; do
${spcCommand} install-pkg "${pkg}"
done
# shellcheck disable=SC2086
${spcCommand} download --with-php="${PHP_VERSION}" --for-extensions="${PHP_EXTENSIONS}" --for-libs="${PHP_EXTENSION_LIBS}" ${SPC_OPT_DOWNLOAD_ARGS}
export FRANKENPHP_SOURCE_PATH="${CURRENT_DIR}"
# shellcheck disable=SC2086,SC2090
${spcCommand} build --enable-zts --build-embed --build-frankenphp ${SPC_OPT_BUILD_ARGS} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}"
if [ -n "$CI" ]; then
rm -rf ./downloads
rm -rf ./source
fi
cd ../..
bin="dist/frankenphp-${os}-${arch}"
cp "dist/static-php-cli/buildroot/bin/frankenphp" "${bin}"
"${bin}" version
"${bin}" build-info
if [ -n "${RELEASE}" ]; then
gh release upload "v${FRANKENPHP_VERSION}" "${bin}" --repo dunglas/frankenphp --clobber
fi
if [ -n "${CURRENT_REF}" ]; then
git checkout "${CURRENT_REF}"
fi