refactor(php): 将平台检测和编译功能从CompilerBase迁移到Translator

- 从CompilerBase.php移除平台检测相关方法(detectPlatform, initializeNewArchitecture, setCppCompiler)
- 从CompilerBase.php移除代码格式化方法(formatCppCode)和save方法
- 从CompilerBase.php移除编译命令选项相关方法(getCompileCommandOptions等)
- 在Translator.php中新增平台检测方法(detectPlatform)
- 在Translator.php中新增代码格式化方法(formatCppCode)和save方法
- 在Translator.php中新增编译命令选项相关方法(getCompileCommandOptions等)
- 移除CompilerBase.php中未使用的SsaBuilder导入
- 在Translator.php中新增必要的平台和编译器工厂类导入
pull/1/head
韩天峰 3 months ago
parent 207bc6b48b
commit 79d4c28c91
  1. 176
      src/Php/CompilerBase.php
  2. 177
      src/Php/Translator.php

@ -9,7 +9,6 @@
namespace PhpAot\Php;
use League\CLImate\CLImate;
use PhpAot\Php\Analysis\SsaBuilder;
use PhpAot\Php\Backend\CompilerBackend;
use PhpAot\Php\Backend\CompilerFactory;
use PhpAot\Php\Context\FunctionContext;
@ -384,77 +383,6 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->climate = $climate;
}
/**
* 检测操作系统、编译器以及 Windows 平台的 PHP lib 文件
*/
protected function detectPlatform(): void
{
try {
$this->platform = PlatformFactory::create();
$this->cppCompiler = CompilerFactory::detectCompilerName($this->platform);
if ($this->platform instanceof Windows) {
$libInfo = $this->platform->detectPhpLibs($this->getPhpDir());
$this->windowsPhpEmbedLib = $libInfo['embed'];
$this->windowsPhpCoreLib = $libInfo['core'];
$this->isPhpZts = $libInfo['is_zts'];
$this->platform = new Windows(
phpLibs: [$this->windowsPhpCoreLib, $this->windowsPhpEmbedLib],
isZts: $this->isPhpZts,
phpSdkPath: $this->getPhpDir() . '\\SDK'
);
}
$this->compilerBackend = CompilerFactory::createByName($this->cppCompiler, $this->platform);
$this->climate->info(
"Initialized platform/backend: {$this->platform->getName()} + {$this->compilerBackend->getName()} ({$this->compilerBackend->getCompilerCommand()})"
);
} catch (\Throwable $e) {
$this->error($e->getMessage());
}
}
/**
* 设置 C++ 编译器(从配置文件读取)
*/
public function setCppCompiler(string $compiler): void
{
$this->cppCompiler = $compiler;
$this->climate->info("Using compiler from config: {$this->cppCompiler}");
// 重新初始化 Backend
$this->initializeNewArchitecture();
}
/**
* 初始化新的 Platform 和 Backend 抽象层
* 这是一个渐进式迁移,保持向后兼容
*/
protected function initializeNewArchitecture(): void
{
try {
$platform = $this->platform ?? PlatformFactory::create();
$this->platform = $platform;
// 自动检测平台和编译器
$result = CompilerFactory::autoDetect($this->cppCompiler, $platform);
$this->platform = $result['platform'];
$this->compilerBackend = $result['compiler'];
$this->climate->info(
"Initialized new architecture: {$this->platform->getName()} + {$this->compilerBackend->getName()}"
);
} catch (\Exception $e) {
// 如果初始化失败,回退到旧逻辑
$this->climate->warning(
"Failed to initialize new architecture: {$e->getMessage()}. Using legacy mode."
);
$this->platform = null;
$this->compilerBackend = null;
}
}
protected function getPhpxDir(): string
{
// 优先使用环境变量 PHPX_HOME
@ -537,12 +465,6 @@ class CompilerBase extends \PhpAot\Core\Translator
}
}
public function save(string $code, string $file): void
{
$this->writeFile($file, $code);
$this->formatCppCode($file);
}
public function isScalarInt(Expr $expr): bool
{
return $expr instanceof Node\Scalar\LNumber;
@ -2300,82 +2222,6 @@ class CompilerBase extends \PhpAot\Core\Translator
return $this->getPlatform()->getLibraryFlags($this->getLibraries());
}
protected function getCompileCommandOptions(): array
{
return [
'include_paths' => $this->getIncludePaths(),
'optimize' => $this->optimizeLevel,
'debug' => $this->debug,
'sanitize' => $this->sanitize,
'cpp_std' => $this->cxxStd,
'is_zts' => $this->isPhpZts,
'build_mode' => $this->buildMode,
'enable_profiler' => $this->enableProfiler,
'prof_output' => $this->targetName . '.prof',
'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [],
'cxxflags' => $this->cxxFlags,
];
}
protected function getCCompileCommandOptions(): array
{
return [
'include_paths' => $this->getIncludePaths(),
'optimize' => 0,
'debug' => $this->debug,
'is_zts' => $this->isPhpZts,
'suppressed_warnings' => ['4244', '4146'],
];
}
/**
* 获取原生源文件(汇编/ObjC 等)的编译选项,不含 C++ 特定标志.
*
* @param string $language 语言标识(assembler, objective-c, objective-c++)
*/
protected function getNativeCompileCommandOptions(string $language = ''): array
{
return [
'include_paths' => $this->getIncludePaths(),
'optimize' => $this->optimizeLevel,
'debug' => $this->debug,
'sanitize' => $this->sanitize,
'is_zts' => $this->isPhpZts,
'build_mode' => $this->buildMode,
'enable_profiler' => $this->enableProfiler,
'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [],
];
}
protected function getLinkCommandOptions(): array
{
$ldflags = $this->ldflags;
if ($this->enableProfiler) {
$ldflags .= ' -lprofiler';
}
$options = [
'library_paths' => $this->getLibraryPaths(),
'libraries' => $this->getLibraries(),
'ldflags' => $ldflags,
'debug' => $this->debug,
'no_console' => $this->noConsole,
'build_mode' => $this->buildMode,
'sanitize' => $this->sanitize,
];
$rpaths = $this->getPlatform()->getDefaultRpaths(
$this->getPhpxDir(),
$this->getPhpDir()
);
if (!empty($rpaths)) {
$options['rpath'] = $rpaths;
}
return $options;
}
protected function getTargetFileName(): string
{
$targetFile = $this->targetName;
@ -2388,16 +2234,6 @@ class CompilerBase extends \PhpAot\Core\Translator
return $targetFile;
}
protected function buildLinkCommand(array $objectFiles, string $targetFile): string
{
return $this->getCompilerBackend()->buildLinkCommand(
$objectFiles,
$targetFile,
$this->getLinkCommandOptions()
);
}
protected function parseFor(Node\Stmt\For_ $v): string
{
$init = $v->init;
@ -3790,18 +3626,6 @@ class CompilerBase extends \PhpAot\Core\Translator
return $code;
}
protected function formatCppCode(string $file): void
{
if (!$this->formatCode) {
return;
}
$cmd = 'cd ' . $this->rootPath . ' && clang-format -i ' . $file;
$this->climate->info('format: ' . $this->getRelativePath($file));
$this->climate->comment($cmd);
shell_exec($cmd);
}
/**
* 为了兼容已有代码,默认不使用原生类型,而是将整数和浮点数作为 php 变量处理
* 原生 int/float/bool 类型,是不支持自动转换的,例如如果 int 计算超过最大值后,会自动转为 float,除法若不能除尽,则会转为 float

@ -10,6 +10,7 @@ namespace PhpAot\Php;
use MJS\TopSort\Implementations\StringSort;
use PhpAot\Php\Analysis\SsaBuilder;
use PhpAot\Php\Backend\CompilerFactory;
use PhpAot\Php\Entity\ClassDef;
use PhpAot\Php\Entity\ClassLikeDef;
use PhpAot\Php\Entity\ConstantDef;
@ -22,6 +23,8 @@ use PhpAot\Php\Exception\Skip;
use PhpAot\Php\Exception\SyntaxError;
use PhpAot\Php\Exception\Unsupported;
use PhpAot\Php\Generator\ResourceFileGenerator;
use PhpAot\Php\Platform\PlatformFactory;
use PhpAot\Php\Platform\Windows;
use PhpParser\Modifiers;
use PhpParser\Node;
use PhpParser\Node\Stmt\Foreach_;
@ -80,6 +83,37 @@ class Translator extends Preprocessor
$this->detectPlatform();
}
/**
* 检测操作系统、编译器以及 Windows 平台的 PHP lib 文件
*/
protected function detectPlatform(): void
{
try {
$this->platform = PlatformFactory::create();
$this->cppCompiler = CompilerFactory::detectCompilerName($this->platform);
if ($this->platform instanceof Windows) {
$libInfo = $this->platform->detectPhpLibs($this->getPhpDir());
$this->windowsPhpEmbedLib = $libInfo['embed'];
$this->windowsPhpCoreLib = $libInfo['core'];
$this->isPhpZts = $libInfo['is_zts'];
$this->platform = new Windows(
phpLibs: [$this->windowsPhpCoreLib, $this->windowsPhpEmbedLib],
isZts: $this->isPhpZts,
phpSdkPath: $this->getPhpDir() . '\\SDK'
);
}
$this->compilerBackend = CompilerFactory::createByName($this->cppCompiler, $this->platform);
$this->climate->info(
"Initialized platform/backend: {$this->platform->getName()} + {$this->compilerBackend->getName()} ({$this->compilerBackend->getCompilerCommand()})"
);
} catch (\Throwable $e) {
$this->error($e->getMessage());
}
}
public function parseArgv(array $argv)
{
$path = null;
@ -209,6 +243,24 @@ class Translator extends Preprocessor
$this->climate->bold()->out(self::APP_NAME . ' v' . self::VERSION);
}
protected function formatCppCode(string $file): void
{
if (!$this->formatCode) {
return;
}
$cmd = 'cd ' . $this->rootPath . ' && clang-format -i ' . $file;
$this->climate->info('format: ' . $this->getRelativePath($file));
$this->climate->comment($cmd);
shell_exec($cmd);
}
public function save(string $code, string $file): void
{
$this->writeFile($file, $code);
$this->formatCppCode($file);
}
public function convertFile(string $file): string
{
$file = realpath($file);
@ -234,6 +286,46 @@ class Translator extends Preprocessor
return implode(', ', $this->getRegisterClassFunctionCeList($classDef));
}
/**
* 初始化新的 Platform 和 Backend 抽象层
* 这是一个渐进式迁移,保持向后兼容
*/
protected function initializeNewArchitecture(): void
{
try {
$platform = $this->platform ?? PlatformFactory::create();
$this->platform = $platform;
// 自动检测平台和编译器
$result = CompilerFactory::autoDetect($this->cppCompiler, $platform);
$this->platform = $result['platform'];
$this->compilerBackend = $result['compiler'];
$this->climate->info(
"Initialized new architecture: {$this->platform->getName()} + {$this->compilerBackend->getName()}"
);
} catch (\Exception $e) {
// 如果初始化失败,回退到旧逻辑
$this->climate->warning(
"Failed to initialize new architecture: {$e->getMessage()}. Using legacy mode."
);
$this->platform = null;
$this->compilerBackend = null;
}
}
/**
* 设置 C++ 编译器(从配置文件读取)
*/
public function setCppCompiler(string $compiler): void
{
$this->cppCompiler = $compiler;
$this->climate->info("Using compiler from config: {$this->cppCompiler}");
// 重新初始化 Backend
$this->initializeNewArchitecture();
}
public function setBuildMode(string $mode): void
{
$this->buildMode = $mode;
@ -1114,6 +1206,91 @@ CODE;
}
}
protected function getCompileCommandOptions(): array
{
return [
'include_paths' => $this->getIncludePaths(),
'optimize' => $this->optimizeLevel,
'debug' => $this->debug,
'sanitize' => $this->sanitize,
'cpp_std' => $this->cxxStd,
'is_zts' => $this->isPhpZts,
'build_mode' => $this->buildMode,
'enable_profiler' => $this->enableProfiler,
'prof_output' => $this->targetName . '.prof',
'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [],
'cxxflags' => $this->cxxFlags,
];
}
protected function getCCompileCommandOptions(): array
{
return [
'include_paths' => $this->getIncludePaths(),
'optimize' => 0,
'debug' => $this->debug,
'is_zts' => $this->isPhpZts,
'suppressed_warnings' => ['4244', '4146'],
];
}
/**
* 获取原生源文件(汇编/ObjC 等)的编译选项,不含 C++ 特定标志.
*
* @param string $language 语言标识(assembler, objective-c, objective-c++)
*/
protected function getNativeCompileCommandOptions(string $language = ''): array
{
return [
'include_paths' => $this->getIncludePaths(),
'optimize' => $this->optimizeLevel,
'debug' => $this->debug,
'sanitize' => $this->sanitize,
'is_zts' => $this->isPhpZts,
'build_mode' => $this->buildMode,
'enable_profiler' => $this->enableProfiler,
'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [],
];
}
protected function getLinkCommandOptions(): array
{
$ldflags = $this->ldflags;
if ($this->enableProfiler) {
$ldflags .= ' -lprofiler';
}
$options = [
'library_paths' => $this->getLibraryPaths(),
'libraries' => $this->getLibraries(),
'ldflags' => $ldflags,
'debug' => $this->debug,
'no_console' => $this->noConsole,
'build_mode' => $this->buildMode,
'sanitize' => $this->sanitize,
];
$rpaths = $this->getPlatform()->getDefaultRpaths(
$this->getPhpxDir(),
$this->getPhpDir()
);
if (!empty($rpaths)) {
$options['rpath'] = $rpaths;
}
return $options;
}
protected function buildLinkCommand(array $objectFiles, string $targetFile): string
{
return $this->getCompilerBackend()->buildLinkCommand(
$objectFiles,
$targetFile,
$this->getLinkCommandOptions()
);
}
public function build(array $objectFiles): string
{
$targetFile = $this->getTargetFileName();

Loading…
Cancel
Save