2023-03-18 17:32:21 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
|
|
namespace SPC\command;
|
|
|
|
|
|
|
|
|
|
|
|
use SPC\builder\BuilderProvider;
|
|
|
|
|
|
use SPC\exception\ExceptionHandler;
|
2023-03-29 21:39:36 +08:00
|
|
|
|
use SPC\exception\WrongUsageException;
|
2023-03-18 17:32:21 +08:00
|
|
|
|
use SPC\util\DependencyUtil;
|
2023-04-15 18:46:46 +08:00
|
|
|
|
use SPC\util\LicenseDumper;
|
2023-03-18 17:32:21 +08:00
|
|
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
|
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
|
|
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
|
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
|
|
|
|
|
|
|
|
/** @noinspection PhpUnused */
|
|
|
|
|
|
class BuildCliCommand extends BuildCommand
|
|
|
|
|
|
{
|
|
|
|
|
|
protected static $defaultName = 'build';
|
|
|
|
|
|
|
|
|
|
|
|
public function configure()
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->setDescription('Build CLI binary');
|
|
|
|
|
|
$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 only');
|
|
|
|
|
|
$this->addOption('build-all', null, null, 'build both cli and micro');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function execute(InputInterface $input, OutputInterface $output): int
|
|
|
|
|
|
{
|
|
|
|
|
|
// 从参数中获取要编译的 libraries,并转换为数组
|
|
|
|
|
|
$libraries = array_map('trim', array_filter(explode(',', $input->getOption('with-libs'))));
|
|
|
|
|
|
// 从参数中获取要编译的 extensions,并转换为数组
|
|
|
|
|
|
$extensions = array_map('trim', array_filter(explode(',', $input->getArgument('extensions'))));
|
|
|
|
|
|
|
|
|
|
|
|
define('BUILD_ALL_STATIC', true);
|
|
|
|
|
|
|
|
|
|
|
|
if ($input->getOption('build-all')) {
|
|
|
|
|
|
$rule = BUILD_MICRO_BOTH;
|
|
|
|
|
|
logger()->info('Builder will build php-cli and phpmicro SAPI');
|
|
|
|
|
|
} elseif ($input->getOption('build-micro')) {
|
|
|
|
|
|
$rule = BUILD_MICRO_ONLY;
|
|
|
|
|
|
logger()->info('Builder will build phpmicro SAPI');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$rule = BUILD_MICRO_NONE;
|
|
|
|
|
|
logger()->info('Builder will build php-cli SAPI');
|
|
|
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 构建对象
|
|
|
|
|
|
$builder = BuilderProvider::makeBuilderByInput($input);
|
|
|
|
|
|
// 根据提供的扩展列表获取依赖库列表并编译
|
|
|
|
|
|
[$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries);
|
|
|
|
|
|
|
|
|
|
|
|
logger()->info('Enabled extensions: ' . implode(', ', $extensions));
|
|
|
|
|
|
logger()->info('Required libraries: ' . implode(', ', $libraries));
|
|
|
|
|
|
if (!empty($not_included)) {
|
|
|
|
|
|
logger()->warning('some extensions will be enabled due to dependencies: ' . implode(',', $not_included));
|
|
|
|
|
|
}
|
|
|
|
|
|
sleep(2);
|
|
|
|
|
|
// 编译和检查库是否完整
|
|
|
|
|
|
$builder->buildLibs($libraries);
|
|
|
|
|
|
// 执行扩展检测
|
|
|
|
|
|
$builder->proveExts($extensions);
|
|
|
|
|
|
// 构建
|
2023-03-26 22:27:51 +08:00
|
|
|
|
$builder->buildPHP($rule, $input->getOption('bloat'));
|
2023-03-18 17:32:21 +08:00
|
|
|
|
// 统计时间
|
|
|
|
|
|
$time = round(microtime(true) - START_TIME, 3);
|
|
|
|
|
|
logger()->info('Build complete, used ' . $time . ' s !');
|
|
|
|
|
|
if ($rule !== BUILD_MICRO_ONLY) {
|
2023-03-26 22:27:51 +08:00
|
|
|
|
logger()->info('Static php binary path: ' . BUILD_ROOT_PATH . '/bin/php');
|
2023-03-18 17:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
if ($rule !== BUILD_MICRO_NONE) {
|
2023-03-26 22:27:51 +08:00
|
|
|
|
logger()->info('phpmicro binary path: ' . BUILD_ROOT_PATH . '/bin/micro.sfx');
|
2023-03-18 17:32:21 +08:00
|
|
|
|
}
|
2023-04-15 18:46:46 +08:00
|
|
|
|
// 导出相关元数据
|
|
|
|
|
|
file_put_contents(BUILD_ROOT_PATH . '/build-extensions.json', json_encode($extensions, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
|
|
|
|
|
file_put_contents(BUILD_ROOT_PATH . '/build-libraries.json', json_encode($libraries, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
|
|
|
|
|
// 导出 LICENSE
|
|
|
|
|
|
$dumper = new LicenseDumper();
|
|
|
|
|
|
$dumper->addExts($extensions)->addLibs($libraries)->addSources(['php-src'])->dump(BUILD_ROOT_PATH . '/license');
|
|
|
|
|
|
logger()->info('License path: ' . BUILD_ROOT_PATH . '/license/');
|
2023-03-18 17:32:21 +08:00
|
|
|
|
return 0;
|
2023-03-29 21:39:36 +08:00
|
|
|
|
} catch (WrongUsageException $e) {
|
|
|
|
|
|
logger()->critical($e->getMessage());
|
|
|
|
|
|
return 1;
|
2023-03-18 17:32:21 +08:00
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
|
if ($input->getOption('debug')) {
|
|
|
|
|
|
ExceptionHandler::getInstance()->handle($e);
|
|
|
|
|
|
} else {
|
2023-03-21 00:21:17 +08:00
|
|
|
|
logger()->critical('Build failed with ' . get_class($e) . ': ' . $e->getMessage());
|
|
|
|
|
|
logger()->critical('Please check with --debug option to see more details.');
|
2023-03-18 17:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|