From 1e898d271dff11158052b161b18d9eb973a46615 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 6 Feb 2024 16:06:09 +0800 Subject: [PATCH 1/6] add with-suggested-libs and with-suggested-exts --- src/SPC/command/BuildCliCommand.php | 15 ++++++++------- src/SPC/command/dev/AllExtCommand.php | 5 ++--- src/SPC/util/DependencyUtil.php | 23 +++++++++++++++++++---- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/SPC/command/BuildCliCommand.php b/src/SPC/command/BuildCliCommand.php index fa5e40b6..b45ef0b3 100644 --- a/src/SPC/command/BuildCliCommand.php +++ b/src/SPC/command/BuildCliCommand.php @@ -23,11 +23,11 @@ class BuildCliCommand extends BuildCommand { $this->addArgument('extensions', InputArgument::REQUIRED, 'The extensions will be compiled, comma separated'); $this->addOption('with-libs', null, InputOption::VALUE_REQUIRED, 'add additional libraries, comma separated', ''); - $this->addOption('build-micro', null, null, 'build micro'); - $this->addOption('build-cli', null, null, 'build cli'); - $this->addOption('build-fpm', null, null, 'build fpm'); - $this->addOption('build-embed', null, null, 'build embed'); - $this->addOption('build-all', null, null, 'build cli, micro, fpm, embed'); + $this->addOption('build-micro', null, null, 'Build micro SAPI'); + $this->addOption('build-cli', null, null, 'Build cli SAPI'); + $this->addOption('build-fpm', null, null, 'Build fpm SAPI'); + $this->addOption('build-embed', null, null, 'Build embed SAPI'); + $this->addOption('build-all', null, null, 'Build all SAPI'); $this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions'); $this->addOption('enable-zts', null, null, 'enable ZTS support'); $this->addOption('disable-opcache-jit', null, null, 'disable opcache jit'); @@ -61,8 +61,9 @@ class BuildCliCommand extends BuildCommand try { // create builder $builder = BuilderProvider::makeBuilderByInput($this->input); - // calculate dependencies - [$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries); + $include_suggest_ext = $this->getOption('with-suggested-exts'); + $include_suggest_lib = $this->getOption('with-suggested-libs'); + [$extensions, $libraries, $not_included] = DependencyUtil::getExtsAndLibs($extensions, $libraries, $include_suggest_ext, $include_suggest_lib); // print info $indent_texts = [ diff --git a/src/SPC/command/dev/AllExtCommand.php b/src/SPC/command/dev/AllExtCommand.php index 399156c2..0a161465 100644 --- a/src/SPC/command/dev/AllExtCommand.php +++ b/src/SPC/command/dev/AllExtCommand.php @@ -15,8 +15,6 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Style\SymfonyStyle; -use function Laravel\Prompts\table; - #[AsCommand('dev:extensions', 'Helper command that lists available extension details', ['list-ext'])] class AllExtCommand extends BaseCommand { @@ -88,7 +86,8 @@ class AllExtCommand extends BaseCommand if ($data === []) { $style->warning('Unknown extension selected: ' . implode(',', $extensions)); } else { - table($columns, $data); + $func = PHP_OS_FAMILY === 'Windows' ? [$style, 'table'] : '\Laravel\Prompts\table'; + call_user_func($func, $columns, $data); } return static::SUCCESS; diff --git a/src/SPC/util/DependencyUtil.php b/src/SPC/util/DependencyUtil.php index 4e0b74b1..fe958b82 100644 --- a/src/SPC/util/DependencyUtil.php +++ b/src/SPC/util/DependencyUtil.php @@ -14,6 +14,20 @@ use SPC\store\Config; */ class DependencyUtil { + public static function getExtsAndLibs(array $exts, array $additional_libs = [], bool $include_suggested_exts = false, bool $include_suggested_libs = false): array + { + if (!$include_suggested_exts && !$include_suggested_libs) { + return self::getExtLibsByDeps($exts, $additional_libs); + } + if ($include_suggested_exts && $include_suggested_libs) { + return self::getAllExtLibsByDeps($exts, $additional_libs); + } + if (!$include_suggested_exts) { + return self::getExtLibsByDeps($exts, $additional_libs); + } + return self::getAllExtLibsByDeps($exts, $additional_libs, false); + } + /** * Obtain the dependent lib list according to the required ext list, and sort according to the dependency * @@ -24,7 +38,7 @@ class DependencyUtil * @throws RuntimeException * @throws FileSystemException */ - public static function getExtLibsByDeps(array $exts, array $additional_libs = []): array + public static function getExtLibsByDeps(array $exts, array $additional_libs = [], bool $include_suggested_exts = false): array { $sorted = []; $visited = []; @@ -99,7 +113,7 @@ class DependencyUtil return $final; } - public static function getAllExtLibsByDeps(array $exts): array + public static function getAllExtLibsByDeps(array $exts, array $additional_libs = [], bool $include_suggested_libs = true): array { $sorted = []; $visited = []; @@ -109,12 +123,13 @@ class DependencyUtil self::visitExtAllDeps($ext, $visited, $sorted); } } - $libs = []; + $libs = $additional_libs; foreach ($sorted as $ext) { if (!in_array($ext, $exts)) { $not_included_exts[] = $ext; } - foreach (array_merge(Config::getExt($ext, 'lib-depends', []), Config::getExt($ext, 'lib-suggests', [])) as $dep) { + $total = $include_suggested_libs ? array_merge(Config::getExt($ext, 'lib-depends', []), Config::getExt($ext, 'lib-suggests', [])) : Config::getExt($ext, 'lib-depends', []); + foreach ($total as $dep) { if (!in_array($dep, $libs)) { $libs[] = $dep; } From 939db75268eba2d27334fc49548bddd4770745fd Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 16 Feb 2024 18:56:33 +0800 Subject: [PATCH 2/6] refactor DependencyUtil, use for-libs and for-sources instead of `by` --- src/SPC/builder/unix/UnixBuilderBase.php | 2 +- src/SPC/builder/windows/WindowsBuilder.php | 2 +- src/SPC/command/BuildLibsCommand.php | 2 +- src/SPC/command/DownloadCommand.php | 2 +- src/SPC/command/DumpLicenseCommand.php | 18 +- src/SPC/command/dev/AllExtCommand.php | 2 +- src/SPC/util/DependencyUtil.php | 286 ++++++++++----------- 7 files changed, 145 insertions(+), 169 deletions(-) diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index c48c3ef3..583ad812 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -107,7 +107,7 @@ abstract class UnixBuilderBase extends BuilderBase // if no libs specified, compile all supported libs if ($sorted_libraries === [] && $this->isLibsOnly()) { $libraries = array_keys($support_lib_list); - $sorted_libraries = DependencyUtil::getLibsByDeps($libraries); + $sorted_libraries = DependencyUtil::getLibs($libraries); } // pkg-config must be compiled first, whether it is specified or not diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index 265751ba..b007e7ff 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -192,7 +192,7 @@ class WindowsBuilder extends BuilderBase // if no libs specified, compile all supported libs if ($sorted_libraries === [] && $this->isLibsOnly()) { $libraries = array_keys($support_lib_list); - $sorted_libraries = DependencyUtil::getLibsByDeps($libraries); + $sorted_libraries = DependencyUtil::getLibs($libraries); } // add lib object for builder diff --git a/src/SPC/command/BuildLibsCommand.php b/src/SPC/command/BuildLibsCommand.php index f3fb8897..f4d3b26c 100644 --- a/src/SPC/command/BuildLibsCommand.php +++ b/src/SPC/command/BuildLibsCommand.php @@ -60,7 +60,7 @@ class BuildLibsCommand extends BuildCommand // 只编译 library 的情况下,标记 $builder->setLibsOnly(); // 编译和检查库完整 - $libraries = DependencyUtil::getLibsByDeps($libraries); + $libraries = DependencyUtil::getLibs($libraries); $builder->buildLibs($libraries); $time = round(microtime(true) - START_TIME, 3); diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index 542dae34..fa7f7543 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -214,7 +214,7 @@ class DownloadCommand extends BaseCommand */ private function calculateSourcesByExt(array $extensions, bool $include_suggests = true): array { - [$extensions, $libraries] = $include_suggests ? DependencyUtil::getAllExtLibsByDeps($extensions) : DependencyUtil::getExtLibsByDeps($extensions); + [$extensions, $libraries] = $include_suggests ? DependencyUtil::getExtsAndLibs($extensions, [], true, true) : DependencyUtil::getExtsAndLibs($extensions); $sources = []; foreach ($extensions as $extension) { if (Config::getExt($extension, 'type') === 'external') { diff --git a/src/SPC/command/DumpLicenseCommand.php b/src/SPC/command/DumpLicenseCommand.php index 5535f820..2d01a692 100644 --- a/src/SPC/command/DumpLicenseCommand.php +++ b/src/SPC/command/DumpLicenseCommand.php @@ -22,8 +22,8 @@ class DumpLicenseCommand extends BaseCommand { $this->addOption('for-extensions', null, InputOption::VALUE_REQUIRED, 'Dump by extensions and related libraries', null); $this->addOption('without-php', null, InputOption::VALUE_NONE, 'Dump without php-src'); - $this->addOption('by-libs', null, InputOption::VALUE_REQUIRED, 'Dump by libraries', null); - $this->addOption('by-sources', null, InputOption::VALUE_REQUIRED, 'Dump by original sources (source.json)', null); + $this->addOption('for-libs', null, InputOption::VALUE_REQUIRED, 'Dump by libraries', null); + $this->addOption('for-sources', null, InputOption::VALUE_REQUIRED, 'Dump by original sources (source.json)', null); $this->addOption('dump-dir', null, InputOption::VALUE_REQUIRED, 'Change dump directory', BUILD_ROOT_PATH . '/license'); } @@ -39,7 +39,7 @@ class DumpLicenseCommand extends BaseCommand // 从参数中获取要编译的 extensions,并转换为数组 $extensions = array_map('trim', array_filter(explode(',', $this->getOption('for-extensions')))); // 根据提供的扩展列表获取依赖库列表并编译 - [$extensions, $libraries] = DependencyUtil::getExtLibsByDeps($extensions); + [$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions); $dumper->addExts($extensions); $dumper->addLibs($libraries); if (!$this->getOption('without-php')) { @@ -52,22 +52,22 @@ class DumpLicenseCommand extends BaseCommand $this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir')); return static::SUCCESS; } - if ($this->getOption('by-libs') !== null) { - $libraries = array_map('trim', array_filter(explode(',', $this->getOption('by-libs')))); - $libraries = DependencyUtil::getLibsByDeps($libraries); + if ($this->getOption('for-libs') !== null) { + $libraries = array_map('trim', array_filter(explode(',', $this->getOption('for-libs')))); + $libraries = DependencyUtil::getLibs($libraries); $dumper->addLibs($libraries); $dumper->dump($this->getOption('dump-dir')); $this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir')); return static::SUCCESS; } - if ($this->getOption('by-sources') !== null) { - $sources = array_map('trim', array_filter(explode(',', $this->getOption('by-sources')))); + if ($this->getOption('for-sources') !== null) { + $sources = array_map('trim', array_filter(explode(',', $this->getOption('for-sources')))); $dumper->addSources($sources); $dumper->dump($this->getOption('dump-dir')); $this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir')); return static::SUCCESS; } - $this->output->writeln('You must use one of "--for-extensions=", "--by-libs=", "--by-sources=" to dump'); + $this->output->writeln('You must use one of "--for-extensions=", "--for-libs=", "--for-sources=" to dump'); return static::FAILURE; } } diff --git a/src/SPC/command/dev/AllExtCommand.php b/src/SPC/command/dev/AllExtCommand.php index 0a161465..90675eb5 100644 --- a/src/SPC/command/dev/AllExtCommand.php +++ b/src/SPC/command/dev/AllExtCommand.php @@ -59,7 +59,7 @@ class AllExtCommand extends BaseCommand } try { - [, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps([$extension]); + [, $libraries, $not_included] = DependencyUtil::getExtsAndLibs([$extension]); } catch (WrongUsageException) { $libraries = $not_included = []; } diff --git a/src/SPC/util/DependencyUtil.php b/src/SPC/util/DependencyUtil.php index fe958b82..e82a93dc 100644 --- a/src/SPC/util/DependencyUtil.php +++ b/src/SPC/util/DependencyUtil.php @@ -5,104 +5,164 @@ declare(strict_types=1); namespace SPC\util; use SPC\exception\FileSystemException; -use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\Config; /** - * 依赖处理工具类,包含处理扩展、库的依赖列表顺序等 + * Dependency processing tool class, including processing extensions, library dependency list order, etc. */ class DependencyUtil { - public static function getExtsAndLibs(array $exts, array $additional_libs = [], bool $include_suggested_exts = false, bool $include_suggested_libs = false): array + /** + * Convert platform extensions to library dependencies and suggestions. + * + * @throws WrongUsageException + * @throws FileSystemException + */ + public static function platExtToLibs(): array { - if (!$include_suggested_exts && !$include_suggested_libs) { - return self::getExtLibsByDeps($exts, $additional_libs); + $exts = Config::getExts(); + $libs = Config::getLibs(); + $dep_list = []; + foreach ($exts as $ext_name => $ext) { + // convert ext-depends value to ext@xxx + $ext_depends = Config::getExt($ext_name, 'ext-depends', []); + $ext_depends = array_map(fn ($x) => "ext@{$x}", $ext_depends); + // convert ext-suggests value to ext@xxx + $ext_suggests = Config::getExt($ext_name, 'ext-suggests', []); + $ext_suggests = array_map(fn ($x) => "ext@{$x}", $ext_suggests); + // merge ext-depends with lib-depends + $lib_depends = Config::getExt($ext_name, 'lib-depends', []); + $depends = array_merge($ext_depends, $lib_depends); + // merge ext-suggests with lib-suggests + $lib_suggests = Config::getExt($ext_name, 'lib-suggests', []); + $suggests = array_merge($ext_suggests, $lib_suggests); + $dep_list["ext@{$ext_name}"] = [ + 'depends' => $depends, + 'suggests' => $suggests, + ]; } - if ($include_suggested_exts && $include_suggested_libs) { - return self::getAllExtLibsByDeps($exts, $additional_libs); + foreach ($libs as $lib_name => $lib) { + $dep_list[$lib_name] = [ + 'depends' => Config::getLib($lib_name, 'lib-depends', []), + 'suggests' => Config::getLib($lib_name, 'lib-suggests', []), + ]; } - if (!$include_suggested_exts) { - return self::getExtLibsByDeps($exts, $additional_libs); - } - return self::getAllExtLibsByDeps($exts, $additional_libs, false); + // here is an array that only contains dependency map + return $dep_list; } /** - * Obtain the dependent lib list according to the required ext list, and sort according to the dependency - * - * @param array $exts extensions list - * @param array $additional_libs List of additional libraries to add to activate the extra library features triggered by lib-suggests - * @return array Returns an array containing three arrays, [extensions, libraries, not included extensions] * @throws WrongUsageException - * @throws RuntimeException * @throws FileSystemException */ - public static function getExtLibsByDeps(array $exts, array $additional_libs = [], bool $include_suggested_exts = false): array + public static function getLibs(array $libs, bool $include_suggested_libs = false): array { - $sorted = []; - $visited = []; - $not_included_exts = []; - foreach ($exts as $ext) { - if (!isset($visited[$ext])) { - self::visitExtDeps($ext, $visited, $sorted); - } - } - $sorted_suggests = []; - $visited_suggests = []; - $final = []; - foreach ($exts as $ext) { - if (!isset($visited_suggests[$ext])) { - self::visitExtAllDeps($ext, $visited_suggests, $sorted_suggests); - } - } - foreach ($sorted_suggests as $suggest) { - if (in_array($suggest, $sorted)) { - $final[] = $suggest; - } - } - $libs = $additional_libs; + $dep_list = self::platExtToLibs(); - foreach ($final as $ext) { - if (!in_array($ext, $exts)) { - $not_included_exts[] = $ext; - } - foreach (Config::getExt($ext, 'lib-depends', []) as $lib) { - if (!in_array($lib, $libs)) { - $libs[] = $lib; + if ($include_suggested_libs) { + foreach ($dep_list as $name => $obj) { + foreach ($obj['suggests'] as $id => $suggest) { + if (!str_starts_with($suggest, 'ext@')) { + $dep_list[$name]['depends'][] = $suggest; + array_splice($dep_list[$name]['suggests'], $id, 1); + } } } } - return [$final, self::getLibsByDeps($libs), $not_included_exts]; + + $final = self::doVisitPlat($libs, $dep_list); + + $libs_final = []; + foreach ($final as $item) { + if (!str_starts_with($item, 'ext@')) { + $libs_final[] = $item; + } + } + return $libs_final; } /** - * 根据 lib 库的依赖关系进行一个排序,同时返回多出来的依赖列表 - * - * @param array $libs 要排序的 libs 列表 - * @return array 排序后的列表 - * @throws FileSystemException - * @throws RuntimeException - * @throws WrongUsageException + * @throws FileSystemException|WrongUsageException */ - public static function getLibsByDeps(array $libs): array + public static function getExtsAndLibs(array $exts, array $additional_libs = [], bool $include_suggested_exts = false, bool $include_suggested_libs = false): array { - $sorted = []; - $visited = []; + $dep_list = self::platExtToLibs(); - // 遍历所有 - foreach ($libs as $lib) { - if (!isset($visited[$lib])) { - self::visitLibDeps($lib, $visited, $sorted); + // include suggested extensions + if ($include_suggested_exts) { + // check every deps suggests contains ext@ + foreach ($dep_list as $name => $obj) { + foreach ($obj['suggests'] as $id => $suggest) { + if (str_starts_with($suggest, 'ext@')) { + $dep_list[$name]['depends'][] = $suggest; + array_splice($dep_list[$name]['suggests'], $id, 1); + } + } } } + // include suggested libraries + if ($include_suggested_libs) { + // check every deps suggests + foreach ($dep_list as $name => $obj) { + foreach ($obj['suggests'] as $id => $suggest) { + if (!str_starts_with($suggest, 'ext@')) { + $dep_list[$name]['depends'][] = $suggest; + array_splice($dep_list[$name]['suggests'], $id, 1); + } + } + } + } + + // convert ext_name to ext@ext_name + $origin_exts = $exts; + $exts = array_map(fn ($x) => "ext@{$x}", $exts); + $exts = array_merge($exts, $additional_libs); + + $final = self::doVisitPlat($exts, $dep_list); + + // revert array + $exts_final = []; + $libs_final = []; + $not_included_final = []; + foreach ($final as $item) { + if (str_starts_with($item, 'ext@')) { + $tmp = substr($item, 4); + if (!in_array($tmp, $origin_exts)) { + $not_included_final[] = $tmp; + } + $exts_final[] = $tmp; + } else { + $libs_final[] = $item; + } + } + return [$exts_final, $libs_final, $not_included_final]; + } + + /** + * @throws WrongUsageException + */ + private static function doVisitPlat(array $deps, array $dep_list): array + { + // default: get extension exts and libs sorted by dep_list + $sorted = []; + $visited = []; + foreach ($deps as $ext_name) { + if (!isset($dep_list[$ext_name])) { + $ext_name = str_starts_with($ext_name, 'ext@') ? ('Extension [' . substr($ext_name, 4) . ']') : ('Library [' . $ext_name . ']'); + throw new WrongUsageException("{$ext_name} not exist !"); + } + if (!isset($visited[$ext_name])) { + self::visitPlatDeps($ext_name, $dep_list, $visited, $sorted); + } + } $sorted_suggests = []; $visited_suggests = []; $final = []; - foreach ($libs as $lib) { - if (!isset($visited_suggests[$lib])) { - self::visitLibAllDeps($lib, $visited_suggests, $sorted_suggests); + foreach ($deps as $ext_name) { + if (!isset($visited_suggests[$ext_name])) { + self::visitPlatAllDeps($ext_name, $dep_list, $visited_suggests, $sorted_suggests); } } foreach ($sorted_suggests as $suggest) { @@ -113,50 +173,7 @@ class DependencyUtil return $final; } - public static function getAllExtLibsByDeps(array $exts, array $additional_libs = [], bool $include_suggested_libs = true): array - { - $sorted = []; - $visited = []; - $not_included_exts = []; - foreach ($exts as $ext) { - if (!isset($visited[$ext])) { - self::visitExtAllDeps($ext, $visited, $sorted); - } - } - $libs = $additional_libs; - foreach ($sorted as $ext) { - if (!in_array($ext, $exts)) { - $not_included_exts[] = $ext; - } - $total = $include_suggested_libs ? array_merge(Config::getExt($ext, 'lib-depends', []), Config::getExt($ext, 'lib-suggests', [])) : Config::getExt($ext, 'lib-depends', []); - foreach ($total as $dep) { - if (!in_array($dep, $libs)) { - $libs[] = $dep; - } - } - } - return [$sorted, self::getAllLibsByDeps($libs), $not_included_exts]; - } - - public static function getAllLibsByDeps(array $libs): array - { - $sorted = []; - $visited = []; - - foreach ($libs as $lib) { - if (!isset($visited[$lib])) { - self::visitLibAllDeps($lib, $visited, $sorted); - } - } - return $sorted; - } - - /** - * @throws FileSystemException - * @throws RuntimeException - * @throws WrongUsageException - */ - private static function visitLibAllDeps(string $lib_name, array &$visited, array &$sorted): void + private static function visitPlatAllDeps(string $lib_name, array $dep_list, array &$visited, array &$sorted): void { // 如果已经识别到了,那就不管 if (isset($visited[$lib_name])) { @@ -164,37 +181,13 @@ class DependencyUtil } $visited[$lib_name] = true; // 遍历该依赖的所有依赖(此处的 getLib 如果检测到当前库不存在的话,会抛出异常) - foreach (array_merge(Config::getLib($lib_name, 'lib-depends', []), Config::getLib($lib_name, 'lib-suggests', [])) as $dep) { - self::visitLibDeps($dep, $visited, $sorted); + foreach (array_merge($dep_list[$lib_name]['depends'], $dep_list[$lib_name]['suggests']) as $dep) { + self::visitPlatAllDeps($dep, $dep_list, $visited, $sorted); } $sorted[] = $lib_name; } - /** - * @throws RuntimeException - * @throws FileSystemException - * @throws WrongUsageException - */ - private static function visitExtAllDeps(string $ext_name, array &$visited, array &$sorted): void - { - // 如果已经识别到了,那就不管 - if (isset($visited[$ext_name])) { - return; - } - $visited[$ext_name] = true; - // 遍历该依赖的所有依赖(此处的 getLib 如果检测到当前库不存在的话,会抛出异常) - foreach (array_merge(Config::getExt($ext_name, 'ext-depends', []), Config::getExt($ext_name, 'ext-suggests', [])) as $dep) { - self::visitExtDeps($dep, $visited, $sorted); - } - $sorted[] = $ext_name; - } - - /** - * @throws RuntimeException - * @throws FileSystemException - * @throws WrongUsageException - */ - private static function visitLibDeps(string $lib_name, array &$visited, array &$sorted): void + private static function visitPlatDeps(string $lib_name, array $dep_list, array &$visited, array &$sorted): void { // 如果已经识别到了,那就不管 if (isset($visited[$lib_name])) { @@ -202,26 +195,9 @@ class DependencyUtil } $visited[$lib_name] = true; // 遍历该依赖的所有依赖(此处的 getLib 如果检测到当前库不存在的话,会抛出异常) - foreach (Config::getLib($lib_name, 'lib-depends', []) as $dep) { - self::visitLibDeps($dep, $visited, $sorted); + foreach ($dep_list[$lib_name]['depends'] as $dep) { + self::visitPlatDeps($dep, $dep_list, $visited, $sorted); } $sorted[] = $lib_name; } - - /** - * @throws RuntimeException - * @throws FileSystemException - * @throws WrongUsageException - */ - private static function visitExtDeps(string $ext_name, array &$visited, array &$sorted): void - { - if (isset($visited[$ext_name])) { - return; - } - $visited[$ext_name] = true; - foreach (Config::getExt($ext_name, 'ext-depends', []) as $dep) { - self::visitExtDeps($dep, $visited, $sorted); - } - $sorted[] = $ext_name; - } } From 2649dcd05cc0f3aaa138b82d317adef42b9154c3 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 16 Feb 2024 18:56:59 +0800 Subject: [PATCH 3/6] add BuilderBase::getPHPVersionFromArchive --- src/SPC/builder/BuilderBase.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index ed7a21a3..2314a7f2 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -231,6 +231,30 @@ abstract class BuilderBase throw new RuntimeException('PHP version file format is malformed, please remove it and download again'); } + /** + * Get PHP version from archive file name. + * + * @param null|string $file php-*.*.*.tar.gz filename, read from lockfile if empty + */ + public function getPHPVersionFromArchive(?string $file = null): false|string + { + if ($file === null) { + $lock = file_exists(DOWNLOAD_PATH . '/.lock.json') ? file_get_contents(DOWNLOAD_PATH . '/.lock.json') : false; + if ($lock === false) { + return false; + } + $lock = json_decode($lock, true); + $file = $lock['php-src']['filename'] ?? null; + if ($file === null) { + return false; + } + } + if (preg_match('/php-(\d+\.\d+\.\d+)/', $file, $match)) { + return $match[1]; + } + return false; + } + /** * Get build type name string to display. * From d9bd96af71a58e25b01bfff6b8e5dadd42cc663d Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 16 Feb 2024 18:57:12 +0800 Subject: [PATCH 4/6] add dependency util tests --- tests/SPC/util/DependencyUtilTest.php | 90 +++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tests/SPC/util/DependencyUtilTest.php diff --git a/tests/SPC/util/DependencyUtilTest.php b/tests/SPC/util/DependencyUtilTest.php new file mode 100644 index 00000000..b77d9d79 --- /dev/null +++ b/tests/SPC/util/DependencyUtilTest.php @@ -0,0 +1,90 @@ + [ + 'type' => 'url', + 'url' => 'https://pecl.php.net/get/APCu', + 'filename' => 'apcu.tgz', + 'license' => [ + 'type' => 'file', + 'path' => 'LICENSE', + ], + ], + ]; + Config::$lib = [ + 'libaaa' => [ + 'source' => 'test1', + 'static-libs' => ['libaaa.a'], + 'lib-depends' => ['libbbb', 'libccc'], + 'lib-suggests' => ['libeee'], + ], + 'libbbb' => [ + 'source' => 'test1', + 'static-libs' => ['libbbb.a'], + 'lib-suggests' => ['libccc'], + ], + 'libccc' => [ + 'source' => 'test1', + 'static-libs' => ['libccc.a'], + ], + 'libeee' => [ + 'source' => 'test1', + 'static-libs' => ['libeee.a'], + 'lib-suggests' => ['libfff'], + ], + 'libfff' => [ + 'source' => 'test1', + 'static-libs' => ['libfff.a'], + ], + ]; + Config::$ext = [ + 'ext-a' => [ + 'type' => 'builtin', + 'lib-depends' => ['libaaa'], + 'ext-suggests' => ['ext-b'], + ], + 'ext-b' => [ + 'type' => 'builtin', + 'lib-depends' => ['libeee'], + ], + ]; + // test getExtLibsByDeps (notmal test with ext-depends and lib-depends) + + [$exts, $libs, $not_included] = DependencyUtil::getExtsAndLibs(['ext-a'], include_suggested_exts: true); + $this->assertContains('libbbb', $libs); + $this->assertContains('libccc', $libs); + $this->assertContains('ext-b', $exts); + $this->assertContains('ext-b', $not_included); + // test dep order + $this->assertIsInt($b = array_search('libbbb', $libs)); + $this->assertIsInt($c = array_search('libccc', $libs)); + $this->assertIsInt($a = array_search('libaaa', $libs)); + // libbbb, libaaa + $this->assertTrue($b < $a); + $this->assertTrue($c < $a); + $this->assertTrue($c < $b); + } + + public function testNotExistExtException(): void + { + $this->expectException(WrongUsageException::class); + DependencyUtil::getExtsAndLibs(['sdsd']); + } +} From 0954ddcc9681dd443a73dd20e710bd43945ea04a Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 16 Feb 2024 18:57:32 +0800 Subject: [PATCH 5/6] refactor some terminal outputs --- src/SPC/command/BuildCliCommand.php | 17 ++++++++++++++--- src/SPC/store/FileSystem.php | 12 ++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/SPC/command/BuildCliCommand.php b/src/SPC/command/BuildCliCommand.php index b45ef0b3..01d4e0e7 100644 --- a/src/SPC/command/BuildCliCommand.php +++ b/src/SPC/command/BuildCliCommand.php @@ -77,12 +77,23 @@ class BuildCliCommand extends BuildCommand if (!empty($this->input->getOption('with-hardcoded-ini'))) { $indent_texts['Hardcoded INI'] = $this->input->getOption('with-hardcoded-ini'); } - $this->printFormatInfo($indent_texts); + if ($this->input->getOption('disable-opcache-jit')) { + $indent_texts['Opcache JIT'] = 'disabled'; + } + try { + $ver = $builder->getPHPVersion(); + $indent_texts['PHP Version'] = $ver; + } catch (\Throwable) { + if (($ver = $builder->getPHPVersionFromArchive()) !== false) { + $indent_texts['PHP Version'] = $ver; + } + } if (!empty($not_included)) { - logger()->warning('Some extensions will be enabled due to dependencies: ' . implode(',', $not_included)); + $indent_texts['Extra Exts (' . count($not_included) . ')'] = implode(', ', $not_included); } - logger()->info('Build will start after 2s ...'); + $this->printFormatInfo($indent_texts); + logger()->notice('Build will start after 2s ...'); sleep(2); if ($this->input->getOption('with-clean')) { diff --git a/src/SPC/store/FileSystem.php b/src/SPC/store/FileSystem.php index 8da010e2..7e5411ab 100644 --- a/src/SPC/store/FileSystem.php +++ b/src/SPC/store/FileSystem.php @@ -227,8 +227,12 @@ class FileSystem { $dir = self::convertPath($dir); // 不是目录不扫,直接 false 处理 + if (!file_exists($dir)) { + logger()->debug('Scan dir failed, no such file or directory.'); + return false; + } if (!is_dir($dir)) { - logger()->warning('Scan dir failed, no such directory.'); + logger()->warning('Scan dir failed, not directory.'); return false; } logger()->debug('scanning directory ' . $dir); @@ -317,8 +321,12 @@ class FileSystem $dir = FileSystem::convertPath($dir); logger()->debug('Removing path recursively: "' . $dir . '"'); // 不是目录不扫,直接 false 处理 + if (!file_exists($dir)) { + logger()->debug('Scan dir failed, no such file or directory.'); + return false; + } if (!is_dir($dir)) { - logger()->warning('Scan dir failed, no such directory.'); + logger()->warning('Scan dir failed, not directory.'); return false; } logger()->debug('scanning directory ' . $dir); From ffa84f8b913378d318f1f8bbd8081413ff788016 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 16 Feb 2024 18:57:44 +0800 Subject: [PATCH 6/6] remove unused exts --- config/ext.json | 21 --------------------- src/globals/test-extensions.php | 6 +++--- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/config/ext.json b/config/ext.json index 3ee4cd32..c88b9bd3 100644 --- a/config/ext.json +++ b/config/ext.json @@ -93,13 +93,6 @@ "freetype" ] }, - "gettext": { - "type": "builtin", - "arg-type": "with", - "lib-depends": [ - "gettext" - ] - }, "glfw": { "type": "external", "arg-type": "custom", @@ -313,13 +306,6 @@ "type": "external", "source": "protobuf" }, - "pspell": { - "type": "builtin", - "arg-type": "with", - "lib-depends": [ - "aspell" - ] - }, "rar": { "type": "external", "source": "rar", @@ -371,13 +357,6 @@ "apcu" ] }, - "snmp": { - "type": "builtin", - "arg-type": "with", - "lib-depends": [ - "net-snmp" - ] - }, "soap": { "type": "builtin", "arg-type": "custom", diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 12843feb..90899a3f 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -13,8 +13,8 @@ declare(strict_types=1); // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'calendar,ctype,curl,dom,fileinfo,filter,gd,iconv,imagick,mbregex,mbstring,mysqli,mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,rar,redis,session,simplexml,soap,sockets,sqlite3,swoole,swoole-hook-mysql,tokenizer,xlswriter,xml,xmlreader,xmlwriter,zip,zlib', - 'Windows' => 'mbstring,openssl', + 'Linux', 'Darwin' => '', + 'Windows' => 'mbstring', }; // If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`). @@ -27,7 +27,7 @@ $with_libs = match (PHP_OS_FAMILY) { // You can use `common`, `bulk`, `minimal` or `none`. // note: combination is only available for *nix platform. Windows must use `none` combination $base_combination = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'none', + 'Linux', 'Darwin' => 'common', 'Windows' => 'none', };