From c6a227f4def9c1248c1474ea4b965de622a4b56b Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 7 Jul 2026 14:50:32 +0800 Subject: [PATCH 1/7] libde265 test --- src/Package/Library/libde265.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Package/Library/libde265.php b/src/Package/Library/libde265.php index d0fd83a5..3d387ddd 100644 --- a/src/Package/Library/libde265.php +++ b/src/Package/Library/libde265.php @@ -20,6 +20,7 @@ class libde265 extends LibraryPackage ->addConfigureArgs( '-DENABLE_SDL=OFF', '-DENABLE_DECODER=OFF', + // '-DENABLE_SIMD=OFF', '-DHAVE_NEON=OFF', ) ->build(); From a59473e4ab2af17650c260524e8f7520952e9dd1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 7 Jul 2026 15:03:31 +0800 Subject: [PATCH 2/7] ext-test-matrix generation fix --- .../Command/Dev/GenExtTestMatrixCommand.php | 45 +++++++++++++++++-- .../Dev/GenExtTestMatrixCommandTest.php | 22 +++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php index 44816863..674c8075 100644 --- a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php +++ b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php @@ -107,7 +107,12 @@ class GenExtTestMatrixCommand extends BaseCommand // Separate into regular and virtual extensions (build-static:false excluded globally) $all_regular = []; $all_virtual = []; + $all_libraries = []; foreach ($all as $pkg_name => $config) { + if (($config['type'] ?? '') === 'library') { + $all_libraries[$pkg_name] = $config; + continue; + } if (($config['type'] ?? '') !== 'php-extension') { continue; } @@ -154,10 +159,7 @@ class GenExtTestMatrixCommand extends BaseCommand $raw, fn ($d) => isset($pool_set[$d]) && $d !== $pkg_name )); - $os_lib_deps[$this->displayName($pkg_name)] = array_values(array_filter( - $raw, - fn ($d) => !str_starts_with($d, 'ext-') - )); + $os_lib_deps[$this->displayName($pkg_name)] = $this->collectLibraryDeps($raw, $all_libraries, $os); } $all_ext_lib_deps[$os] = $os_lib_deps; @@ -300,6 +302,41 @@ class GenExtTestMatrixCommand extends BaseCommand return str_starts_with($pkg_name, 'ext-') ? substr($pkg_name, 4) : $pkg_name; } + /** + * Collect direct and transitive library dependencies from a package dependency list. + * + * @param string[] $deps + * @param array $library_configs + * @param array $seen + * + * @return string[] + */ + private function collectLibraryDeps(array $deps, array $library_configs, string $platform, array $seen = []): array + { + $collected = []; + foreach ($deps as $dep) { + if (str_starts_with($dep, 'ext-') || isset($seen[$dep])) { + continue; + } + + $seen[$dep] = true; + $collected[$dep] = $dep; + + if (!isset($library_configs[$dep])) { + continue; + } + + $child_deps = array_merge( + $this->resolvePlatformList($library_configs[$dep], 'depends', $platform), + $this->resolvePlatformList($library_configs[$dep], 'suggests', $platform), + ); + foreach ($this->collectLibraryDeps($child_deps, $library_configs, $platform, $seen) as $child_dep) { + $collected[$child_dep] = $child_dep; + } + } + return array_values($collected); + } + /** * Split orphans into batches such that no two conflicting extensions share a batch. * Uses a greedy graph-coloring approach. diff --git a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php index b6beb6fb..4e3fc33a 100644 --- a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php +++ b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php @@ -176,6 +176,20 @@ class GenExtTestMatrixCommandTest extends TestCase } } + /** + * --for-libs must include extensions that depend on the library through other libraries. + */ + public function testForLibsFilterIncludesTransitiveLibraryDeps(): void + { + $matrix = $this->runMatrix(['--os' => 'Linux', '--for-libs' => 'libde265']); + + $this->assertNotEmpty($matrix, '--for-libs=libde265 must yield at least one entry'); + foreach ($matrix as $entry) { + $parts = explode(',', $entry['extension']); + $this->assertContains('imagick', $parts, "Entry {$entry['extension']} should not appear in --for-libs=libde265 results"); + } + } + /** * --tier2 must produce only Tier2 runners and no Windows entries. */ @@ -260,12 +274,14 @@ class GenExtTestMatrixCommandTest extends TestCase * - ext-redis simple orphan * - ext-xml depends on lib 'libxml2' * - ext-dom depends on ext-xml (DFS chain) + * - ext-imagick depends on imagemagick -> libheif -> libde265 * - ext-linux-only restricted to Linux via os: [Linux] */ private static function buildFixture(): array { // php-extension must be a non-empty assoc array ([] fails is_assoc_array() check). $ext = static fn (array $phpExt = ['arg-type' => 'standard'], array $topLevel = []): array => array_merge(['type' => 'php-extension', 'php-extension' => $phpExt], $topLevel); + $lib = static fn (array $topLevel = []): array => array_merge(['type' => 'library', 'artifact' => ['source' => 'custom']], $topLevel); return [ // Isolated standalones @@ -284,6 +300,12 @@ class GenExtTestMatrixCommandTest extends TestCase 'ext-xml' => $ext(['arg-type' => 'standard'], ['depends' => ['libxml2']]), 'ext-dom' => $ext(['arg-type' => 'standard'], ['depends' => ['ext-xml']]), + // Transitive library chain: imagick -> imagemagick -> libheif -> libde265 + 'ext-imagick' => $ext(['arg-type' => 'standard'], ['depends' => ['imagemagick']]), + 'imagemagick' => $lib(['depends' => ['libheif']]), + 'libheif' => $lib(['depends' => ['libde265']]), + 'libde265' => $lib(), + // OS-restricted to Linux only 'ext-linux-only' => $ext(['os' => ['Linux']]), ]; From dc55881b7823c6e072650b591ab2802e32805c59 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 7 Jul 2026 15:21:19 +0800 Subject: [PATCH 3/7] libde265 fix build --- src/Package/Library/libde265.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Package/Library/libde265.php b/src/Package/Library/libde265.php index 3d387ddd..c2134aa7 100644 --- a/src/Package/Library/libde265.php +++ b/src/Package/Library/libde265.php @@ -20,7 +20,7 @@ class libde265 extends LibraryPackage ->addConfigureArgs( '-DENABLE_SDL=OFF', '-DENABLE_DECODER=OFF', - // '-DENABLE_SIMD=OFF', + '-DENABLE_SIMD=OFF', '-DHAVE_NEON=OFF', ) ->build(); From cc448d463b84262a83296123a8ce82bbdfaa62c7 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 7 Jul 2026 15:42:34 +0800 Subject: [PATCH 4/7] simdjson test --- src/Package/Extension/simdjson.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Package/Extension/simdjson.php b/src/Package/Extension/simdjson.php index e04c415a..0a548a66 100644 --- a/src/Package/Extension/simdjson.php +++ b/src/Package/Extension/simdjson.php @@ -50,6 +50,7 @@ class simdjson extends PhpExtensionPackage if (!str_contains((string) $extra, '-lstdc++')) { f_putenv('SPC_COMPILER_EXTRA=' . clean_spaces($extra . ' -lstdc++')); } + $env['CFLAGS'] .= ' -Xclang -target-feature -Xclang +evex512'; $env['CXXFLAGS'] .= ' -Xclang -target-feature -Xclang +evex512'; } From 331da67049d0d084a0d3488de99f417c43c24cc2 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 7 Jul 2026 15:48:35 +0800 Subject: [PATCH 5/7] Fix gen-ext-test-matrix AND bug (should be OR) --- .../Command/Dev/GenExtTestMatrixCommand.php | 25 ++++++++++--------- .../Dev/GenExtTestMatrixCommandTest.php | 13 ++++++++++ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php index 674c8075..6b5c9e6d 100644 --- a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php +++ b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php @@ -248,22 +248,23 @@ class GenExtTestMatrixCommand extends BaseCommand } } - if (!empty($filter_extensions)) { - $entries = array_values(array_filter($entries, function (array $entry) use ($filter_extensions): bool { + if (!empty($filter_extensions) || !empty($filter_libs)) { + $entries = array_values(array_filter($entries, function (array $entry) use ($filter_extensions, $filter_libs, $all_ext_lib_deps): bool { $names = explode(',', $entry['extension']); - return count(array_intersect($names, $filter_extensions)) > 0; - })); - } - if (!empty($filter_libs)) { - $entries = array_values(array_filter($entries, function (array $entry) use ($filter_libs, $all_ext_lib_deps): bool { - $names = explode(',', $entry['extension']); - $lib_deps = $all_ext_lib_deps[$entry['os']] ?? []; - foreach ($names as $name) { - if (count(array_intersect($lib_deps[$name] ?? [], $filter_libs)) > 0) { - return true; + if (!empty($filter_extensions) && count(array_intersect($names, $filter_extensions)) > 0) { + return true; + } + + if (!empty($filter_libs)) { + $lib_deps = $all_ext_lib_deps[$entry['os']] ?? []; + foreach ($names as $name) { + if (count(array_intersect($lib_deps[$name] ?? [], $filter_libs)) > 0) { + return true; + } } } + return false; })); } diff --git a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php index 4e3fc33a..4db6da59 100644 --- a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php +++ b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php @@ -190,6 +190,17 @@ class GenExtTestMatrixCommandTest extends TestCase } } + /** + * Multiple filters should include entries matching any changed package. + */ + public function testExtensionAndLibraryFiltersAreCombinedAsUnion(): void + { + $matrix = $this->runMatrix(['--os' => 'Linux', '--for-extensions' => 'simdjson', '--for-libs' => 'libde265']); + + $this->assertNotEmpty($this->findEntriesContaining($matrix, 'simdjson'), 'simdjson entry must be included'); + $this->assertNotEmpty($this->findEntriesContaining($matrix, 'imagick'), 'imagick entry must be included through libde265'); + } + /** * --tier2 must produce only Tier2 runners and no Windows entries. */ @@ -272,6 +283,7 @@ class GenExtTestMatrixCommandTest extends TestCase * - ext-swoole-hook-* virtual (arg-type: none) — must be bundled with swoole * - ext-curl simple orphan, depended on by swoole but must NOT be pulled into swoole entry * - ext-redis simple orphan + * - ext-simdjson simple orphan used for combined filter tests * - ext-xml depends on lib 'libxml2' * - ext-dom depends on ext-xml (DFS chain) * - ext-imagick depends on imagemagick -> libheif -> libde265 @@ -295,6 +307,7 @@ class GenExtTestMatrixCommandTest extends TestCase // Simple orphans 'ext-curl' => $ext(), 'ext-redis' => $ext(), + 'ext-simdjson' => $ext(), // DFS chain: dom depends on xml; xml depends on lib 'libxml2' 'ext-xml' => $ext(['arg-type' => 'standard'], ['depends' => ['libxml2']]), From 160d7f55375dde39d3d68cfc28e9e7716fa3e126 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 8 Jul 2026 11:41:41 +0800 Subject: [PATCH 6/7] fix: disable undefined behavior sanitizer in build flags --- src/Package/Extension/simdjson.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Package/Extension/simdjson.php b/src/Package/Extension/simdjson.php index 0a548a66..4939c811 100644 --- a/src/Package/Extension/simdjson.php +++ b/src/Package/Extension/simdjson.php @@ -51,8 +51,8 @@ class simdjson extends PhpExtensionPackage f_putenv('SPC_COMPILER_EXTRA=' . clean_spaces($extra . ' -lstdc++')); } - $env['CFLAGS'] .= ' -Xclang -target-feature -Xclang +evex512'; - $env['CXXFLAGS'] .= ' -Xclang -target-feature -Xclang +evex512'; + $env['CFLAGS'] .= ' -fno-sanitize=undefined -Xclang -target-feature -Xclang +evex512'; + $env['CXXFLAGS'] .= ' -fno-sanitize=undefined -Xclang -target-feature -Xclang +evex512'; } return $env; } @@ -64,8 +64,8 @@ class simdjson extends PhpExtensionPackage return; } $extra_cflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') ?: ''; - GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS=' . trim($extra_cflags . ' -Xclang -target-feature -Xclang +evex512')); + GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS=' . trim($extra_cflags . ' -fno-sanitize=undefined -Xclang -target-feature -Xclang +evex512')); $extra_cxxflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS') ?: ''; - GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS=' . trim($extra_cxxflags . ' -Xclang -target-feature -Xclang +evex512')); + GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS=' . trim($extra_cxxflags . ' -fno-sanitize=undefined -Xclang -target-feature -Xclang +evex512')); } } From facc7bc5a7d875550c3ff79e4ccfdd5ca997f0bb Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 8 Jul 2026 11:43:35 +0800 Subject: [PATCH 7/7] test swoole --- src/Package/Extension/swoole.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Package/Extension/swoole.php b/src/Package/Extension/swoole.php index c269ba54..10fb1928 100644 --- a/src/Package/Extension/swoole.php +++ b/src/Package/Extension/swoole.php @@ -30,6 +30,7 @@ class swoole extends PhpExtensionPackage if ($installer->getPhpExtensionPackage('swoole-hook-odbc') && $installer->getPhpExtensionPackage('pdo_odbc')?->isBuildStatic()) { throw new WrongUsageException('swoole-hook-odbc provides pdo_odbc, if you enable odbc hook for swoole, you must remove pdo_odbc extension.'); } + // swoole-hook-pgsql conflicts with pdo_pgsql if ($installer->getPhpExtensionPackage('swoole-hook-pgsql') && $installer->getPhpExtensionPackage('pdo_pgsql')?->isBuildStatic()) { throw new WrongUsageException('swoole-hook-pgsql provides pdo_pgsql, if you enable pgsql hook for swoole, you must remove pdo_pgsql extension.');