Skip to content

Add PHP 8.5 support #819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5f2459a
Avoid useless exception on startup version mismatch
crazywhalecc Jul 15, 2025
ec959f6
Add 8.5 patch support for phpmicro
crazywhalecc Jul 15, 2025
b9e096a
Download alpha version for 8.5
crazywhalecc Jul 15, 2025
88cf018
extension test
crazywhalecc Jul 15, 2025
d3f8e94
Use new branch of micro, extension test
crazywhalecc Jul 15, 2025
dc8f7de
Merge branch 'main' into php-85
crazywhalecc Jul 15, 2025
1ce3ba0
Update docs and READMEs
crazywhalecc Jul 15, 2025
5838c87
Merge remote-tracking branch 'origin/php-85' into php-85
crazywhalecc Jul 15, 2025
f061259
Test bulk (without amqp, swoole) and spc-max
crazywhalecc Jul 15, 2025
fb106a3
Merge branch 'refs/heads/main' into php-85
crazywhalecc Jul 28, 2025
85e89e4
alpha2
crazywhalecc Jul 28, 2025
973c8f0
Add php-src git version support
crazywhalecc Jul 28, 2025
0696acb
Add support for re2c in tool checklists and environment setup
crazywhalecc Jul 28, 2025
1ae0752
Trigger full extension test
crazywhalecc Jul 28, 2025
b9bec5b
Whoops, extension test
crazywhalecc Jul 28, 2025
4efb3df
Add check for Bison version in MacOS tool checklist, trigger extensio…
crazywhalecc Jul 28, 2025
e9dbeb1
Refactor opcache JIT handling and version checks in Linux and MacOS b…
crazywhalecc Jul 29, 2025
ed67393
Move opcache JIT handling from Linux and MacOS builders to Extension
crazywhalecc Jul 29, 2025
9ed3c8b
phpstan
crazywhalecc Jul 29, 2025
5f5d934
Add openssl argon2 password hash support for PHP 8.5
crazywhalecc Jul 30, 2025
af10cac
Add openssl version getter for Windows, test openssl
crazywhalecc Jul 30, 2025
0dfa6e6
Fix dev:lib-version command with dependencies
crazywhalecc Jul 30, 2025
357c04d
Merge branch 'main' into php-85
crazywhalecc Jul 30, 2025
5f33a07
Fix windows builds when unix configure does not exist
crazywhalecc Jul 30, 2025
fcdb029
Install re2c manually in gnu docker
crazywhalecc Jul 30, 2025
cb0ea67
Fix x86_64 macOS bison finder path
crazywhalecc Jul 30, 2025
6984c29
suggestion
crazywhalecc Jul 30, 2025
3c972ac
Add re2c build
crazywhalecc Jul 30, 2025
601444d
Add re2c build for spc-gnu-docker
crazywhalecc Jul 30, 2025
be85791
Add alt for re2c
crazywhalecc Jul 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ext-matrix-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ jobs:
- zlib
- zstd
php-version:
- "8.4"
- "git"
operating-system:
- "ubuntu-latest"
- "ubuntu-24.04"
#- "macos-13"
#- "debian-arm64-self-hosted"
- "macos-14"
Expand Down
21 changes: 11 additions & 10 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,17 @@ static-php-cli(简称 `spc`)有许多特性:
>
> :x: 不支持
| PHP Version | Status | Comment |
|-------------|--------------------|----------------------------------------------|
| 7.2 | :x: | |
| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
| 8.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新 |
| 8.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | |
| 8.4 | :heavy_check_mark: | |
| PHP Version | Status | Comment |
|-------------|--------------------|---------------------------------------------------------|
| 7.2 | :x: | |
| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
| 8.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新,在 8.5 发布后我们不再处理 8.1 相关的 backport 支持 |
| 8.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | |
| 8.4 | :heavy_check_mark: | |
| 8.5 | :heavy_check_mark: | |

> 这个表格的支持状态是 static-php-cli 对构建对应版本的支持情况,不是 PHP 官方对该版本的支持情况。
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ Currently supported PHP versions for compilation:
| 7.3 | :x: | phpmicro and some extensions not supported on 7.x |
| 7.4 | :x: | phpmicro and some extensions not supported on 7.x |
| 8.0 | :warning: | PHP official has stopped maintenance of 8.0, we no longer provide backport support for version 8.0 |
| 8.1 | :heavy_check_mark: | PHP official has security fixes only |
| 8.1 | :heavy_check_mark: | PHP official has security fixes only, we no longer provide backport support when 8.5 released |
| 8.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | |
| 8.4 | :heavy_check_mark: | |
| 8.5 (alpha) | :heavy_check_mark: | |


