From 656a58c3fad9e5c4075ba9fd79c7ec4830e0048f Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 09:58:45 +0100 Subject: [PATCH 01/34] remove source dir after successful build in CI environment --- src/SPC/builder/LibraryBase.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index c88e8d96c..0018868fa 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -195,6 +195,9 @@ public function tryBuild(bool $force_build = false): int $this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build'); $this->build(); $this->installLicense(); + if (getenv('CI')) { + FileSystem::removeDir($this->source_dir); + } $this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-build'); return LIB_STATUS_OK; } From 024745885321448a70cdfc7e0a9b514a1bae21cf Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 11:06:21 +0100 Subject: [PATCH 02/34] we were installing to wrong dir if source name != lib name --- src/SPC/builder/LibraryBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 0018868fa..9d676b245 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -357,11 +357,11 @@ protected function installLicense(): void } foreach ($license_files as $index => $license) { if ($license['type'] === 'text') { - FileSystem::writeFile(BUILD_ROOT_PATH . '/source-licenses/' . $this->getName() . "/{$index}.txt", $license['text']); + FileSystem::writeFile(BUILD_ROOT_PATH . "/source-licenses/{$source}/{$index}.txt", $license['text']); continue; } if ($license['type'] === 'file') { - copy($this->source_dir . '/' . $license['path'], BUILD_ROOT_PATH . '/source-licenses/' . $this->getName() . "/{$index}.txt"); + copy($this->source_dir . '/' . $license['path'], BUILD_ROOT_PATH . "/source-licenses/{$source}/{$index}.txt"); } } } From ce44e00bd40afeb03d7a27671510f1b6846d3a85 Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 12:35:06 +0100 Subject: [PATCH 03/34] @crazywhalecc how to use patch points to delete source dirs? --- src/SPC/builder/Extension.php | 3 +++ src/SPC/builder/LibraryBase.php | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index 08b403e61..0df87e912 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -385,6 +385,9 @@ public function buildShared(array $visited = []): void logger()->info('Shared extension [' . $this->getName() . '] was already built, skipping (' . $this->getName() . '.so)'); return; } + if (Config::getExt($this->getName(), 'type') === 'addon') { + return; + } logger()->info('Building extension [' . $this->getName() . '] as shared extension (' . $this->getName() . '.so)'); foreach ($this->dependencies as $dependency) { if (!$dependency instanceof Extension) { diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 9d676b245..81abceee0 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -184,21 +184,21 @@ public function tryBuild(bool $force_build = false): int // extract first if not exists if (!is_dir($this->source_dir)) { - $this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-extract'); + $this->getBuilder()->emitPatchPoint('before-library[' . static::NAME . ']-extract'); SourceManager::initSource(libs: [static::NAME], source_only: true); - $this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-extract'); + $this->getBuilder()->emitPatchPoint('after-library[' . static::NAME . ']-extract'); } if (!$this->patched && $this->patchBeforeBuild()) { file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!'); } - $this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build'); + $this->getBuilder()->emitPatchPoint('before-library[' . static::NAME . ']-build'); $this->build(); $this->installLicense(); if (getenv('CI')) { FileSystem::removeDir($this->source_dir); } - $this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-build'); + $this->getBuilder()->emitPatchPoint('after-library[' . static::NAME . ']-build'); return LIB_STATUS_OK; } @@ -349,8 +349,8 @@ protected function getSnakeCaseName(): string */ protected function installLicense(): void { - FileSystem::createDir(BUILD_ROOT_PATH . '/source-licenses/' . $this->getName()); $source = Config::getLib($this->getName(), 'source'); + FileSystem::createDir(BUILD_ROOT_PATH . "/source-licenses/{$source}"); $license_files = Config::getSource($source)['license'] ?? []; if (is_assoc_array($license_files)) { $license_files = [$license_files]; From 037d224fd7d6bfbb6b82b314d1d68d5668421d5e Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 12:38:17 +0100 Subject: [PATCH 04/34] why does phpstan think this is necessary? --- src/SPC/builder/Extension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index 0df87e912..e79b886bf 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -385,7 +385,7 @@ public function buildShared(array $visited = []): void logger()->info('Shared extension [' . $this->getName() . '] was already built, skipping (' . $this->getName() . '.so)'); return; } - if (Config::getExt($this->getName(), 'type') === 'addon') { + if ((string) Config::getExt($this->getName(), 'type') === 'addon') { return; } logger()->info('Building extension [' . $this->getName() . '] as shared extension (' . $this->getName() . '.so)'); From e677be74d7e1f85d5503a285f4fd8998e4c8428f Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 13:07:21 +0100 Subject: [PATCH 05/34] remove --- src/SPC/builder/LibraryBase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 81abceee0..d34663021 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -195,9 +195,6 @@ public function tryBuild(bool $force_build = false): int $this->getBuilder()->emitPatchPoint('before-library[' . static::NAME . ']-build'); $this->build(); $this->installLicense(); - if (getenv('CI')) { - FileSystem::removeDir($this->source_dir); - } $this->getBuilder()->emitPatchPoint('after-library[' . static::NAME . ']-build'); return LIB_STATUS_OK; } From 9e051c8c8068bb97a2c0533a78fa82cceab70dab Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 14:52:02 +0100 Subject: [PATCH 06/34] fix: check for link first before checking for is_dir --- src/SPC/store/FileSystem.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SPC/store/FileSystem.php b/src/SPC/store/FileSystem.php index f6c538bdf..1d0815ce2 100644 --- a/src/SPC/store/FileSystem.php +++ b/src/SPC/store/FileSystem.php @@ -408,13 +408,13 @@ public static function removeDir(string $dir): bool continue; } $sub_file = self::convertPath($dir . '/' . $v); - if (is_dir($sub_file)) { - # 如果是 目录 且 递推 , 则递推添加下级文件 - if (!self::removeDir($sub_file)) { + if (is_link($sub_file) || is_file($sub_file)) { + if (!unlink($sub_file)) { return false; } - } elseif (is_link($sub_file) || is_file($sub_file)) { - if (!unlink($sub_file)) { + } elseif (is_dir($sub_file)) { + # 如果是 目录 且 递推 , 则递推添加下级文件 + if (!self::removeDir($sub_file)) { return false; } } From e1a14bbb9fa9522ccfde72f8e69d689b6c158ca6 Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 17:39:05 +0100 Subject: [PATCH 07/34] fix implicit include --- src/SPC/builder/unix/library/libwebp.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SPC/builder/unix/library/libwebp.php b/src/SPC/builder/unix/library/libwebp.php index 068185829..015fa73ba 100644 --- a/src/SPC/builder/unix/library/libwebp.php +++ b/src/SPC/builder/unix/library/libwebp.php @@ -10,9 +10,10 @@ trait libwebp { protected function build(): void { - $code = 'int main() { return _mm256_cvtsi256_si32(_mm256_setzero_si256()); }'; + $code = '#include +int main() { return _mm256_cvtsi256_si32(_mm256_setzero_si256()); }'; $cc = getenv('CC') ?: 'gcc'; - [$ret] = shell()->execWithResult("echo '{$code}' | {$cc} -x c -mavx2 -o /dev/null - 2>&1"); + [$ret] = shell()->execWithResult("printf '%s' '{$code}' | {$cc} -x c -mavx2 -o /dev/null - 2>&1"); $disableAvx2 = $ret !== 0 && GNU_ARCH === 'x86_64' && PHP_OS_FAMILY === 'Linux'; UnixCMakeExecutor::create($this) From 53f7cdefe0e791d621d86cc2ce6938d228ec3b19 Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 18 Dec 2025 20:12:01 +0100 Subject: [PATCH 08/34] fix swoole compilation with php 8.5.1 --- src/SPC/builder/extension/swoole.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SPC/builder/extension/swoole.php b/src/SPC/builder/extension/swoole.php index f6ff5931d..4e292a362 100644 --- a/src/SPC/builder/extension/swoole.php +++ b/src/SPC/builder/extension/swoole.php @@ -17,6 +17,7 @@ class swoole extends Extension public function patchBeforeMake(): bool { $patched = parent::patchBeforeMake(); + FileSystem::replaceFileStr($this->source_dir . '/ext-src/php_swoole_private.h', 'PHP_VERSION_ID > 80500', 'PHP_VERSION_ID >= 80600'); if ($this->builder instanceof MacOSBuilder) { // Fix swoole with event extension conflict bug $util_path = shell()->execWithResult('xcrun --show-sdk-path', false)[1][0] . '/usr/include/util.h'; From 6b5200002e6d744a450038e982c3c88d386ef3e6 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 20 Dec 2025 23:29:25 +0100 Subject: [PATCH 09/34] fix downloader selecting drafts --- composer.lock | 428 ++++++++++++++++++----------------- src/SPC/store/Downloader.php | 3 + 2 files changed, 224 insertions(+), 207 deletions(-) diff --git a/composer.lock b/composer.lock index e8f320c7c..a69833c7c 100644 --- a/composer.lock +++ b/composer.lock @@ -8,7 +8,7 @@ "packages": [ { "name": "illuminate/collections", - "version": "v11.46.1", + "version": "v11.47.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -64,7 +64,7 @@ }, { "name": "illuminate/conditionable", - "version": "v11.46.1", + "version": "v11.47.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -110,16 +110,16 @@ }, { "name": "illuminate/contracts", - "version": "v11.46.1", + "version": "v11.47.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "4b2a67d1663f50085bc91e6371492697a5d2d4e8" + "reference": "4787042340aae19a7ea0fa82f4073c4826204a48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/4b2a67d1663f50085bc91e6371492697a5d2d4e8", - "reference": "4b2a67d1663f50085bc91e6371492697a5d2d4e8", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/4787042340aae19a7ea0fa82f4073c4826204a48", + "reference": "4787042340aae19a7ea0fa82f4073c4826204a48", "shasum": "" }, "require": { @@ -154,11 +154,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-03-24T11:54:20+00:00" + "time": "2025-11-27T16:16:07+00:00" }, { "name": "illuminate/macroable", - "version": "v11.46.1", + "version": "v11.47.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -416,16 +416,16 @@ }, { "name": "symfony/console", - "version": "v7.3.6", + "version": "v7.4.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a" + "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", - "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "url": "https://api.github.com/repos/symfony/console/zipball/6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", + "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", "shasum": "" }, "require": { @@ -433,7 +433,7 @@ "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^7.2" + "symfony/string": "^7.2|^8.0" }, "conflict": { "symfony/dependency-injection": "<6.4", @@ -447,16 +447,16 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -490,7 +490,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.6" + "source": "https://github.com/symfony/console/tree/v7.4.1" }, "funding": [ { @@ -510,7 +510,7 @@ "type": "tidelift" } ], - "time": "2025-11-04T01:21:42+00:00" + "time": "2025-12-05T15:23:39+00:00" }, { "name": "symfony/deprecation-contracts", @@ -916,16 +916,16 @@ }, { "name": "symfony/process", - "version": "v7.3.4", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b" + "reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b", - "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b", + "url": "https://api.github.com/repos/symfony/process/zipball/7ca8dc2d0dcf4882658313aba8be5d9fd01026c8", + "reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8", "shasum": "" }, "require": { @@ -957,7 +957,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.3.4" + "source": "https://github.com/symfony/process/tree/v7.4.0" }, "funding": [ { @@ -977,7 +977,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T10:12:26+00:00" + "time": "2025-10-16T11:21:06+00:00" }, { "name": "symfony/service-contracts", @@ -1068,34 +1068,34 @@ }, { "name": "symfony/string", - "version": "v7.3.4", + "version": "v8.0.1", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f96476035142921000338bad71e5247fbc138872" + "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", - "reference": "f96476035142921000338bad71e5247fbc138872", + "url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc", + "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-intl-grapheme": "^1.33", + "symfony/polyfill-intl-normalizer": "^1.0", + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", + "symfony/emoji": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/var-exporter": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -1134,7 +1134,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.3.4" + "source": "https://github.com/symfony/string/tree/v8.0.1" }, "funding": [ { @@ -1154,32 +1154,32 @@ "type": "tidelift" } ], - "time": "2025-09-11T14:36:48+00:00" + "time": "2025-12-01T09:13:36+00:00" }, { "name": "symfony/yaml", - "version": "v7.3.5", + "version": "v7.4.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "90208e2fc6f68f613eae7ca25a2458a931b1bacc" + "reference": "24dd4de28d2e3988b311751ac49e684d783e2345" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/90208e2fc6f68f613eae7ca25a2458a931b1bacc", - "reference": "90208e2fc6f68f613eae7ca25a2458a931b1bacc", + "url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345", + "reference": "24dd4de28d2e3988b311751ac49e684d783e2345", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^6.4|^7.0" + "symfony/console": "^6.4|^7.0|^8.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -1210,7 +1210,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.5" + "source": "https://github.com/symfony/yaml/tree/v7.4.1" }, "funding": [ { @@ -1230,7 +1230,7 @@ "type": "tidelift" } ], - "time": "2025-09-27T09:00:46+00:00" + "time": "2025-12-04T18:11:45+00:00" }, { "name": "zhamao/logger", @@ -1615,16 +1615,16 @@ }, { "name": "amphp/parallel", - "version": "v2.3.2", + "version": "v2.3.3", "source": { "type": "git", "url": "https://github.com/amphp/parallel.git", - "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce" + "reference": "296b521137a54d3a02425b464e5aee4c93db2c60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parallel/zipball/321b45ae771d9c33a068186b24117e3cd1c48dce", - "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce", + "url": "https://api.github.com/repos/amphp/parallel/zipball/296b521137a54d3a02425b464e5aee4c93db2c60", + "reference": "296b521137a54d3a02425b464e5aee4c93db2c60", "shasum": "" }, "require": { @@ -1687,7 +1687,7 @@ ], "support": { "issues": "https://github.com/amphp/parallel/issues", - "source": "https://github.com/amphp/parallel/tree/v2.3.2" + "source": "https://github.com/amphp/parallel/tree/v2.3.3" }, "funding": [ { @@ -1695,7 +1695,7 @@ "type": "github" } ], - "time": "2025-08-27T21:55:40+00:00" + "time": "2025-11-15T06:23:42+00:00" }, { "name": "amphp/parser", @@ -2113,7 +2113,7 @@ }, { "name": "captainhook/captainhook-phar", - "version": "5.25.11", + "version": "5.27.3", "source": { "type": "git", "url": "https://github.com/captainhook-git/captainhook-phar.git", @@ -2167,7 +2167,7 @@ ], "support": { "issues": "https://github.com/captainhook-git/captainhook/issues", - "source": "https://github.com/captainhook-git/captainhook-phar/tree/5.25.11" + "source": "https://github.com/captainhook-git/captainhook-phar/tree/5.27.3" }, "funding": [ { @@ -2864,16 +2864,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.89.2", + "version": "v3.92.3", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "7569658f91e475ec93b99bd5964b059ad1336dcf" + "reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7569658f91e475ec93b99bd5964b059ad1336dcf", - "reference": "7569658f91e475ec93b99bd5964b059ad1336dcf", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8", + "reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8", "shasum": "" }, "require": { @@ -2891,17 +2891,17 @@ "react/socket": "^1.16", "react/stream": "^1.4", "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", - "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0", - "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0", - "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0", - "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0", - "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", "symfony/polyfill-mbstring": "^1.33", "symfony/polyfill-php80": "^1.33", "symfony/polyfill-php81": "^1.33", "symfony/polyfill-php84": "^1.33", - "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2", - "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0" + "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2 || ^8.0", + "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0" }, "require-dev": { "facile-it/paraunit": "^1.3.1 || ^2.7", @@ -2913,8 +2913,9 @@ "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34", - "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2", - "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2" + "symfony/polyfill-php85": "^1.33", + "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2 || ^8.0", + "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2 || ^8.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -2929,7 +2930,7 @@ "PhpCsFixer\\": "src/" }, "exclude-from-classmap": [ - "src/Fixer/Internal/*" + "src/**/Internal/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2955,7 +2956,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.89.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.3" }, "funding": [ { @@ -2963,7 +2964,7 @@ "type": "github" } ], - "time": "2025-11-06T21:12:50+00:00" + "time": "2025-12-18T10:45:02+00:00" }, { "name": "humbug/box", @@ -3212,21 +3213,21 @@ }, { "name": "justinrainbow/json-schema", - "version": "6.6.1", + "version": "6.6.3", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "fd8e5c6b1badb998844ad34ce0abcd71a0aeb396" + "reference": "134e98916fa2f663afa623970af345cd788e8967" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/fd8e5c6b1badb998844ad34ce0abcd71a0aeb396", - "reference": "fd8e5c6b1badb998844ad34ce0abcd71a0aeb396", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/134e98916fa2f663afa623970af345cd788e8967", + "reference": "134e98916fa2f663afa623970af345cd788e8967", "shasum": "" }, "require": { "ext-json": "*", - "marc-mabe/php-enum": "^4.0", + "marc-mabe/php-enum": "^4.4", "php": "^7.2 || ^8.0" }, "require-dev": { @@ -3281,9 +3282,9 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/6.6.1" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.6.3" }, - "time": "2025-11-07T18:30:29+00:00" + "time": "2025-12-02T10:21:33+00:00" }, { "name": "kelunik/certificate", @@ -3345,33 +3346,38 @@ }, { "name": "league/uri", - "version": "7.5.1", + "version": "7.7.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "81fb5145d2644324614cc532b28efd0215bda430" + "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", - "reference": "81fb5145d2644324614cc532b28efd0215bda430", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/8d587cddee53490f9b82bf203d3a9aa7ea4f9807", + "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807", "shasum": "" }, "require": { - "league/uri-interfaces": "^7.5", - "php": "^8.1" + "league/uri-interfaces": "^7.7", + "php": "^8.1", + "psr/http-factory": "^1" }, "conflict": { "league/uri-schemes": "^1.0" }, "suggest": { "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", "ext-fileinfo": "to create Data URI from file contennts", "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", + "ext-uri": "to use the PHP native URI class", "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", "league/uri-components": "Needed to easily manipulate URI objects components", + "league/uri-polyfill": "Needed to backport the PHP URI extension for older versions of PHP", "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle WHATWG URL", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", @@ -3399,6 +3405,7 @@ "description": "URI manipulation library", "homepage": "https://uri.thephpleague.com", "keywords": [ + "URN", "data-uri", "file-uri", "ftp", @@ -3411,9 +3418,11 @@ "psr-7", "query-string", "querystring", + "rfc2141", "rfc3986", "rfc3987", "rfc6570", + "rfc8141", "uri", "uri-template", "url", @@ -3423,7 +3432,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.5.1" + "source": "https://github.com/thephpleague/uri/tree/7.7.0" }, "funding": [ { @@ -3431,26 +3440,25 @@ "type": "github" } ], - "time": "2024-12-08T08:40:02+00:00" + "time": "2025-12-07T16:02:06+00:00" }, { "name": "league/uri-interfaces", - "version": "7.5.0", + "version": "7.7.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" + "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/62ccc1a0435e1c54e10ee6022df28d6c04c2946c", + "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c", "shasum": "" }, "require": { "ext-filter": "*", "php": "^8.1", - "psr/http-factory": "^1", "psr/http-message": "^1.1 || ^2.0" }, "suggest": { @@ -3458,6 +3466,7 @@ "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle WHATWG URL", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", @@ -3482,7 +3491,7 @@ "homepage": "https://nyamsprod.com" } ], - "description": "Common interfaces and classes for URI representation and interaction", + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", "homepage": "https://uri.thephpleague.com", "keywords": [ "data-uri", @@ -3507,7 +3516,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.7.0" }, "funding": [ { @@ -3515,7 +3524,7 @@ "type": "github" } ], - "time": "2024-12-08T08:18:47+00:00" + "time": "2025-12-07T16:03:21+00:00" }, { "name": "marc-mabe/php-enum", @@ -3704,16 +3713,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.6.2", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "3a454ca033b9e06b63282ce19562e892747449bb" + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb", - "reference": "3a454ca033b9e06b63282ce19562e892747449bb", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { @@ -3756,9 +3765,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2025-10-21T19:32:17+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { "name": "phar-io/composer-distributor", @@ -4147,16 +4156,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.3", + "version": "5.6.5", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9" + "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9", - "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/90614c73d3800e187615e2dd236ad0e2a01bf761", + "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761", "shasum": "" }, "require": { @@ -4205,22 +4214,22 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.3" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.5" }, - "time": "2025-08-01T19:43:32+00:00" + "time": "2025-11-27T19:50:05+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.10.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", - "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", "shasum": "" }, "require": { @@ -4263,9 +4272,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" }, - "time": "2024-11-09T15:12:26+00:00" + "time": "2025-11-21T15:09:14+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -4690,16 +4699,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.58", + "version": "10.5.60", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e24fb46da450d8e6a5788670513c1af1424f16ca" + "reference": "f2e26f52f80ef77832e359205f216eeac00e320c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e24fb46da450d8e6a5788670513c1af1424f16ca", - "reference": "e24fb46da450d8e6a5788670513c1af1424f16ca", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f2e26f52f80ef77832e359205f216eeac00e320c", + "reference": "f2e26f52f80ef77832e359205f216eeac00e320c", "shasum": "" }, "require": { @@ -4771,7 +4780,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.58" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.60" }, "funding": [ { @@ -4795,7 +4804,7 @@ "type": "tidelift" } ], - "time": "2025-09-28T12:04:46+00:00" + "time": "2025-12-06T07:50:42+00:00" }, { "name": "psr/event-dispatcher", @@ -5104,16 +5113,16 @@ }, { "name": "react/dns", - "version": "v1.13.0", + "version": "v1.14.0", "source": { "type": "git", "url": "https://github.com/reactphp/dns.git", - "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", - "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3", "shasum": "" }, "require": { @@ -5168,7 +5177,7 @@ ], "support": { "issues": "https://github.com/reactphp/dns/issues", - "source": "https://github.com/reactphp/dns/tree/v1.13.0" + "source": "https://github.com/reactphp/dns/tree/v1.14.0" }, "funding": [ { @@ -5176,20 +5185,20 @@ "type": "open_collective" } ], - "time": "2024-06-13T14:18:03+00:00" + "time": "2025-11-18T19:34:28+00:00" }, { "name": "react/event-loop", - "version": "v1.5.0", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/reactphp/event-loop.git", - "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", - "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a", "shasum": "" }, "require": { @@ -5240,7 +5249,7 @@ ], "support": { "issues": "https://github.com/reactphp/event-loop/issues", - "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + "source": "https://github.com/reactphp/event-loop/tree/v1.6.0" }, "funding": [ { @@ -5248,7 +5257,7 @@ "type": "open_collective" } ], - "time": "2023-11-13T13:48:05+00:00" + "time": "2025-11-17T20:46:25+00:00" }, { "name": "react/promise", @@ -5325,16 +5334,16 @@ }, { "name": "react/socket", - "version": "v1.16.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/reactphp/socket.git", - "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", - "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08", "shasum": "" }, "require": { @@ -5393,7 +5402,7 @@ ], "support": { "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.16.0" + "source": "https://github.com/reactphp/socket/tree/v1.17.0" }, "funding": [ { @@ -5401,7 +5410,7 @@ "type": "open_collective" } ], - "time": "2024-07-26T10:38:09+00:00" + "time": "2025-11-19T20:47:34+00:00" }, { "name": "react/stream", @@ -5483,16 +5492,16 @@ }, { "name": "revolt/event-loop", - "version": "v1.0.7", + "version": "v1.0.8", "source": { "type": "git", "url": "https://github.com/revoltphp/event-loop.git", - "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3" + "reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/09bf1bf7f7f574453efe43044b06fafe12216eb3", - "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/b6fc06dce8e9b523c9946138fa5e62181934f91c", + "reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c", "shasum": "" }, "require": { @@ -5549,9 +5558,9 @@ ], "support": { "issues": "https://github.com/revoltphp/event-loop/issues", - "source": "https://github.com/revoltphp/event-loop/tree/v1.0.7" + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.8" }, - "time": "2025-01-25T19:27:39+00:00" + "time": "2025-08-27T21:33:23+00:00" }, { "name": "sebastian/cli-parser", @@ -6620,24 +6629,24 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.3.3", + "version": "v8.0.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" + "reference": "573f95783a2ec6e38752979db139f09fec033f03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", - "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/573f95783a2ec6e38752979db139f09fec033f03", + "reference": "573f95783a2ec6e38752979db139f09fec033f03", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<6.4", + "symfony/security-http": "<7.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -6646,13 +6655,14 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/error-handler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/expression-language": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0" + "symfony/stopwatch": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -6680,7 +6690,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.0" }, "funding": [ { @@ -6700,7 +6710,7 @@ "type": "tidelift" } ], - "time": "2025-08-13T11:49:31+00:00" + "time": "2025-10-30T14:17:19+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -6780,16 +6790,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.3.6", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a" + "reference": "d551b38811096d0be9c4691d406991b47c0c630a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e9bcfd7837928ab656276fe00464092cc9e1826a", - "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a", + "reference": "d551b38811096d0be9c4691d406991b47c0c630a", "shasum": "" }, "require": { @@ -6798,7 +6808,7 @@ "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "symfony/process": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -6826,7 +6836,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.3.6" + "source": "https://github.com/symfony/filesystem/tree/v7.4.0" }, "funding": [ { @@ -6846,27 +6856,27 @@ "type": "tidelift" } ], - "time": "2025-11-05T09:52:27+00:00" + "time": "2025-11-27T13:27:24+00:00" }, { "name": "symfony/finder", - "version": "v7.3.5", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9f696d2f1e340484b4683f7853b273abff94421f" + "reference": "340b9ed7320570f319028a2cbec46d40535e94bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9f696d2f1e340484b4683f7853b273abff94421f", - "reference": "9f696d2f1e340484b4683f7853b273abff94421f", + "url": "https://api.github.com/repos/symfony/finder/zipball/340b9ed7320570f319028a2cbec46d40535e94bd", + "reference": "340b9ed7320570f319028a2cbec46d40535e94bd", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.4|^7.0" + "symfony/filesystem": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -6894,7 +6904,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.3.5" + "source": "https://github.com/symfony/finder/tree/v7.4.0" }, "funding": [ { @@ -6914,24 +6924,24 @@ "type": "tidelift" } ], - "time": "2025-10-15T18:45:57+00:00" + "time": "2025-11-05T05:42:40+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.3.3", + "version": "v8.0.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d" + "reference": "d2b592535ffa6600c265a3893a7f7fd2bad82dd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d", - "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/d2b592535ffa6600c265a3893a7f7fd2bad82dd7", + "reference": "d2b592535ffa6600c265a3893a7f7fd2bad82dd7", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", @@ -6965,7 +6975,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.3.3" + "source": "https://github.com/symfony/options-resolver/tree/v8.0.0" }, "funding": [ { @@ -6985,7 +6995,7 @@ "type": "tidelift" } ], - "time": "2025-08-05T10:16:07+00:00" + "time": "2025-11-12T15:55:31+00:00" }, { "name": "symfony/polyfill-iconv", @@ -7153,20 +7163,20 @@ }, { "name": "symfony/stopwatch", - "version": "v7.3.0", + "version": "v8.0.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" + "reference": "67df1914c6ccd2d7b52f70d40cf2aea02159d942" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", - "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/67df1914c6ccd2d7b52f70d40cf2aea02159d942", + "reference": "67df1914c6ccd2d7b52f70d40cf2aea02159d942", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -7195,7 +7205,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.3.0" + "source": "https://github.com/symfony/stopwatch/tree/v8.0.0" }, "funding": [ { @@ -7206,25 +7216,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-02-24T10:49:57+00:00" + "time": "2025-08-04T07:36:47+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.3.5", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "476c4ae17f43a9a36650c69879dcf5b1e6ae724d" + "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/476c4ae17f43a9a36650c69879dcf5b1e6ae724d", - "reference": "476c4ae17f43a9a36650c69879dcf5b1e6ae724d", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/41fd6c4ae28c38b294b42af6db61446594a0dece", + "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece", "shasum": "" }, "require": { @@ -7236,10 +7250,10 @@ "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0", "twig/twig": "^3.12" }, "bin": [ @@ -7278,7 +7292,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.3.5" + "source": "https://github.com/symfony/var-dumper/tree/v7.4.0" }, "funding": [ { @@ -7298,7 +7312,7 @@ "type": "tidelift" } ], - "time": "2025-09-27T09:00:46+00:00" + "time": "2025-10-27T20:36:44+00:00" }, { "name": "thecodingmachine/safe", @@ -7441,16 +7455,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "d74205c497bfbca49f34d4bc4c19c17e22db4ebb" + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/d74205c497bfbca49f34d4bc4c19c17e22db4ebb", - "reference": "d74205c497bfbca49f34d4bc4c19c17e22db4ebb", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", "shasum": "" }, "require": { @@ -7479,7 +7493,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.3.0" + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" }, "funding": [ { @@ -7487,7 +7501,7 @@ "type": "github" } ], - "time": "2025-11-13T13:44:09+00:00" + "time": "2025-11-17T20:03:58+00:00" }, { "name": "webmozart/assert", diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 63bec8075..a2911e46b 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -108,6 +108,9 @@ public static function getLatestGithubTarball(string $name, array $source, strin if (($rel['prerelease'] ?? false) === true && ($source['prefer-stable'] ?? false)) { continue; } + if (($rel['draft'] ?? false) === true && (($source['prefer-stable'] ?? false) || !$rel['tarball_url'])) { + continue; + } if (!($source['match'] ?? null)) { $url = $rel['tarball_url'] ?? null; break; From f7ca621efec86cd5f24ec69410ac86d7644e0cf8 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 26 Dec 2025 15:03:54 +0800 Subject: [PATCH 10/34] Test --- src/globals/test-extensions.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index cdd27e235..0402eaf37 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -13,10 +13,10 @@ // test php version (8.1 ~ 8.4 available, multiple for matrix) $test_php_version = [ - // '8.1', + '8.1', // '8.2', // '8.3', - // '8.4', + '8.4', '8.5', // 'git', ]; @@ -24,10 +24,10 @@ // test os (macos-15-intel, macos-15, ubuntu-latest, windows-latest are available) $test_os = [ 'macos-15-intel', // bin/spc for x86_64 - // 'macos-15', // bin/spc for arm64 - // 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 - // 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 - // 'ubuntu-24.04', // bin/spc for x86_64 + 'macos-15', // bin/spc for arm64 + 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 + 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 + 'ubuntu-24.04', // bin/spc for x86_64 // 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64 // 'ubuntu-24.04-arm', // bin/spc for arm64 // 'windows-2022', // .\bin\spc.ps1 @@ -50,7 +50,7 @@ // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'imagick', + 'Linux', 'Darwin' => 'swoole,imagick', 'Windows' => 'bcmath', }; From 9a681a9fa6249130bddcb7d342761f389c8d49ef Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 27 Dec 2025 21:19:31 +0100 Subject: [PATCH 11/34] add mariadb mysqlnd plugins --- config/ext.json | 30 +++++++++++++++++++ config/source.json | 18 +++++++++++ src/SPC/builder/extension/mysqlnd_ed25519.php | 22 ++++++++++++++ src/SPC/builder/extension/mysqlnd_parsec.php | 22 ++++++++++++++ src/globals/test-extensions.php | 10 +++---- 5 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 src/SPC/builder/extension/mysqlnd_ed25519.php create mode 100644 src/SPC/builder/extension/mysqlnd_parsec.php diff --git a/config/ext.json b/config/ext.json index d3fd2aa27..78a0ea38a 100644 --- a/config/ext.json +++ b/config/ext.json @@ -487,6 +487,36 @@ "zlib" ] }, + "mysqlnd_ed25519": { + "type": "external", + "source": "mysqlnd_ed25519", + "arg-type": "enable", + "target": [ + "shared" + ], + "ext-depends": [ + "mysqlnd" + ], + "lib-depends": [ + "libsodium", + "openssl" + ] + }, + "mysqlnd_parsec": { + "type": "external", + "source": "mysqlnd_parsec", + "arg-type": "enable", + "target": [ + "shared" + ], + "ext-depends": [ + "mysqlnd" + ], + "lib-depends": [ + "libsodium", + "openssl" + ] + }, "oci8": { "type": "wip", "support": { diff --git a/config/source.json b/config/source.json index c96822d6b..255d95848 100644 --- a/config/source.json +++ b/config/source.json @@ -871,6 +871,24 @@ "path": "LICENSE" } }, + "mysqlnd_ed25519": { + "type": "pie", + "repo": "mariadb/mysqlnd_ed25519", + "path": "php-src/ext/mysqlnd_ed25519", + "license": { + "type": "file", + "path": "LICENSE" + } + }, + "mysqlnd_parsec": { + "type": "pie", + "repo": "mariadb/mysqlnd_parsec", + "path": "php-src/ext/mysqlnd_parsec", + "license": { + "type": "file", + "path": "LICENSE" + } + }, "ncurses": { "type": "filelist", "url": "https://ftp.gnu.org/pub/gnu/ncurses/", diff --git a/src/SPC/builder/extension/mysqlnd_ed25519.php b/src/SPC/builder/extension/mysqlnd_ed25519.php new file mode 100644 index 000000000..7b2b4abcd --- /dev/null +++ b/src/SPC/builder/extension/mysqlnd_ed25519.php @@ -0,0 +1,22 @@ +getConfigureArg(); + } +} diff --git a/src/SPC/builder/extension/mysqlnd_parsec.php b/src/SPC/builder/extension/mysqlnd_parsec.php new file mode 100644 index 000000000..d044b1c52 --- /dev/null +++ b/src/SPC/builder/extension/mysqlnd_parsec.php @@ -0,0 +1,22 @@ +getConfigureArg(); + } +} diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 0402eaf37..d76153e49 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -13,9 +13,9 @@ // test php version (8.1 ~ 8.4 available, multiple for matrix) $test_php_version = [ - '8.1', - // '8.2', - // '8.3', + // '8.1', + '8.2', + '8.3', '8.4', '8.5', // 'git', @@ -50,13 +50,13 @@ // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'swoole,imagick', + 'Linux', 'Darwin' => 'mysqli', 'Windows' => 'bcmath', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). $shared_extensions = match (PHP_OS_FAMILY) { - 'Linux' => '', + 'Linux' => 'mysqlnd_parsec,mysqlnd_ed25519', 'Darwin' => '', 'Windows' => '', }; From 09b89a30f925510c4cd039a83bb0908390496d81 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 27 Dec 2025 22:20:02 +0100 Subject: [PATCH 12/34] WIP: use system libraries for grpc without building our own grpc lib --- src/SPC/builder/LibraryBase.php | 11 ++++++++- src/SPC/builder/traits/UnixLibraryTrait.php | 2 +- src/SPC/util/SPCConfigUtil.php | 26 +++++++++++++++++---- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index d34663021..383faa41a 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -375,8 +375,17 @@ protected function isLibraryInstalled(): bool return false; } } + $pkg_config_path = getenv('PKG_CONFIG_PATH') ?: ''; + $search_paths = array_filter(explode(is_unix() ? ':' : ';', $pkg_config_path)); foreach (Config::getLib(static::NAME, 'pkg-configs', []) as $name) { - if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$name}.pc")) { + $found = false; + foreach ($search_paths as $path) { + if (file_exists($path . "/{$name}.pc")) { + $found = true; + break; + } + } + if (!$found) { return false; } } diff --git a/src/SPC/builder/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index 868cf6f7b..ec1e7c2be 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -34,7 +34,7 @@ public function patchPkgconfPrefix(array $files = [], int $patch_option = PKGCON $files = array_map(fn ($x) => "{$x}.pc", $conf_pc); } foreach ($files as $name) { - $realpath = realpath(BUILD_ROOT_PATH . '/lib/pkgconfig/' . $name); + $realpath = realpath(BUILD_LIB_PATH . '/pkgconfig/' . $name); if ($realpath === false) { throw new PatchException('pkg-config prefix patcher', 'Cannot find library [' . static::NAME . '] pkgconfig file [' . $name . '] in ' . BUILD_LIB_PATH . '/pkgconfig/ !'); } diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index a74d6a24c..7d2001f52 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -226,9 +226,17 @@ private function getIncludesString(array $libraries): string // parse pkg-configs foreach ($libraries as $library) { $pc = Config::getLib($library, 'pkg-configs', []); + $pkg_config_path = getenv('PKG_CONFIG_PATH') ?: ''; + $search_paths = array_filter(explode(is_unix() ? ':' : ';', $pkg_config_path)); foreach ($pc as $file) { - if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$file}.pc")) { - throw new WrongUsageException("pkg-config file '{$file}.pc' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first."); + $found = false; + foreach ($search_paths as $path) { + if (file_exists($path . "/{$file}.pc")) { + $found = true; + } + } + if (!$found) { + throw new WrongUsageException("pkg-config file '{$file}.pc' for lib [{$library}] does not exist. Please build it first."); } } $pc_cflags = implode(' ', $pc); @@ -257,9 +265,17 @@ private function getLibsString(array $libraries, bool $use_short_libs = true): s foreach ($libraries as $library) { // add pkg-configs libs $pkg_configs = Config::getLib($library, 'pkg-configs', []); - foreach ($pkg_configs as $pkg_config) { - if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$pkg_config}.pc")) { - throw new WrongUsageException("pkg-config file '{$pkg_config}.pc' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first."); + $pkg_config_path = getenv('PKG_CONFIG_PATH') ?: ''; + $search_paths = array_filter(explode(is_unix() ? ':' : ';', $pkg_config_path)); + foreach ($pkg_configs as $file) { + $found = false; + foreach ($search_paths as $path) { + if (file_exists($path . "/{$file}.pc")) { + $found = true; + } + } + if (!$found) { + throw new WrongUsageException("pkg-config file '{$file}.pc' for lib [{$library}] does not exist. Please build it first."); } } $pkg_configs = implode(' ', $pkg_configs); From e952f1c76abf73703f0b160306e90c109e75d0eb Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 27 Dec 2025 22:36:24 +0100 Subject: [PATCH 13/34] we don't even need to build grpc library for grpc extension... --- config/ext.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/ext.json b/config/ext.json index 78a0ea38a..e5f4d7706 100644 --- a/config/ext.json +++ b/config/ext.json @@ -236,7 +236,9 @@ "arg-type-unix": "enable-path", "cpp-extension": true, "lib-depends": [ - "grpc" + "zlib", + "openssl", + "libcares" ] }, "iconv": { From 5ef46230513bf6b44634c01752bad1412dfd1238 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 27 Dec 2025 23:05:35 +0100 Subject: [PATCH 14/34] grpc will fail for php 8.5, it's not updated yet --- src/globals/test-extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index d76153e49..d9202e08d 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -56,7 +56,7 @@ // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). $shared_extensions = match (PHP_OS_FAMILY) { - 'Linux' => 'mysqlnd_parsec,mysqlnd_ed25519', + 'Linux' => 'grpc,mysqlnd_parsec,mysqlnd_ed25519', 'Darwin' => '', 'Windows' => '', }; From 93a35908de867c9784cfafe59a257ba0e7b704bb Mon Sep 17 00:00:00 2001 From: henderkes Date: Sun, 28 Dec 2025 12:11:56 +0100 Subject: [PATCH 15/34] factor grpc extension out to ext-grpc, keep library for now, even though unused --- config/ext.json | 2 +- config/source.json | 12 ++++++++++++ src/SPC/builder/extension/grpc.php | 9 --------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/config/ext.json b/config/ext.json index e5f4d7706..62ec48772 100644 --- a/config/ext.json +++ b/config/ext.json @@ -232,7 +232,7 @@ "BSD": "wip" }, "type": "external", - "source": "grpc", + "source": "ext-grpc", "arg-type-unix": "enable-path", "cpp-extension": true, "lib-depends": [ diff --git a/config/source.json b/config/source.json index 255d95848..530e4703d 100644 --- a/config/source.json +++ b/config/source.json @@ -151,6 +151,18 @@ "path": "LICENSE" } }, + "ext-grpc": { + "type": "url", + "url": "https://pecl.php.net/get/grpc", + "path": "php-src/ext/grpc", + "filename": "grpc.tgz", + "license": { + "type": "file", + "path": [ + "LICENSE" + ] + } + }, "ext-imagick": { "type": "url", "url": "https://pecl.php.net/get/imagick", diff --git a/src/SPC/builder/extension/grpc.php b/src/SPC/builder/extension/grpc.php index fb31c85fe..ce8243d00 100644 --- a/src/SPC/builder/extension/grpc.php +++ b/src/SPC/builder/extension/grpc.php @@ -21,15 +21,6 @@ public function patchBeforeBuildconf(): bool if ($this->builder instanceof WindowsBuilder) { throw new ValidationException('grpc extension does not support windows yet'); } - if (file_exists(SOURCE_PATH . '/php-src/ext/grpc')) { - return false; - } - // soft link to the grpc source code - if (is_dir($this->source_dir . '/src/php/ext/grpc')) { - shell()->exec('ln -s ' . $this->source_dir . '/src/php/ext/grpc ' . SOURCE_PATH . '/php-src/ext/grpc'); - } else { - throw new ValidationException('Cannot find grpc source code in ' . $this->source_dir . '/src/php/ext/grpc'); - } if (SPCTarget::getTargetOS() === 'Darwin') { FileSystem::replaceFileRegex( SOURCE_PATH . '/php-src/ext/grpc/config.m4', From 2f3122627e054d51ed131c5f80a4972c434e8662 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sun, 28 Dec 2025 12:44:24 +0100 Subject: [PATCH 16/34] make grpc php 8.5 compatible --- src/SPC/builder/extension/grpc.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SPC/builder/extension/grpc.php b/src/SPC/builder/extension/grpc.php index ce8243d00..42dcdd5b8 100644 --- a/src/SPC/builder/extension/grpc.php +++ b/src/SPC/builder/extension/grpc.php @@ -21,9 +21,14 @@ public function patchBeforeBuildconf(): bool if ($this->builder instanceof WindowsBuilder) { throw new ValidationException('grpc extension does not support windows yet'); } + FileSystem::replaceFileStr( + $this->source_dir . '/src/php/ext/grpc/call.c', + 'zend_exception_get_default(TSRMLS_C),', + 'zend_ce_exception,', + ); if (SPCTarget::getTargetOS() === 'Darwin') { FileSystem::replaceFileRegex( - SOURCE_PATH . '/php-src/ext/grpc/config.m4', + $this->source_dir . '/config.m4', '/GRPC_LIBDIR=.*$/m', 'GRPC_LIBDIR=' . BUILD_LIB_PATH . "\n" . 'LDFLAGS="$LDFLAGS -framework CoreFoundation"' ); From e7a88f1df76956297d19db09dcd3e22812162aa7 Mon Sep 17 00:00:00 2001 From: henderkes Date: Mon, 29 Dec 2025 21:15:53 +0100 Subject: [PATCH 17/34] enable fat for gmp when next version releases --- src/SPC/builder/unix/library/gmp.php | 4 +++- src/globals/test-extensions.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SPC/builder/unix/library/gmp.php b/src/SPC/builder/unix/library/gmp.php index f625274f6..97a88ba1c 100644 --- a/src/SPC/builder/unix/library/gmp.php +++ b/src/SPC/builder/unix/library/gmp.php @@ -14,7 +14,9 @@ protected function build(): void ->appendEnv([ 'CFLAGS' => '-std=c17', ]) - ->configure() + ->configure( + '--enable-fat' + ) ->make(); $this->patchPkgconfPrefix(['gmp.pc']); } diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index d9202e08d..e2186c8e4 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -50,7 +50,7 @@ // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'mysqli', + 'Linux', 'Darwin' => 'mysqli,gmp', 'Windows' => 'bcmath', }; From 08388c0b153bd9e96b77c543a468ec46cdf99ad8 Mon Sep 17 00:00:00 2001 From: henderkes Date: Mon, 29 Dec 2025 22:12:25 +0100 Subject: [PATCH 18/34] force enable tailcall vm with zig --- src/SPC/toolchain/ZigToolchain.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SPC/toolchain/ZigToolchain.php b/src/SPC/toolchain/ZigToolchain.php index bb423db20..212a158f7 100644 --- a/src/SPC/toolchain/ZigToolchain.php +++ b/src/SPC/toolchain/ZigToolchain.php @@ -65,9 +65,11 @@ public function afterInit(): void GlobalEnvManager::putenv("SPC_EXTRA_LIBS={$extra_libs}"); } $cflags = getenv('SPC_DEFAULT_C_FLAGS') ?: getenv('CFLAGS') ?: ''; + GlobalEnvManager::putenv('SPC_EXTRA_PHP_VARS=php_cv_preserve_none=yes'); $has_avx512 = str_contains($cflags, '-mavx512') || str_contains($cflags, '-march=x86-64-v4'); if (!$has_avx512) { - GlobalEnvManager::putenv('SPC_EXTRA_PHP_VARS=php_cv_have_avx512=no php_cv_have_avx512vbmi=no'); + $extra_vars = getenv('SPC_EXTRA_PHP_VARS') ?: ''; + GlobalEnvManager::putenv("SPC_EXTRA_PHP_VARS=php_cv_have_avx512=no php_cv_have_avx512vbmi=no {$extra_vars}"); } } From 7688a556562ed4200255e820d64695cdd601d39a Mon Sep 17 00:00:00 2001 From: henderkes Date: Mon, 29 Dec 2025 22:16:53 +0100 Subject: [PATCH 19/34] don't get zig master branch --- src/SPC/store/pkg/Zig.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/SPC/store/pkg/Zig.php b/src/SPC/store/pkg/Zig.php index e9865dbe3..c2a81c0da 100644 --- a/src/SPC/store/pkg/Zig.php +++ b/src/SPC/store/pkg/Zig.php @@ -72,8 +72,11 @@ public function fetch(string $name, bool $force = false, ?array $config = null): $latest_version = null; foreach ($index_json as $version => $data) { - $latest_version = $version; - break; + // Skip the master branch, get the latest stable release + if ($version !== 'master') { + $latest_version = $version; + break; + } } if (!$latest_version) { From 022fdb2fc5b8ed2d78c0cac972fe4d9cd5f2d7d4 Mon Sep 17 00:00:00 2001 From: henderkes Date: Mon, 29 Dec 2025 23:58:54 +0100 Subject: [PATCH 20/34] fix no-strip --- src/SPC/builder/unix/UnixBuilderBase.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index d98059cb0..e2507f1f4 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -145,11 +145,10 @@ public function deployBinary(string $src, string $dst, bool $executable = true): throw new SPCInternalException("Deploy failed. Cannot find file after copy: {$dst}"); } - // extract debug info - $this->extractDebugInfo($dst); - - // strip if (!$this->getOption('no-strip')) { + // extract debug info + $this->extractDebugInfo($dst); + // extra strip $this->stripBinary($dst); } From a06cc3249169c3c1e7c76c6c9a8d53c075924882 Mon Sep 17 00:00:00 2001 From: henderkes Date: Tue, 30 Dec 2025 11:58:57 +0100 Subject: [PATCH 21/34] pin libpng to released tags, not git --- config/source.json | 13 +++++++------ src/SPC/store/Downloader.php | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/config/source.json b/config/source.json index 530e4703d..1bae46ce7 100644 --- a/config/source.json +++ b/config/source.json @@ -682,9 +682,10 @@ } }, "libpng": { - "type": "git", - "url": "https://github.com/glennrp/libpng.git", - "rev": "libpng16", + "type": "ghtagtar", + "repo": "pnggroup/libpng", + "match": "v1\\.6\\.\\d+", + "query": "?per_page=150", "provide-pre-built": true, "license": { "type": "file", @@ -692,9 +693,9 @@ } }, "librabbitmq": { - "type": "git", - "url": "https://github.com/alanxz/rabbitmq-c.git", - "rev": "master", + "type": "ghtar", + "repo": "alanxz/rabbitmq-c", + "prefer-stable": true, "license": { "type": "file", "path": "LICENSE" diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index a2911e46b..ccf61dd8d 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -97,8 +97,9 @@ public static function getLatestBitbucketTag(string $name, array $source): array public static function getLatestGithubTarball(string $name, array $source, string $type = 'releases'): array { logger()->debug("finding {$name} source from github {$type} tarball"); + $source['query'] ??= ''; $data = json_decode(self::curlExec( - url: "https://api.github.com/repos/{$source['repo']}/{$type}", + url: "https://api.github.com/repos/{$source['repo']}/{$type}{$source['query']}", hooks: [[CurlHook::class, 'setupGithubToken']], retries: self::getRetryAttempts() ), true, 512, JSON_THROW_ON_ERROR); From 64f7a3553e3fd961045f36842f05bfe2b3f9664b Mon Sep 17 00:00:00 2001 From: henderkes Date: Thu, 1 Jan 2026 12:33:55 +0100 Subject: [PATCH 22/34] don't need it anymore --- src/SPC/toolchain/ZigToolchain.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SPC/toolchain/ZigToolchain.php b/src/SPC/toolchain/ZigToolchain.php index 212a158f7..1b7cc70dc 100644 --- a/src/SPC/toolchain/ZigToolchain.php +++ b/src/SPC/toolchain/ZigToolchain.php @@ -65,7 +65,6 @@ public function afterInit(): void GlobalEnvManager::putenv("SPC_EXTRA_LIBS={$extra_libs}"); } $cflags = getenv('SPC_DEFAULT_C_FLAGS') ?: getenv('CFLAGS') ?: ''; - GlobalEnvManager::putenv('SPC_EXTRA_PHP_VARS=php_cv_preserve_none=yes'); $has_avx512 = str_contains($cflags, '-mavx512') || str_contains($cflags, '-march=x86-64-v4'); if (!$has_avx512) { $extra_vars = getenv('SPC_EXTRA_PHP_VARS') ?: ''; From d1b194999d22f8d6f55b715150fe9e10524fcd3c Mon Sep 17 00:00:00 2001 From: henderkes Date: Fri, 2 Jan 2026 21:13:22 +0100 Subject: [PATCH 23/34] use OPENSSL_CONF directory for openssl default configuration --- src/SPC/builder/linux/library/openssl.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index a78b6a642..8d071f2d9 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -51,6 +51,8 @@ public function build(): void $zlib_extra = ''; } + $openssl_conf = getenv('OPENSSL_CONF'); + $openssl_dir = $openssl_conf ? dirname($openssl_conf) : '/etc/ssl'; $ex_lib = trim($ex_lib); shell()->cd($this->source_dir)->initializeEnv($this) @@ -58,7 +60,7 @@ public function build(): void "{$env} ./Configure no-shared {$extra} " . '--prefix=' . BUILD_ROOT_PATH . ' ' . '--libdir=' . BUILD_LIB_PATH . ' ' . - '--openssldir=/etc/ssl ' . + "--openssldir={$openssl_dir} " . "{$zlib_extra}" . 'enable-pie ' . 'no-legacy ' . From fff24845298730398bd70cbaaba90be997f7595d Mon Sep 17 00:00:00 2001 From: henderkes Date: Fri, 2 Jan 2026 22:52:03 +0100 Subject: [PATCH 24/34] postgresql doesn't build under c23 --- src/SPC/builder/unix/library/postgresql.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/builder/unix/library/postgresql.php b/src/SPC/builder/unix/library/postgresql.php index 6e0cb606e..a72f3a1a6 100644 --- a/src/SPC/builder/unix/library/postgresql.php +++ b/src/SPC/builder/unix/library/postgresql.php @@ -50,7 +50,7 @@ protected function build(): void $config = $spc->config(libraries: $libs, include_suggest_lib: $this->builder->getOption('with-suggested-libs', false)); $env_vars = [ - 'CFLAGS' => $config['cflags'], + 'CFLAGS' => $config['cflags'] . ' -std=c17', 'CPPFLAGS' => '-DPIC', 'LDFLAGS' => $config['ldflags'], 'LIBS' => $config['libs'], From 559a2909a911a5557bee0d97430649e7f9d5daa0 Mon Sep 17 00:00:00 2001 From: henderkes Date: Fri, 2 Jan 2026 23:21:29 +0100 Subject: [PATCH 25/34] use little trick to order libargon2 before libsodium --- config/lib.json | 3 +++ src/SPC/builder/extension/password_argon2.php | 19 ------------------- src/SPC/util/SPCConfigUtil.php | 1 - 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/config/lib.json b/config/lib.json index 47f3c7b89..3be972484 100644 --- a/config/lib.json +++ b/config/lib.json @@ -361,6 +361,9 @@ "source": "libargon2", "static-libs-unix": [ "libargon2.a" + ], + "lib-suggests": [ + "libsodium" ] }, "libavif": { diff --git a/src/SPC/builder/extension/password_argon2.php b/src/SPC/builder/extension/password_argon2.php index 30e6fd2c5..d42fe4e37 100644 --- a/src/SPC/builder/extension/password_argon2.php +++ b/src/SPC/builder/extension/password_argon2.php @@ -24,25 +24,6 @@ public function runCliCheckUnix(): void } } - public function patchBeforeMake(): bool - { - $patched = parent::patchBeforeMake(); - if ($this->builder->getLib('libsodium') !== null) { - $extraLibs = getenv('SPC_EXTRA_LIBS'); - if ($extraLibs !== false) { - $extraLibs = str_replace( - [BUILD_LIB_PATH . '/libargon2.a', BUILD_LIB_PATH . '/libsodium.a'], - ['', BUILD_LIB_PATH . '/libargon2.a ' . BUILD_LIB_PATH . '/libsodium.a'], - $extraLibs, - ); - $extraLibs = trim(preg_replace('/\s+/', ' ', $extraLibs)); // normalize spacing - f_putenv('SPC_EXTRA_LIBS=' . $extraLibs); - return true; - } - } - return $patched; - } - public function getConfigureArg(bool $shared = false): string { if ($this->builder->getLib('openssl') !== null) { diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 7d2001f52..8c4fa9267 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -80,7 +80,6 @@ public function config(array $extensions = [], array $libraries = [], bool $incl $libs = $this->getLibsString($libraries, !$this->absolute_libs); // additional OS-specific libraries (e.g. macOS -lresolv) - // embed if ($extra_libs = SPCTarget::getRuntimeLibs()) { $libs .= " {$extra_libs}"; } From 890ff475f131c809de2b2e3309b85d33f28f5274 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 14:09:16 +0100 Subject: [PATCH 26/34] our memcache patch prevents shared building --- config/ext.json | 3 +-- src/SPC/builder/extension/memcache.php | 35 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/config/ext.json b/config/ext.json index 62ec48772..419be5a9b 100644 --- a/config/ext.json +++ b/config/ext.json @@ -410,8 +410,7 @@ "ext-depends": [ "zlib", "session" - ], - "build-with-php": true + ] }, "memcached": { "support": { diff --git a/src/SPC/builder/extension/memcache.php b/src/SPC/builder/extension/memcache.php index 59c6065d4..feba0151b 100644 --- a/src/SPC/builder/extension/memcache.php +++ b/src/SPC/builder/extension/memcache.php @@ -18,6 +18,9 @@ public function getUnixConfigureArg(bool $shared = false): string public function patchBeforeBuildconf(): bool { + if (!$this->isBuildStatic()) { + return false; + } FileSystem::replaceFileStr( SOURCE_PATH . '/php-src/ext/memcache/config9.m4', 'if test -d $abs_srcdir/src ; then', @@ -44,6 +47,38 @@ public function patchBeforeBuildconf(): bool return true; } + public function patchBeforeSharedConfigure(): bool + { + if (!$this->isBuildShared()) { + return false; + } + FileSystem::replaceFileStr( + SOURCE_PATH . '/php-src/ext/memcache/config9.m4', + 'if test -d $abs_srcdir/main ; then', + 'if test -d $abs_srcdir/src ; then', + ); + FileSystem::replaceFileStr( + SOURCE_PATH . '/php-src/ext/memcache/config9.m4', + 'export CPPFLAGS="$CPPFLAGS $INCLUDES -I$abs_srcdir/main"', + 'export CPPFLAGS="$CPPFLAGS $INCLUDES"', + ); + // add for in-tree building + FileSystem::replaceFileStr( + SOURCE_PATH . '/php-src/ext/memcache/php_memcache.h', + <<<'EOF' +#ifndef PHP_MEMCACHE_H +#define PHP_MEMCACHE_H + +extern zend_module_entry memcache_module_entry; +#define phpext_memcache_ptr &memcache_module_entry + +#endif +EOF, + '' + ); + return true; + } + protected function getExtraEnv(): array { return ['CFLAGS' => '-std=c17']; From 54001ab868b17b4b99b74443a88d5f1244895534 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 16:33:40 +0100 Subject: [PATCH 27/34] simplify logic a bit --- src/SPC/builder/linux/LinuxBuilder.php | 49 +++----------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 0d6f77fba..63abf018b 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -319,7 +319,7 @@ private function getMakeExtraVars(): array return array_filter([ 'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'), 'EXTRA_LIBS' => $config['libs'], - 'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), + 'EXTRA_LDFLAGS' => preg_replace('/-release\s+(\S+)/', '', getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS')), 'EXTRA_LDFLAGS_PROGRAM' => "-L{$lib} {$static} -pie", ]); } @@ -328,14 +328,12 @@ private function processLibphpSoFile(string $libphpSo): void { $ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS') ?: ''; $libDir = BUILD_LIB_PATH; - $modulesDir = BUILD_MODULES_PATH; - $realLibName = 'libphp.so'; $cwd = getcwd(); if (preg_match('/-release\s+(\S+)/', $ldflags, $matches)) { $release = $matches[1]; - $realLibName = "libphp-{$release}.so"; - $libphpRelease = "{$libDir}/{$realLibName}"; + $releaseName = "libphp-{$release}.so"; + $libphpRelease = "{$libDir}/{$releaseName}"; if (!file_exists($libphpRelease) && file_exists($libphpSo)) { rename($libphpSo, $libphpRelease); } @@ -344,52 +342,15 @@ private function processLibphpSoFile(string $libphpSo): void if (file_exists($libphpSo)) { unlink($libphpSo); } - symlink($realLibName, 'libphp.so'); + symlink($releaseName, 'libphp.so'); shell()->exec(sprintf( 'patchelf --set-soname %s %s', - escapeshellarg($realLibName), + escapeshellarg($releaseName), escapeshellarg($libphpRelease) )); } - if (is_dir($modulesDir)) { - chdir($modulesDir); - foreach ($this->getExts() as $ext) { - if (!$ext->isBuildShared()) { - continue; - } - $name = $ext->getName(); - $versioned = "{$name}-{$release}.so"; - $unversioned = "{$name}.so"; - $src = "{$modulesDir}/{$versioned}"; - $dst = "{$modulesDir}/{$unversioned}"; - if (is_file($src)) { - rename($src, $dst); - shell()->exec(sprintf( - 'patchelf --set-soname %s %s', - escapeshellarg($unversioned), - escapeshellarg($dst) - )); - } - } - } chdir($cwd); } - - $target = "{$libDir}/{$realLibName}"; - if (file_exists($target)) { - [, $output] = shell()->execWithResult('readelf -d ' . escapeshellarg($target)); - $output = implode("\n", $output); - if (preg_match('/SONAME.*\[(.+)]/', $output, $sonameMatch)) { - $currentSoname = $sonameMatch[1]; - if ($currentSoname !== basename($target)) { - shell()->exec(sprintf( - 'patchelf --set-soname %s %s', - escapeshellarg(basename($target)), - escapeshellarg($target) - )); - } - } - } } /** From 1be353fd13051949e301cbaef71f32bd13a57250 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 16:45:39 +0100 Subject: [PATCH 28/34] more concise message --- src/SPC/builder/unix/UnixBuilderBase.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index e2507f1f4..050394f06 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -235,8 +235,10 @@ protected function sanityCheck(int $build_target): void $lens .= ' -static'; } $dynamic_exports = ''; + $embedType = 'static'; // if someone changed to EMBED_TYPE=shared, we need to add LD_LIBRARY_PATH if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') { + $embedType = 'shared'; if (PHP_OS_FAMILY === 'Darwin') { $ext_path = 'DYLD_LIBRARY_PATH=' . BUILD_LIB_PATH . ':$DYLD_LIBRARY_PATH '; } else { @@ -255,18 +257,19 @@ protected function sanityCheck(int $build_target): void } } $cc = getenv('CC'); + [$ret, $out] = shell()->cd($sample_file_path)->execWithResult("{$cc} -o embed embed.c {$lens} {$dynamic_exports}"); if ($ret !== 0) { throw new ValidationException( - 'embed failed sanity check: build failed. Error message: ' . implode("\n", $out), - validation_module: 'static libphp.a sanity check' + 'embed failed to build. Error message: ' . implode("\n", $out), + validation_module: $embedType . 'libphp embed build sanity check' ); } [$ret, $output] = shell()->cd($sample_file_path)->execWithResult($ext_path . './embed'); if ($ret !== 0 || trim(implode('', $output)) !== 'hello') { throw new ValidationException( - 'embed failed sanity check: run failed. Error message: ' . implode("\n", $output), - validation_module: 'static libphp.a sanity check' + 'embed failed to run. Error message: ' . implode("\n", $output), + validation_module: $embedType . ' libphp embed run sanity check' ); } } From 76025b95c1683b29bcdcbeda30ee4f31513d7365 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 16:46:14 +0100 Subject: [PATCH 29/34] missing space --- src/SPC/builder/unix/UnixBuilderBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index 050394f06..464c9b2fc 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -262,7 +262,7 @@ protected function sanityCheck(int $build_target): void if ($ret !== 0) { throw new ValidationException( 'embed failed to build. Error message: ' . implode("\n", $out), - validation_module: $embedType . 'libphp embed build sanity check' + validation_module: $embedType . ' libphp embed build sanity check' ); } [$ret, $output] = shell()->cd($sample_file_path)->execWithResult($ext_path . './embed'); From 6bbb3c969ce914c146b96849c7210c9592fe8323 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 17:03:43 +0100 Subject: [PATCH 30/34] remove -release handling functionality --- bin/spc-alpine-docker | 3 +- bin/spc-gnu-docker | 5 ---- src/SPC/builder/linux/LinuxBuilder.php | 33 +--------------------- src/SPC/doctor/item/LinuxToolCheckList.php | 5 +--- 4 files changed, 3 insertions(+), 43 deletions(-) diff --git a/bin/spc-alpine-docker b/bin/spc-alpine-docker index 2790a5c34..1abf10480 100755 --- a/bin/spc-alpine-docker +++ b/bin/spc-alpine-docker @@ -108,8 +108,7 @@ RUN apk update; \ wget \ xz \ gettext-dev \ - binutils-gold \ - patchelf + binutils-gold RUN curl -#fSL https://dl.static-php.dev/static-php-cli/bulk/php-8.4.4-cli-linux-\$(uname -m).tar.gz | tar -xz -C /usr/local/bin && \ chmod +x /usr/local/bin/php diff --git a/bin/spc-gnu-docker b/bin/spc-gnu-docker index 68f85109f..286ef9859 100755 --- a/bin/spc-gnu-docker +++ b/bin/spc-gnu-docker @@ -92,11 +92,6 @@ RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc RUN source /etc/bashrc RUN yum install -y which -RUN curl -fsSL -o patchelf.tgz https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-$SPC_USE_ARCH.tar.gz && \ - mkdir -p /patchelf && \ - tar -xzf patchelf.tgz -C /patchelf --strip-components=1 && \ - cp /patchelf/bin/patchelf /usr/bin/ - RUN curl -o cmake.tgz -#fSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$SPC_USE_ARCH.tar.gz && \ mkdir /cmake && \ tar -xzf cmake.tgz -C /cmake --strip-components 1 diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 63abf018b..22c2d47a1 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -284,8 +284,6 @@ protected function buildEmbed(): void // process libphp.so for shared embed $libphpSo = BUILD_LIB_PATH . '/libphp.so'; if (file_exists($libphpSo)) { - // post actions: rename libphp.so to libphp-.so if -release is set in LDFLAGS - $this->processLibphpSoFile($libphpSo); // deploy libphp.so $this->deployBinary($libphpSo, $libphpSo, false); } @@ -319,40 +317,11 @@ private function getMakeExtraVars(): array return array_filter([ 'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'), 'EXTRA_LIBS' => $config['libs'], - 'EXTRA_LDFLAGS' => preg_replace('/-release\s+(\S+)/', '', getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS')), + 'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), 'EXTRA_LDFLAGS_PROGRAM' => "-L{$lib} {$static} -pie", ]); } - private function processLibphpSoFile(string $libphpSo): void - { - $ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS') ?: ''; - $libDir = BUILD_LIB_PATH; - $cwd = getcwd(); - - if (preg_match('/-release\s+(\S+)/', $ldflags, $matches)) { - $release = $matches[1]; - $releaseName = "libphp-{$release}.so"; - $libphpRelease = "{$libDir}/{$releaseName}"; - if (!file_exists($libphpRelease) && file_exists($libphpSo)) { - rename($libphpSo, $libphpRelease); - } - if (file_exists($libphpRelease)) { - chdir($libDir); - if (file_exists($libphpSo)) { - unlink($libphpSo); - } - symlink($releaseName, 'libphp.so'); - shell()->exec(sprintf( - 'patchelf --set-soname %s %s', - escapeshellarg($releaseName), - escapeshellarg($libphpRelease) - )); - } - chdir($cwd); - } - } - /** * Patch micro.sfx after UPX compression. * micro needs special section handling in LinuxBuilder. diff --git a/src/SPC/doctor/item/LinuxToolCheckList.php b/src/SPC/doctor/item/LinuxToolCheckList.php index ab8144a21..53b356ff3 100644 --- a/src/SPC/doctor/item/LinuxToolCheckList.php +++ b/src/SPC/doctor/item/LinuxToolCheckList.php @@ -22,7 +22,6 @@ class LinuxToolCheckList 'bzip2', 'cmake', 'gcc', 'g++', 'patch', 'binutils-gold', 'libtoolize', 'which', - 'patchelf', ]; public const TOOLS_DEBIAN = [ @@ -31,7 +30,6 @@ class LinuxToolCheckList 'tar', 'unzip', 'gzip', 'gcc', 'g++', 'bzip2', 'cmake', 'patch', 'xz', 'libtoolize', 'which', - 'patchelf', ]; public const TOOLS_RHEL = [ @@ -39,8 +37,7 @@ class LinuxToolCheckList 'git', 'autoconf', 'automake', 'tar', 'unzip', 'gzip', 'gcc', 'g++', 'bzip2', 'cmake', 'patch', 'which', - 'xz', 'libtool', 'gettext-devel', - 'patchelf', 'file', + 'xz', 'libtool', 'gettext-devel', 'file', ]; public const TOOLS_ARCH = [ From f8b0c2c98078d0963ceb6846991825b0760838f3 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 19:08:14 +0100 Subject: [PATCH 31/34] add release thing to extension build too --- src/SPC/builder/Extension.php | 1 + src/SPC/builder/linux/LinuxBuilder.php | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index e79b886bf..040eae026 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -546,6 +546,7 @@ protected function getSharedExtensionEnv(): array 'CFLAGS' => $config['cflags'], 'CXXFLAGS' => $config['cflags'], 'LDFLAGS' => $config['ldflags'], + 'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), 'LIBS' => clean_spaces("{$preStatic} {$staticLibs} {$postStatic} {$sharedLibs}"), 'LD_LIBRARY_PATH' => BUILD_LIB_PATH, ]; diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 22c2d47a1..004c37def 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -283,9 +283,14 @@ protected function buildEmbed(): void // process libphp.so for shared embed $libphpSo = BUILD_LIB_PATH . '/libphp.so'; + $libphpSoDest = BUILD_LIB_PATH . '/libphp.so'; if (file_exists($libphpSo)) { // deploy libphp.so - $this->deployBinary($libphpSo, $libphpSo, false); + preg_match('/-release\s+(\S*)/', getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), $matches); + if (!empty($matches[1])) { + $libphpSoDest = str_replace('.so', '-' . $matches[1] . '.so', $libphpSo); + } + $this->deployBinary($libphpSo, $libphpSoDest, false); } // process shared extensions build-with-php From 94644d374ff8d10e678ae0cac9fdd236bd187593 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 19:12:16 +0100 Subject: [PATCH 32/34] fix --- src/SPC/builder/extension/memcache.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/SPC/builder/extension/memcache.php b/src/SPC/builder/extension/memcache.php index feba0151b..32cb301c6 100644 --- a/src/SPC/builder/extension/memcache.php +++ b/src/SPC/builder/extension/memcache.php @@ -62,20 +62,6 @@ public function patchBeforeSharedConfigure(): bool 'export CPPFLAGS="$CPPFLAGS $INCLUDES -I$abs_srcdir/main"', 'export CPPFLAGS="$CPPFLAGS $INCLUDES"', ); - // add for in-tree building - FileSystem::replaceFileStr( - SOURCE_PATH . '/php-src/ext/memcache/php_memcache.h', - <<<'EOF' -#ifndef PHP_MEMCACHE_H -#define PHP_MEMCACHE_H - -extern zend_module_entry memcache_module_entry; -#define phpext_memcache_ptr &memcache_module_entry - -#endif -EOF, - '' - ); return true; } From 3a17cec52193f01cf9e6354c476546747ae27fac Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 3 Jan 2026 19:15:57 +0100 Subject: [PATCH 33/34] deploy extensions with -release flag too --- src/SPC/builder/Extension.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index 040eae026..c0cb152d9 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -455,12 +455,17 @@ public function buildUnixShared(): void // process *.so file $soFile = BUILD_MODULES_PATH . '/' . $this->getName() . '.so'; + $soDest = $soFile; + preg_match('/-release\s+(\S*)/', getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), $matches); + if (!empty($matches[1])) { + $soDest = str_replace('.so', '-' . $matches[1] . '.so', $soFile); + } if (!file_exists($soFile)) { throw new ValidationException("extension {$this->getName()} build failed: {$soFile} not found", validation_module: "Extension {$this->getName()} build"); } /** @var UnixBuilderBase $builder */ $builder = $this->builder; - $builder->deployBinary($soFile, $soFile, false); + $builder->deployBinary($soFile, $soDest, false); } /** From 34910d18e959931ea2216c756ee3b42075495627 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sun, 4 Jan 2026 02:31:41 +0100 Subject: [PATCH 34/34] add patch point for shared ext build --- src/SPC/builder/Extension.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index c0cb152d9..816ea8116 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -401,10 +401,12 @@ public function buildShared(array $visited = []): void if (Config::getExt($this->getName(), 'type') === 'addon') { return; } + $this->builder->emitPatchPoint('before-shared-ext[' . $this->getName() . ']-build'); match (PHP_OS_FAMILY) { 'Darwin', 'Linux' => $this->buildUnixShared(), default => throw new WrongUsageException(PHP_OS_FAMILY . ' build shared extensions is not supported yet'), }; + $this->builder->emitPatchPoint('after-shared-ext[' . $this->getName() . ']-build'); } catch (SPCException $e) { $e->bindExtensionInfo(['extension_name' => $this->getName()]); throw $e;