diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 7b120f6a..45b356a4 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.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 diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 248a844a..8024918c 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -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();