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-all', null, null, 'build cli, micro, fpm'); } public function handle(): int { // 从参数中获取要编译的 libraries,并转换为数组 $libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs')))); // 从参数中获取要编译的 extensions,并转换为数组 $extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions')))); define('BUILD_ALL_STATIC', true); $rule = BUILD_TARGET_NONE; $rule = $rule | ($this->getOption('build-cli') ? BUILD_TARGET_CLI : BUILD_TARGET_NONE); $rule = $rule | ($this->getOption('build-micro') ? BUILD_TARGET_MICRO : BUILD_TARGET_NONE); $rule = $rule | ($this->getOption('build-fpm') ? BUILD_TARGET_FPM : BUILD_TARGET_NONE); $rule = $rule | ($this->getOption('build-all') ? BUILD_TARGET_ALL : BUILD_TARGET_NONE); if ($rule === BUILD_TARGET_NONE) { $this->output->writeln('Please add at least one build target!'); $this->output->writeln("\t--build-cli\tBuild php-cli SAPI"); $this->output->writeln("\t--build-micro\tBuild phpmicro SAPI"); $this->output->writeln("\t--build-fpm\tBuild php-fpm SAPI"); $this->output->writeln("\t--build-all\tBuild all SAPI: cli, micro, fpm"); return 1; } try { // 构建对象 $builder = BuilderProvider::makeBuilderByInput($this->input); // 根据提供的扩展列表获取依赖库列表并编译 [$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries); /* @phpstan-ignore-next-line */ logger()->info('Build target: ' . ConsoleColor::yellow($builder->getBuildTypeName($rule))); /* @phpstan-ignore-next-line */ logger()->info('Enabled extensions: ' . ConsoleColor::yellow(implode(', ', $extensions))); /* @phpstan-ignore-next-line */ logger()->info('Required libraries: ' . ConsoleColor::yellow(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); // 构建 $builder->buildPHP($rule, $this->getOption('bloat')); // 统计时间 $time = round(microtime(true) - START_TIME, 3); logger()->info('Build complete, used ' . $time . ' s !'); if (($rule & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { logger()->info('Static php binary path: ' . BUILD_ROOT_PATH . '/bin/php'); } if (($rule & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) { logger()->info('phpmicro binary path: ' . BUILD_ROOT_PATH . '/bin/micro.sfx'); } if (($rule & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) { logger()->info('Static php-fpm binary path: ' . BUILD_ROOT_PATH . '/bin/php-fpm'); } // 导出相关元数据 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/'); return 0; } catch (WrongUsageException $e) { logger()->critical($e->getMessage()); return 1; } catch (\Throwable $e) { if ($this->getOption('debug')) { ExceptionHandler::getInstance()->handle($e); } else { logger()->critical('Build failed with ' . get_class($e) . ': ' . $e->getMessage()); logger()->critical('Please check with --debug option to see more details.'); } return 1; } } }