mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-18 04:44:53 +08:00
refactor DependencyUtil, use for-libs and for-sources instead of by
This commit is contained in:
parent
1e898d271d
commit
939db75268
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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') {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 = [];
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user