TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
12 KiB
12 KiB
完全解耦重构方案
目标
将 CompilerBase.php 和 Translator.php 中所有平台相关和编译器相关的代码完全迁移到 Platform 和 Backend 类中,实现真正的解耦。
重构原则
- 单一职责:每个类只负责一件事
- 依赖倒置:通过接口调用,不直接依赖具体实现
- 开闭原则:对扩展开放,对修改关闭
- 渐进式迁移:保持向后兼容,逐步替换
架构设计
┌─────────────────────────────────────┐
│ CompilerBase (协调者) │
│ - orchestrates compilation flow │
│ - delegates to Platform/Backend │
└──────────┬──────────────┬───────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Platform │ │ Backend │
│ (平台抽象层) │ │ (编译器抽象层) │
│ │ │ │
│ - Windows │ │ - Msvc │
│ - Linux │ │ - Gcc │
│ - Macos │ │ - Clang │
└─────────────────┘ └──────────────────┘
迁移清单
Phase 1: Platform 层增强(已完成 50%)
✅ Windows Platform
buildPhpSdkIncludePaths()- 构建 PHP SDK 包含路径buildPhpSdkLibPaths()- 构建 PHP SDK 库路径detectPhpLibs()- 检测 PHP lib 文件getCompilerFlags()- 获取编译器标志getLinkerFlags()- 获取链接器标志
⏳ Linux Platform
getRpathOptions()- RPATH 选项getPicFlag()- PIC 标志getSharedLinkFlag()- 共享库链接标志
⏳ macOS Platform
getRpathOptions()- RPATH 选项getCurrentInstallNameOption()- install_name 选项getSharedLinkFlag()- 动态库链接标志
Phase 2: Backend 层增强(已完成 60%)
✅ MSVC Backend
buildFullCompileOptions()- 完整编译选项buildFullLinkOptions()- 完整链接选项addSanitizerOptions()- Sanitizer 选项addWarningOptions()- 警告选项
⏳ GCC Backend
buildFullCompileOptions()buildFullLinkOptions()
⏳ Clang Backend
buildFullCompileOptions()buildFullLinkOptions()
Phase 3: CompilerBase 解耦(待开始)
需要迁移的方法:
高优先级(核心逻辑)
parseIncludes()→$platform->getIncludeFlags()+$backend->buildIncludeOptions()parseLdflags()→$platform->getLibraryPathFlags()parseLibs()→$platform->getLibraryFlags()addCompilationOption()→$backend->buildFullCompileOptions()compileFile()→$backend->compileFile()linkObjects()→$backend->linkObjects()
中优先级(平台特定)
parseWindowsIncludes()→ 删除,使用 PlatformparseWindowsLdflags()→ 删除,使用 PlatformparseWindowsLibs()→ 删除,使用 PlatformdetectWindowsPhpLibs()→ 删除,使用Windows::detectPhpLibs()addWindowsCompilationOption()→ 删除,使用 MSVC BackendaddWindowsClangCompilationOption()→ 删除,使用 Clang BackendaddUnixCompilationOption()→ 删除,使用 GCC Backend
低优先级(辅助方法)
isWindows()→$platform instanceof WindowsisMacos()→$platform instanceof Macos- 其他平台检测方法
Phase 4: Translator 解耦(待开始)
检查 Translator.php 中直接使用编译器命令的地方,改为通过 Backend 调用。
实施步骤
Step 1: 完善 Platform 类(1-2天)
为每个 Platform 类添加缺失的方法:
// Windows.php
public function getCompilerFlags(array $options): string
{
// 返回 MSVC 或 Clang 的编译器标志
}
public function getLinkerFlags(array $options): string
{
// 返回链接器标志
}
Step 2: 完善 Backend 类(2-3天)
为每个 Backend 类添加完整的方法实现:
// Msvc.php
public function buildFullCompileOptions(array $options): string
{
// 包括所有 MSVC 特定的编译选项
// - 宏定义
// - 优化级别
// - 警告设置
// - C++ 标准
// - Sanitizer
// - etc.
}
Step 3: 创建适配器层(1天)
在 CompilerBase 中创建适配器方法,桥接旧代码和新架构:
// CompilerBase.php
protected function parseIncludesNew(): string
{
if ($this->platform === null) {
return $this->parseIncludesLegacy();
}
$includePaths = $this->getIncludePaths();
return $this->platform->getIncludeFlags($includePaths);
}
protected function parseIncludesLegacy(): string
{
// 旧的实现,保持兼容
}
protected function parseIncludes(): string
{
return $this->parseIncludesNew();
}
Step 4: 逐个替换方法(3-5天)
按照优先级逐个替换方法:
// 替换前
protected function addWindowsCompilationOption(string &$cmd, bool $link): void
{
// 100+ 行代码
}
// 替换后
protected function addCompilationOption(string &$cmd, bool $link): void
{
if ($this->compilerBackend === null) {
$this->addCompilationOptionLegacy($cmd, $link);
return;
}
if (!$link) {
$cmd .= $this->compilerBackend->buildFullCompileOptions([
'optimize' => $this->optimizeLevel,
'debug_info' => $this->debugInfo,
'sanitize' => $this->sanitize,
'cpp_std' => $this->cxxStd,
]);
} else {
$cmd .= $this->compilerBackend->buildFullLinkOptions([
'debug_info' => $this->debugInfo,
'no_console' => $this->noConsole,
'shared' => ($this->buildMode === 'ext'),
]);
}
}
Step 5: 移除旧代码(1-2天)
当所有方法都迁移完成后,删除旧的实现:
// 删除这些方法
- protected function parseWindowsIncludes()
- protected function parseWindowsLdflags()
- protected function parseWindowsLibs()
- protected function detectWindowsPhpLibs()
- protected function addWindowsCompilationOption()
- protected function addWindowsClangCompilationOption()
- protected function addUnixCompilationOption()
Step 6: 测试和验证(2-3天)
- 单元测试
- 集成测试
- 回归测试
- 性能测试
代码示例
示例 1:Platform 处理包含路径
之前(CompilerBase.php):
protected function parseWindowsIncludes(): string
{
$list = [
$this->getPhpxDir() . '\include',
$this->getPhpDir() . '\SDK\include',
// ... 更多路径
];
$out = '';
foreach ($list as $li) {
$normalizedPath = str_replace('/', '\\', $li);
$out .= '/I "' . $normalizedPath . '" ';
}
return $out;
}
之后(使用 Platform):
protected function parseIncludes(): string
{
$includePaths = [
$this->getPhpxDir() . '/include',
...$this->platform->buildPhpSdkIncludePaths($this->getPhpDir()),
];
return $this->platform->getIncludeFlags($includePaths);
}
示例 2:Backend 处理编译选项
之前(CompilerBase.php):
protected function addWindowsCompilationOption(string &$cmd, bool $link): void
{
if (!$link) {
$cmd .= ' /DZEND_WIN32';
$cmd .= ' /DPHP_WIN32';
$cmd .= ' /DZEND_DEBUG=0';
if ($this->isPhpZts) {
$cmd .= ' /DZTS';
}
// ... 100+ 行代码
}
}
之后(使用 Backend):
protected function addCompilationOption(string &$cmd, bool $link): void
{
if ($this->compilerBackend === null) {
// 回退到旧逻辑
return;
}
if (!$link) {
$cmd .= $this->compilerBackend->buildFullCompileOptions([
'optimize' => $this->optimizeLevel,
'debug_info' => $this->debugInfo,
'sanitize' => $this->sanitize,
'cpp_std' => $this->cxxStd,
'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS,
]);
} else {
$cmd .= $this->compilerBackend->buildFullLinkOptions([
'debug_info' => $this->debugInfo,
'no_console' => $this->noConsole,
'shared' => ($this->buildMode === 'ext'),
]);
}
}
示例 3:检测 PHP Libs
之前(CompilerBase.php):
protected function detectWindowsPhpLibs(): void
{
$phpDirs = [
$this->getPhpDir() . '\SDK\lib',
$this->getPhpDir() . '\lib',
];
// ... 50+ 行检测逻辑
$this->windowsPhpEmbedLib = $embedLibPath;
$this->windowsPhpCoreLib = $coreLibPath;
$this->isPhpZts = $isZts;
}
之后(使用 Platform):
protected function detectPlatform(): void
{
$this->isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
if ($this->isWindows) {
// 使用 Windows Platform 检测
/** @var Windows $platform */
$platform = PlatformFactory::create();
$libInfo = $platform->detectPhpLibs($this->getPhpDir());
$this->windowsPhpEmbedLib = $libInfo['embed'];
$this->windowsPhpCoreLib = $libInfo['core'];
$this->isPhpZts = $libInfo['is_zts'];
// 重新创建带信息的 Platform 实例
$this->platform = new Windows(
phpLibs: [$libInfo['embed'], $libInfo['core']],
isZts: $libInfo['is_zts']
);
$this->compilerBackend = CompilerFactory::create($this->platform);
}
}
预期收益
代码质量
- ✅ CompilerBase.php 减少 ~500 行代码
- ✅ 职责更清晰
- ✅ 更易维护
- ✅ 更易测试
可扩展性
- ✅ 添加新平台只需创建新的 Platform 类
- ✅ 添加新编译器只需创建新的 Backend 类
- ✅ 无需修改 CompilerBase
可测试性
- ✅ 每个类可以独立测试
- ✅ 易于 Mock
- ✅ 更高的测试覆盖率
风险评估
低风险
- Platform 和 Backend 层已经存在并工作
- 有完整的回退机制
- 渐进式迁移
中风险
- 需要充分测试确保功能一致
- 可能需要调整一些边缘情况
缓解措施
- 保留旧代码作为回退
- 充分的单元测试
- 集成测试覆盖所有场景
- 灰度发布,逐步切换
时间估算
| 阶段 | 工作量 | 说明 |
|---|---|---|
| Phase 1: Platform 增强 | 1-2 天 | 补充缺失方法 |
| Phase 2: Backend 增强 | 2-3 天 | 补充缺失方法 |
| Phase 3: 创建适配器 | 1 天 | 桥接新旧代码 |
| Phase 4: 逐个替换 | 3-5 天 | 迁移核心逻辑 |
| Phase 5: 移除旧代码 | 1-2 天 | 清理冗余代码 |
| Phase 6: 测试验证 | 2-3 天 | 全面测试 |
| 总计 | 10-16 天 | 约 2-3 周 |
下一步行动
-
立即开始:
- 完善 Linux 和 macOS Platform 类
- 完善 GCC 和 Clang Backend 类
-
本周内:
- 创建适配器层
- 开始替换高优先级方法
-
下周:
- 完成所有方法迁移
- 编写测试
- 性能验证
-
下下周:
- 移除旧代码
- 最终测试
- 发布新版本
总结
这是一个系统性的重构,目标是:
- 🎯 完全解耦平台和编译器逻辑
- 🎯 提高代码质量和可维护性
- 🎯 保持向后兼容
- 🎯 降低未来扩展成本
通过渐进式迁移和充分的测试,可以安全地完成这次重构!