> This table shows the support status for static-php-cli in building the corresponding version,
> not the official PHP support status for that version.
Expand Down
1 change: 1 addition & 0 deletions bin/spc-alpine-docker
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ RUN apk update; \
m4 \
make \
pkgconfig \
re2c \
wget \
xz \
gettext-dev \
Expand Down
2 changes: 1 addition & 1 deletion config/source.json
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@
"micro": {
"type": "git",
"path": "php-src/sapi/micro",
"rev": "84beta",
"rev": "master",
"url": "https://github.com/static-php/phpmicro",
"license": {
"type": "file",
Expand Down
1 change: 1 addition & 0 deletions docs/.vitepress/components/CliGenerator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ const availablePhpVersions = [
'8.2',
'8.3',
'8.4',
'8.5',
];
const I18N = {
Expand Down
2 changes: 1 addition & 1 deletion docs/en/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Windows currently only supports the x86_64 architecture, and does not support 32

## Supported PHP Version

Currently, static php cli supports PHP versions 8.1 to 8.4, and theoretically supports PHP 8.0 and earlier versions.
Currently, static php cli supports PHP versions 8.1 to 8.5, and theoretically supports PHP 8.0 and earlier versions.
Simply select the earlier version when downloading.
However, due to some extensions and special components that have stopped supporting earlier versions of PHP,
static-php-cli will not explicitly support earlier versions.
Expand Down
4 changes: 2 additions & 2 deletions docs/en/guide/manual-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ Also, it is available when downloading with the `--for-extensions` option.


```bash
# Specifying to download a beta version of PHP8.3
bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"
# Specifying to download a alpha version of PHP 8.5
bin/spc download --all -U "php-src:https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz"
# Specifying to download an older version of the curl library
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ Windows 目前只支持 x86_64 架构,不支持 32 位 x86、不支持 arm64

## PHP 支持版本

目前,static-php-cli 对 PHP 8.1 ~ 8.4 版本是支持的,对于 PHP 8.0 及更早版本理论上支持,只需下载时选择早期版本即可。
目前,static-php-cli 对 PHP 8.1 ~ 8.5 版本是支持的,对于 PHP 8.0 及更早版本理论上支持,只需下载时选择早期版本即可。
但由于部分扩展和特殊组件已对早期版本的 PHP 停止了支持,所以 static-php-cli 不会明确支持早期版本。
我们推荐你编译尽可能新的 PHP 版本,以获得更好的体验。
4 changes: 2 additions & 2 deletions docs/zh/guide/manual-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ bin/spc download --from-zip=/path/to/your/download.zip
让下载器强制使用你指定的链接下载此 source 的包。使用方法为 `{source-name}:{url}` 即可,可同时重写多个库的下载地址。在使用 `--for-extensions` 选项下载时同样可用。

```bash
# 例如:指定下载测试版的 PHP8.3
bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"
# 例如:指定下载 Alpha 版的 PHP8.5
bin/spc download --all -U "php-src:https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz"

# 指定下载旧版本的 curl 库
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
Expand Down
11 changes: 8 additions & 3 deletions src/SPC/builder/BuilderBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,16 +337,21 @@ public function getPHPVersionID(): int
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
}

public function getPHPVersion(): string
public function getPHPVersion(bool $exception_on_failure = true): string
{
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
if (!$exception_on_failure) {
return 'unknown';
}
throw new WrongUsageException('PHP source files are not available, you need to download them first');
}
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
if (preg_match('/PHP_VERSION "(.*)"/', $file, $match) !== 0) {
return $match[1];
}

if (!$exception_on_failure) {
return 'unknown';
}
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
}

Expand All @@ -364,7 +369,7 @@ public function getPHPVersionFromArchive(?string $file = null): false|string
}
$file = LockFile::getLockFullPath($lock);
}
if (preg_match('/php-(\d+\.\d+\.\d+(?:RC\d+)?)\.tar\.(?:gz|bz2|xz)/', $file, $match)) {
if (preg_match('/php-(\d+\.\d+\.\d+(?:RC\d+|alpha\d+|beta\d+)?)\.tar\.(?:gz|bz2|xz)/', $file, $match)) {
return $match[1];
}
return false;
Expand Down
21 changes: 17 additions & 4 deletions src/SPC/builder/extension/opcache.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,38 @@ public function validate(): void

public function patchBeforeBuildconf(): bool
{
$version = $this->builder->getPHPVersion();
if (file_exists(SOURCE_PATH . '/php-src/.opcache_patched')) {
return false;
}
// if 8.2.0 <= PHP_VERSION < 8.2.23, we need to patch from legacy patch file
if (version_compare($this->builder->getPHPVersion(), '8.2.0', '>=') && version_compare($this->builder->getPHPVersion(), '8.2.23', '<')) {
if (version_compare($version, '8.2.0', '>=') && version_compare($version, '8.2.23', '<')) {
SourcePatcher::patchFile('spc_fix_static_opcache_before_80222.patch', SOURCE_PATH . '/php-src');
}
// if 8.3.0 <= PHP_VERSION < 8.3.11, we need to patch from legacy patch file
elseif (version_compare($this->builder->getPHPVersion(), '8.3.0', '>=') && version_compare($this->builder->getPHPVersion(), '8.3.11', '<')) {
elseif (version_compare($version, '8.3.0', '>=') && version_compare($version, '8.3.11', '<')) {
SourcePatcher::patchFile('spc_fix_static_opcache_before_80310.patch', SOURCE_PATH . '/php-src');
} else {
}
// if 8.3.12 <= PHP_VERSION < 8.5.0-dev, we need to patch from legacy patch file
elseif (version_compare($version, '8.5.0-dev', '<')) {
SourcePatcher::patchMicro(items: ['static_opcache']);
}
// PHP 8.5.0-dev and later supports static opcache without patching
else {
return false;
}
return file_put_contents(SOURCE_PATH . '/php-src/.opcache_patched', '1') !== false;
}

public function getUnixConfigureArg(bool $shared = false): string
{
return '--enable-opcache';
$version = $this->builder->getPHPVersion();
$opcache_jit = !$this->builder->getOption('disable-opcache-jit', false);
$opcache_jit = $opcache_jit ? '--enable-opcache-jit' : '--disable-opcache-jit';
if (version_compare($version, '8.5.0-dev', '<')) {
return "--enable-opcache {$opcache_jit}";
}
return $opcache_jit;
}

public function getDistName(): string
Expand Down
4 changes: 1 addition & 3 deletions src/SPC/builder/linux/LinuxBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
$maxExecutionTimers = '';
$zts = '';
}
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';

$config_file_path = $this->getOption('with-config-file-path', false) ?
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
Expand Down Expand Up @@ -120,7 +119,6 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
($enableMicro ? '--enable-micro=all-static ' : '--disable-micro ') .
$config_file_path .
$config_file_scan_dir .
$disable_jit .
$json_74 .
$zts .
$maxExecutionTimers .
Expand Down Expand Up @@ -265,7 +263,7 @@ protected function buildEmbed(): void
->exec('sed -i "s|^EXTENSION_DIR = .*|EXTENSION_DIR = /' . basename(BUILD_MODULES_PATH) . '|" Makefile')
->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install");

$ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS');
$ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS') ?: '';
if (preg_match('/-release\s+(\S+)/', $ldflags, $matches)) {
$release = $matches[1];
$realLibName = 'libphp-' . $release . '.so';
Expand Down
3 changes: 2 additions & 1 deletion src/SPC/builder/macos/MacOSBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this);

$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
$phpVersionID = $this->getPHPVersionID();
$json_74 = $phpVersionID < 80000 ? '--enable-json ' : '';
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';

$config_file_path = $this->getOption('with-config-file-path', false) ?
Expand Down
3 changes: 2 additions & 1 deletion src/SPC/command/BuildPHPCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public function handle(): int
$indent_texts['UPX Pack'] = 'enabled';
}

$ver = $builder->getPHPVersionFromArchive() ?: $builder->getPHPVersion();
$ver = $builder->getPHPVersionFromArchive() ?: $builder->getPHPVersion(false);
$indent_texts['PHP Version'] = $ver;

if (!empty($not_included)) {
Expand Down Expand Up @@ -269,6 +269,7 @@ public function handle(): int
} catch (WrongUsageException $e) {
// WrongUsageException is not an exception, it's a user error, so we just print the error message
logger()->critical($e->getMessage());
logger()->error($e->getTraceAsString());
return static::FAILURE;
} catch (\Throwable $e) {
if ($this->getOption('debug')) {
Expand Down
9 changes: 3 additions & 6 deletions src/SPC/command/DownloadCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,9 @@ public function handle(): int
// Define PHP major version
$ver = $this->php_major_ver = $this->getOption('with-php');
define('SPC_BUILD_PHP_VERSION', $ver);
// match x.y
preg_match('/^\d+\.\d+$/', $ver, $matches);
if (!$matches) {
// match x.y.z
preg_match('/^\d+\.\d+\.\d+$/', $ver, $matches);
if (!$matches) {
if ($ver !== 'git' && !preg_match('/^\d+\.\d+$/', $ver)) {
// If not git, we need to check the version format
if (!preg_match('/^\d+\.\d+(\.\d+)?$/', $ver)) {
logger()->error("bad version arg: {$ver}, x.y or x.y.z required!");
return static::FAILURE;
}
Expand Down
6 changes: 3 additions & 3 deletions src/SPC/doctor/item/LinuxToolCheckList.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class LinuxToolCheckList
use UnixSystemUtilTrait;

public const TOOLS_ALPINE = [
'make', 'bison', 'flex',
'make', 'bison', 're2c', 'flex',
'git', 'autoconf', 'automake', 'gettext-dev',
'tar', 'unzip', 'gzip',
'bzip2', 'cmake', 'gcc',
Expand All @@ -26,7 +26,7 @@ class LinuxToolCheckList
];

public const TOOLS_DEBIAN = [
'make', 'bison', 'flex',
'make', 'bison', 're2c', 'flex',
'git', 'autoconf', 'automake', 'autopoint',
'tar', 'unzip', 'gzip',
'bzip2', 'cmake', 'patch',
Expand All @@ -35,7 +35,7 @@ class LinuxToolCheckList
];

public const TOOLS_RHEL = [
'perl', 'make', 'bison', 'flex',
'perl', 'make', 'bison', 're2c', 'flex',
'git', 'autoconf', 'automake',
'tar', 'unzip', 'gzip', 'gcc',
'bzip2', 'cmake', 'patch', 'which',
Expand Down
25 changes: 25 additions & 0 deletions src/SPC/doctor/item/MacOSToolCheckList.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class MacOSToolCheckList
'curl',
'make',
'bison',
're2c',
'flex',
'pkg-config',
'git',
Expand Down Expand Up @@ -61,6 +62,30 @@ public function checkCliTools(): ?CheckResult
return CheckResult::ok();
}

#[AsCheckItem('if bison version is 3.0 or later', limit_os: 'Darwin')]
public function checkBisonVersion(array $command_path = []): ?CheckResult
{
// if the bison command is /usr/bin/bison, it is the system bison that may be too old
if (($bison = $this->findCommand('bison', $command_path)) === null) {
return CheckResult::fail('bison is not installed or too old', 'build-tools', [['bison']]);
}
// check version: bison (GNU Bison) x.y(.z)
$version = shell()->execWithResult("{$bison} --version", false);
if (preg_match('/bison \(GNU Bison\) (\d+)\.(\d+)(?:\.(\d+))?/', $version[1][0], $matches)) {
$major = (int) $matches[1];
// major should be 3 or later
if ($major < 3) {
// find homebrew keg-only bison
if ($command_path !== []) {
return CheckResult::fail("Current {$bison} version is too old: " . $matches[0]);
}
return $this->checkBisonVersion(['/opt/homebrew/opt/bison/bin', '/usr/local/homebrew/opt/bison/bin']);
}
return CheckResult::ok($matches[0]);
}
return CheckResult::fail('bison version cannot be determined');
}

#[AsFixItem('brew')]
public function fixBrew(): bool
{
Expand Down
2 changes: 1 addition & 1 deletion src/SPC/store/SourcePatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public static function patchMicro(?array $items = null): bool
}
$patch_list = $spc_micro_patches;
$patches = [];
$serial = ['80', '81', '82', '83', '84'];
$serial = ['80', '81', '82', '83', '84', '85'];
foreach ($patch_list as $patchName) {
if (file_exists(SOURCE_PATH . "/php-src/sapi/micro/patches/{$patchName}.patch")) {
$patches[] = "sapi/micro/patches/{$patchName}.patch";
Expand Down
10 changes: 8 additions & 2 deletions src/SPC/store/source/PhpSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ class PhpSource extends CustomSourceBase
*/
public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWNLOAD_SOURCE): void
{
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.3';
Downloader::downloadSource('php-src', self::getLatestPHPInfo($major), $force);
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.4';
if ($major === '8.5') {
Downloader::downloadSource('php-src', ['type' => 'url', 'url' => 'https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz'], $force);
} elseif ($major === 'git') {
Downloader::downloadSource('php-src', ['type' => 'git', 'url' => 'https://github.com/php/php-src.git', 'rev' => 'master'], $force);
} else {
Downloader::downloadSource('php-src', self::getLatestPHPInfo($major), $force);
}
}

/**
Expand Down
10 changes: 10 additions & 0 deletions src/SPC/util/GlobalEnvManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace SPC\util;

use SPC\builder\macos\SystemUtil;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\toolchain\ToolchainManager;
Expand Down Expand Up @@ -111,6 +112,15 @@ public static function afterInit(): void
if (!filter_var(getenv('SPC_SKIP_TOOLCHAIN_CHECK'), FILTER_VALIDATE_BOOL)) {
ToolchainManager::afterInitToolchain();
}
// test bison
if (PHP_OS_FAMILY === 'Darwin') {
if ($bison = SystemUtil::findCommand('bison', ['/opt/homebrew/opt/bison/bin', '/usr/local/homebrew/opt/bison/bin'])) {
self::putenv("BISON={$bison}");
}
if ($yacc = SystemUtil::findCommand('yacc', ['/opt/homebrew/opt/bison/bin', '/usr/local/homebrew/opt/bison/bin'])) {
self::putenv("YACC={$yacc}");
}
}
}

/**
Expand Down
Loading
Loading