From c6a227f4def9c1248c1474ea4b965de622a4b56b Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 7 Jul 2026 14:50:32 +0800 Subject: [PATCH 1/5] 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 d0fd83a54..3d387dddd 100644 --- a/src/Package/Library/libde265.php +++ b/src/Package/Library/libde265.php @@ -20,6 +20,7 @@ public function buildUnix(): void ->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/5] 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 448168635..674c80759 100644 --- a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php +++ b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php @@ -107,7 +107,12 @@ public function handle(): int // 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 @@ public function handle(): int $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 @@ private function displayName(string $pkg_name): string 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 b6beb6fb7..4e3fc33aa 100644 --- a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php +++ b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php @@ -176,6 +176,20 @@ public function testForLibsFilter(): void } } + /** + * --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 @@ private function findEntriesContaining(array $matrix, string ...$names): array * - 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 @@ private static function buildFixture(): array '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/5] 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 3d387dddd..c2134aa7f 100644 --- a/src/Package/Library/libde265.php +++ b/src/Package/Library/libde265.php @@ -20,7 +20,7 @@ public function buildUnix(): void ->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/5] 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 e04c415ac..0a548a66b 100644 --- a/src/Package/Extension/simdjson.php +++ b/src/Package/Extension/simdjson.php @@ -50,6 +50,7 @@ public function getSharedExtensionEnv(): array 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/5] 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 674c80759..6b5c9e6df 100644 --- a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php +++ b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php @@ -248,22 +248,23 @@ public function handle(): int } } - 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 4e3fc33aa..4db6da59d 100644 --- a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php +++ b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php @@ -190,6 +190,17 @@ public function testForLibsFilterIncludesTransitiveLibraryDeps(): void } } + /** + * 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 @@ private function findEntriesContaining(array $matrix, string ...$names): array * - 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 @@ private static function buildFixture(): array // 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']]),