feat(backend): 添加编译器和平台抽象层实现

- 实现 CompilerBackend 抽象基类定义编译器接口
- 添加 Clang、GCC、MSVC 编译器后端具体实现
- 创建 PlatformBase 抽象基类定义平台接口
- 添加 Windows、Linux、macOS 平台具体实现
- 实现 CompilerFactory 工厂类自动创建编译器
- 实现 PlatformFactory 工厂类自动检测平台
- 提供跨平台路径处理和命令行参数生成
- 添加完整的使用示例和架构说明文档
pull/1/head
韩天峰 4 months ago
parent 0793a647ee
commit 95827cfb73
  1. 200
      src/Php/Backend/Clang.php
  2. 109
      src/Php/Backend/CompilerBackend.php
  3. 68
      src/Php/Backend/CompilerFactory.php
  4. 143
      src/Php/Backend/Gcc.php
  5. 156
      src/Php/Backend/Msvc.php
  6. 193
      src/Php/Backend/README.md
  7. 78
      src/Php/Backend/example_usage.php
  8. 121
      src/Php/Platform/Linux.php
  9. 129
      src/Php/Platform/Macos.php
  10. 71
      src/Php/Platform/PlatformBase.php
  11. 58
      src/Php/Platform/PlatformFactory.php
  12. 145
      src/Php/Platform/Windows.php

@ -0,0 +1,200 @@
<?php
namespace PhpAot\Php\Backend;
use PhpAot\Php\Platform\PlatformBase;
/**
* Clang 编译器后端实现
*/
class Clang extends CompilerBackend
{
public function getName(): string
{
return 'Clang';
}
public function getCompilerCommand(): string
{
return 'clang++';
}
public function getLinkerCommand(): string
{
// Windows 下使用 MSVC 链接器,其他平台使用 clang++
if ($this->platform instanceof \PhpAot\Php\Platform\Windows) {
return 'link';
}
return 'clang++';
}
public function compileFile(
string $sourceFile,
string $outputFile,
array $includePaths = [],
array $defines = [],
array $flags = []
): string {
$cmd = $this->getCompilerCommand();
// Windows 下需要 MSVC 兼容模式
if ($this->platform instanceof \PhpAot\Php\Platform\Windows) {
$cmd .= ' -fms-compatibility';
$cmd .= ' -fms-compatibility-version=19.40';
$cmd .= ' -fdelayed-template-parsing';
$cmd .= ' -fms-extensions';
}
$cmd .= ' -c ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
// 添加包含路径
if (!empty($includePaths)) {
$cmd .= ' ' . $this->formatIncludePaths($includePaths);
}
// 添加宏定义
foreach ($defines as $define) {
$cmd .= ' -D' . $define;
}
// 添加额外标志
if (!empty($flags)) {
$cmd .= ' ' . implode(' ', $flags);
}
return $cmd;
}
public function linkObjects(
array $objectFiles,
string $outputFile,
array $libraryPaths = [],
array $libraries = [],
array $flags = []
): string {
$cmd = $this->getLinkerCommand();
// 添加目标文件
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles));
// 输出文件
if ($this->platform instanceof \PhpAot\Php\Platform\Windows) {
$cmd .= ' /OUT:' . escapeshellarg($outputFile);
} else {
$cmd .= ' -o ' . escapeshellarg($outputFile);
}
// 添加库路径
if (!empty($libraryPaths)) {
$cmd .= ' ' . $this->formatLibraryPaths($libraryPaths);
}
// 添加库文件
if (!empty($libraries)) {
$cmd .= ' ' . $this->formatLibraries($libraries);
}
// 添加额外标志
if (!empty($flags)) {
$cmd .= ' ' . implode(' ', $flags);
}
return $cmd;
}
public function buildCompileCommand(string $sourceFile, string $outputFile, array $options = []): string
{
$cmd = $this->getCompilerCommand();
// Windows 下需要 MSVC 兼容模式
if ($this->platform instanceof \PhpAot\Php\Platform\Windows) {
$cmd .= ' -fms-compatibility';
$cmd .= ' -fms-compatibility-version=19.40';
$cmd .= ' -fdelayed-template-parsing';
$cmd .= ' -fms-extensions';
}
$cmd .= ' -c';
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
// 优化级别
$optimizeLevel = $options['optimize'] ?? 2;
// 调试模式
if (!empty($options['debug'])) {
$cmd .= ' -O0 -g';
} else {
$cmd .= ' -O' . $optimizeLevel;
}
// 警告级别
$cmd .= ' -Wall';
// C++ 标准
$cppStd = $options['cpp_std'] ?? 'c++17';
$cmd .= ' -std=' . $cppStd;
// Sanitizer 支持
if (!empty($options['sanitize'])) {
$cmd .= ' -fsanitize=' . $options['sanitize'];
}
// PIC(位置无关代码)
if (!empty($options['pic'])) {
$cmd .= ' -fPIC';
}
return $cmd;
}
public function buildLinkCommand(array $objectFiles, string $outputFile, array $options = []): string
{
$cmd = $this->getLinkerCommand();
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles));
// Windows 使用 MSVC 链接器语法
if ($this->platform instanceof \PhpAot\Php\Platform\Windows) {
$cmd .= ' /OUT:' . escapeshellarg($outputFile);
// 调试信息
if (!empty($options['debug'])) {
$cmd .= ' /DEBUG';
}
// Windows 子系统
if (!empty($options['no_console'])) {
$cmd .= ' ' . $this->platform->getSubsystemOptions(true);
}
// CRT 配置
$cmd .= ' ' . $this->platform->getCrtConfig();
} else {
// Unix/Linux/macOS 使用 GCC 风格语法
$cmd .= ' -o ' . escapeshellarg($outputFile);
// 共享库
if (!empty($options['shared'])) {
$cmd .= ' ' . $this->platform->getSharedLinkFlag();
// macOS 需要 install_name
if ($this->platform instanceof \PhpAot\Php\Platform\Macos && !empty($options['install_name'])) {
$cmd .= ' ' . $this->platform->getCurrentInstallNameOption($options['install_name']);
}
}
// RPATH(运行时库搜索路径)
if (!empty($options['rpath'])) {
$cmd .= ' ' . $this->platform->getRpathOptions($options['rpath']);
}
// Sanitizer 链接选项
if (!empty($options['sanitize'])) {
$cmd .= ' -fsanitize=' . $options['sanitize'];
}
}
return $cmd;
}
}

@ -0,0 +1,109 @@
<?php
namespace PhpAot\Php\Backend;
use PhpAot\Php\Platform\PlatformBase;
/**
* 编译器后端抽象基类
* 定义所有编译器必须实现的接口
*/
abstract class CompilerBackend
{
/**
* 平台实例
*/
protected PlatformBase $platform;
public function __construct(PlatformBase $platform)
{
$this->platform = $platform;
}
/**
* 获取编译器名称
*/
abstract public function getName(): string;
/**
* 获取编译器命令
*/
abstract public function getCompilerCommand(): string;
/**
* 获取链接器命令
*/
abstract public function getLinkerCommand(): string;
/**
* 编译单个文件
*/
abstract public function compileFile(
string $sourceFile,
string $outputFile,
array $includePaths = [],
array $defines = [],
array $flags = []
): string;
/**
* 链接目标文件
*/
abstract public function linkObjects(
array $objectFiles,
string $outputFile,
array $libraryPaths = [],
array $libraries = [],
array $flags = []
): string;
/**
* 构建完整的编译命令
*/
abstract public function buildCompileCommand(
string $sourceFile,
string $outputFile,
array $options = []
): string;
/**
* 构建完整的链接命令
*/
abstract public function buildLinkCommand(
array $objectFiles,
string $outputFile,
array $options = []
): string;
/**
* 获取平台实例
*/
public function getPlatform(): PlatformBase
{
return $this->platform;
}
/**
* 格式化包含路径
*/
protected function formatIncludePaths(array $includePaths): string
{
return $this->platform->getIncludeFlags($includePaths);
}
/**
* 格式化库路径
*/
protected function formatLibraryPaths(array $libraryPaths): string
{
return $this->platform->getLibraryPathFlags($libraryPaths);
}
/**
* 格式化库文件
*/
protected function formatLibraries(array $libraries): string
{
return $this->platform->getLibraryFlags($libraries);
}
}

@ -0,0 +1,68 @@
<?php
namespace PhpAot\Php\Backend;
use PhpAot\Php\Platform\PlatformBase;
use PhpAot\Php\Platform\Windows;
use PhpAot\Php\Platform\Linux;
use PhpAot\Php\Platform\Macos;
/**
* 编译器工厂类
* 根据平台自动创建合适的编译器后端
*/
class CompilerFactory
{
/**
* 创建默认编译器后端
*/
public static function create(PlatformBase $platform): CompilerBackend
{
if ($platform instanceof Windows) {
// Windows 默认使用 MSVC
return new Msvc($platform);
} elseif ($platform instanceof Linux) {
// Linux 默认使用 GCC
return new Gcc($platform);
} elseif ($platform instanceof Macos) {
// macOS 默认使用 Clang
return new Clang($platform);
} else {
throw new \RuntimeException("Unsupported platform: " . $platform->getName());
}
}
/**
* 创建指定类型的编译器后端
*/
public static function createByName(string $compilerName, PlatformBase $platform): CompilerBackend
{
return match (strtolower($compilerName)) {
'msvc', 'cl' => new Msvc($platform),
'gcc', 'g++' => new Gcc($platform),
'clang', 'clang++' => new Clang($platform),
default => throw new \RuntimeException("Unsupported compiler: {$compilerName}"),
};
}
/**
* 自动检测并创建编译器和平台
*/
public static function autoDetect(string $compilerName = ''): array
{
// 创建平台
$platform = \PhpAot\Php\Platform\PlatformFactory::create();
// 创建编译器
if (!empty($compilerName)) {
$compiler = self::createByName($compilerName, $platform);
} else {
$compiler = self::create($platform);
}
return [
'platform' => $platform,
'compiler' => $compiler,
];
}
}

@ -0,0 +1,143 @@
<?php
namespace PhpAot\Php\Backend;
use PhpAot\Php\Platform\PlatformBase;
/**
* GCC 编译器后端实现
*/
class Gcc extends CompilerBackend
{
public function getName(): string
{
return 'GCC';
}
public function getCompilerCommand(): string
{
return 'g++';
}
public function getLinkerCommand(): string
{
return 'g++';
}
public function compileFile(
string $sourceFile,
string $outputFile,
array $includePaths = [],
array $defines = [],
array $flags = []
): string {
$cmd = $this->getCompilerCommand();
$cmd .= ' -c ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
// 添加包含路径
if (!empty($includePaths)) {
$cmd .= ' ' . $this->formatIncludePaths($includePaths);
}
// 添加宏定义
foreach ($defines as $define) {
$cmd .= ' -D' . $define;
}
// 添加额外标志
if (!empty($flags)) {
$cmd .= ' ' . implode(' ', $flags);
}
return $cmd;
}
public function linkObjects(
array $objectFiles,
string $outputFile,
array $libraryPaths = [],
array $libraries = [],
array $flags = []
): string {
$cmd = $this->getLinkerCommand();
// 添加目标文件
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles));
// 输出文件
$cmd .= ' -o ' . escapeshellarg($outputFile);
// 添加库路径
if (!empty($libraryPaths)) {
$cmd .= ' ' . $this->formatLibraryPaths($libraryPaths);
}
// 添加库文件
if (!empty($libraries)) {
$cmd .= ' ' . $this->formatLibraries($libraries);
}
// 添加额外标志
if (!empty($flags)) {
$cmd .= ' ' . implode(' ', $flags);
}
return $cmd;
}
public function buildCompileCommand(string $sourceFile, string $outputFile, array $options = []): string
{
$cmd = $this->getCompilerCommand();
$cmd .= ' -c';
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
// 优化级别
$optimizeLevel = $options['optimize'] ?? 2;
$cmd .= ' -O' . $optimizeLevel;
// 调试信息
if (!empty($options['debug'])) {
$cmd .= ' -g';
}
// 警告级别
$cmd .= ' -Wall';
// C++ 标准
$cppStd = $options['cpp_std'] ?? 'c++17';
$cmd .= ' -std=' . $cppStd;
// PIC(位置无关代码)
if (!empty($options['pic'])) {
$cmd .= ' -fPIC';
}
return $cmd;
}
public function buildLinkCommand(array $objectFiles, string $outputFile, array $options = []): string
{
$cmd = $this->getLinkerCommand();
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles));
$cmd .= ' -o ' . escapeshellarg($outputFile);
// 共享库
if (!empty($options['shared'])) {
$cmd .= ' ' . $this->platform->getSharedLinkFlag();
// macOS 需要 install_name
if ($this->platform instanceof \PhpAot\Php\Platform\Macos && !empty($options['install_name'])) {
$cmd .= ' ' . $this->platform->getCurrentInstallNameOption($options['install_name']);
}
}
// RPATH(运行时库搜索路径)
if (!empty($options['rpath'])) {
$cmd .= ' ' . $this->platform->getRpathOptions($options['rpath']);
}
return $cmd;
}
}

@ -0,0 +1,156 @@
<?php
namespace PhpAot\Php\Backend;
use PhpAot\Php\Platform\Windows;
/**
* MSVC 编译器后端实现
*/
class Msvc extends CompilerBackend
{
public function __construct(Windows $platform)
{
parent::__construct($platform);
}
public function getName(): string
{
return 'MSVC';
}
public function getCompilerCommand(): string
{
return 'cl';
}
public function getLinkerCommand(): string
{
return 'link';
}
public function compileFile(
string $sourceFile,
string $outputFile,
array $includePaths = [],
array $defines = [],
array $flags = []
): string {
$cmd = $this->getCompilerCommand();
$cmd .= ' /c ' . escapeshellarg($sourceFile);
$cmd .= ' /Fo' . escapeshellarg($outputFile);
// 添加包含路径
if (!empty($includePaths)) {
$cmd .= ' ' . $this->formatIncludePaths($includePaths);
}
// 添加宏定义
foreach ($defines as $define) {
$cmd .= ' /D' . $define;
}
// 添加额外标志
if (!empty($flags)) {
$cmd .= ' ' . implode(' ', $flags);
}
return $cmd;
}
public function linkObjects(
array $objectFiles,
string $outputFile,
array $libraryPaths = [],
array $libraries = [],
array $flags = []
): string {
$cmd = $this->getLinkerCommand();
// 添加目标文件
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles));
// 输出文件
$cmd .= ' /OUT:' . escapeshellarg($outputFile);
// 添加库路径
if (!empty($libraryPaths)) {
$cmd .= ' ' . $this->formatLibraryPaths($libraryPaths);
}
// 添加库文件
if (!empty($libraries)) {
$cmd .= ' ' . $this->formatLibraries($libraries);
}
// 添加额外标志
if (!empty($flags)) {
$cmd .= ' ' . implode(' ', $flags);
}
return $cmd;
}
public function buildCompileCommand(string $sourceFile, string $outputFile, array $options = []): string
{
$cmd = $this->getCompilerCommand();
$cmd .= ' /c';
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' /Fo' . escapeshellarg($outputFile);
// 平台宏定义
$cmd .= ' /DZEND_WIN32 /DPHP_WIN32 /DZEND_DEBUG=0';
// ZTS 支持
if ($this->platform instanceof Windows && $this->platform->isZts()) {
$cmd .= ' /DZTS';
}
// 优化级别
$optimizeLevel = $options['optimize'] ?? 2;
$cmd .= ' /O' . ($optimizeLevel >= 2 ? '2' : ($optimizeLevel === 0 ? 'd' : '1'));
// 警告级别
$cmd .= ' /W3';
// C++ 标准
$cppStd = $options['cpp_std'] ?? 'c++17';
$cmd .= ' /std:' . $cppStd;
// 异常处理
$cmd .= ' /EHsc';
// CRT
$cmd .= ' /MD';
// nologo
$cmd .= ' /nologo';
return $cmd;
}
public function buildLinkCommand(array $objectFiles, string $outputFile, array $options = []): string
{
$cmd = $this->getLinkerCommand();
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles));
$cmd .= ' /OUT:' . escapeshellarg($outputFile);
// 调试信息
if (!empty($options['debug'])) {
$cmd .= ' /DEBUG';
}
// Windows 子系统
if (!empty($options['no_console'])) {
$cmd .= ' ' . $this->platform->getSubsystemOptions(true);
}
// CRT 配置
$cmd .= ' ' . $this->platform->getCrtConfig();
// nologo
$cmd .= ' /nologo';
return $cmd;
}
}

@ -0,0 +1,193 @@
# 编译器和平台抽象层
## 目录结构
```
src/Php/
├── Backend/ # 编译器后端抽象
│ ├── CompilerBackend.php # 编译器抽象基类
│ ├── CompilerFactory.php # 编译器工厂(自动检测)
│ ├── Msvc.php # MSVC 编译器实现 ✅
│ ├── Gcc.php # GCC 编译器实现 ✅
│ ├── Clang.php # Clang 编译器实现 ✅
│ ├── example_usage.php # 使用示例
│ └── README.md # 本文档
└── Platform/ # 平台抽象
├── PlatformBase.php # 平台抽象基类
├── PlatformFactory.php # 平台工厂(自动检测)
├── Windows.php # Windows 平台实现 ✅
├── Linux.php # Linux 平台实现 ✅
└── Macos.php # macOS 平台实现 ✅
```
## 设计理念
### 1. 平台抽象 (Platform)
**职责:**
- 处理不同操作系统的差异
- 提供统一的路径、文件扩展名、命令行参数格式
- 封装平台特定的配置和选项
**核心方法:**
- `getIncludeFlags()` - 获取包含路径参数
- `getLibraryPathFlags()` - 获取库路径参数
- `getLibraryFlags()` - 获取库文件参数
- `getObjectExtension()` - 获取对象文件扩展名
- `getExecutableExtension()` - 获取可执行文件扩展名
### 2. 编译器后端 (Backend)
**职责:**
- 处理不同编译器的差异
- 生成编译和链接命令
- 封装编译器特定的选项和标志
**核心方法:**
- `compileFile()` - 编译单个文件
- `linkObjects()` - 链接目标文件
- `buildCompileCommand()` - 构建完整编译命令
- `buildLinkCommand()` - 构建完整链接命令
## 使用示例
### 基本用法
```php
use PhpAot\Php\Platform\Windows;
use PhpAot\Php\Backend\Msvc;
// 创建平台实例
$platform = new Windows(
phpLibs: ['php8embed.lib', 'php8ts.lib'],
isZts: true
);
// 创建编译器后端
$compiler = new Msvc($platform);
// 构建编译命令
$compileCmd = $compiler->buildCompileCommand(
'source.cpp',
'source.obj',
[
'optimize' => 2,
'cpp_std' => 'c++17',
]
);
// 构建链接命令
$linkCmd = $compiler->buildLinkCommand(
['source.obj'],
'output.exe',
[
'debug' => true,
'no_console' => false,
]
);
```
### 跨平台支持
```php
use PhpAot\Php\Platform\Linux;
use PhpAot\Php\Platform\Macos;
use PhpAot\Php\Backend\Gcc;
// 自动检测当前平台
if ((new Windows())->isCurrent()) {
$platform = new Windows();
$compiler = new Msvc($platform);
} elseif ((new Linux())->isCurrent()) {
$platform = new Linux();
$compiler = new Gcc($platform);
} elseif ((new Macos())->isCurrent()) {
$platform = new Macos();
$compiler = new Gcc($platform); // macOS 通常也用 GCC/Clang
}
```
## 优势
### 1. 关注点分离
- **Platform**: 只关心操作系统差异
- **Backend**: 只关心编译器差异
- 两者独立,可以任意组合
### 2. 易于扩展
- 添加新平台:继承 `PlatformBase`
- 添加新编译器:继承 `CompilerBackend`
- 无需修改现有代码
### 3. 易于测试
- 每个类职责单一
- 可以独立单元测试
- 便于 Mock 和 stub
### 4. 代码复用
- 平台相关逻辑集中管理
- 编译器相关逻辑集中管理
- 避免重复代码
## 迁移计划
### 阶段 1:创建抽象层(✅ 已完成)
- ✅ 创建 Platform 抽象和实现
- ✅ PlatformBase.php
- ✅ Windows.php
- ✅ Linux.php
- ✅ Macos.php
- ✅ PlatformFactory.php
- ✅ 创建 Backend 抽象和实现
- ✅ CompilerBackend.php
- ✅ Msvc.php
- ✅ Gcc.php
- ✅ Clang.php
- ✅ CompilerFactory.php
- ✅ 创建使用示例和文档
- ✅ example_usage.php
- ✅ README.md
### 阶段 2:重构 CompilerBase
- 将平台相关代码迁移到 Platform 类
- 将编译器相关代码迁移到 Backend 类
- CompilerBase 作为协调者使用这些类
### 阶段 3:清理和优化
- 删除冗余代码
- 更新文档
- 完善测试
## 下一步工作
### ✅ 已完成
1. **完成 Backend 实现**
- ✅ 创建 `Gcc.php`
- ✅ 创建 `Clang.php`
- ✅ 创建 `CompilerFactory.php`(自动检测)
2. **完成 Platform 实现**
- ✅ 创建所有平台实现
- ✅ 创建 `PlatformFactory.php`(自动检测)
3. **文档和示例**
- ✅ 创建详细 README
- ✅ 创建使用示例
### 🔄 进行中
4. **重构 CompilerBase**
- ⏳ 使用新的 Platform 和 Backend 类
- ⏳ 保持向后兼容
- ⏳ 逐步迁移现有代码
### 📋 待办
5. **添加单元测试**
- ⏳ 测试所有 Platform 实现
- ⏳ 测试所有 Backend 实现
- ⏳ 测试工厂类
- ⏳ 测试集成场景
6. **文档完善**
- ⏳ 添加更多使用示例
- ⏳ 编写迁移指南
- ⏳ 更新 API 文档

@ -0,0 +1,78 @@
<?php
/**
* 新架构使用示例
*
* 展示如何使用 Platform 和 Backend 抽象层
*/
require_once __DIR__ . '/../../../vendor/autoload.php';
use PhpAot\Php\Platform\PlatformFactory;
use PhpAot\Php\Backend\CompilerFactory;
echo "=== 平台和编译器抽象层示例 ===\n\n";
// 示例 1:自动检测平台和编译器
echo "1. 自动检测平台和编译器:\n";
$result = CompilerFactory::autoDetect();
$platform = $result['platform'];
$compiler = $result['compiler'];
echo " 平台: {$platform->getName()}\n";
echo " 编译器: {$compiler->getName()}\n";
echo " 对象文件扩展名: {$platform->getObjectExtension()}\n";
echo " 可执行文件扩展名: {$platform->getExecutableExtension()}\n";
echo "\n";
// 示例 2:构建编译命令
echo "2. 构建编译命令:\n";
$compileCmd = $compiler->buildCompileCommand(
'test.cpp',
'test' . $platform->getObjectExtension(),
[
'optimize' => 2,
'debug' => false,
'cpp_std' => 'c++17',
]
);
echo " {$compileCmd}\n";
echo "\n";
// 示例 3:构建链接命令
echo "3. 构建链接命令:\n";
$linkCmd = $compiler->buildLinkCommand(
['test' . $platform->getObjectExtension()],
'output' . $platform->getExecutableExtension(),
[
'debug' => true,
'no_console' => false,
]
);
echo " {$linkCmd}\n";
echo "\n";
// 示例 4:手动指定平台和编译器
echo "4. 手动指定平台和编译器:\n";
use PhpAot\Php\Platform\Windows;
use PhpAot\Php\Backend\Msvc;
$windowsPlatform = new Windows(
phpLibs: ['php8embed.lib', 'php8ts.lib'],
isZts: true
);
$msvcCompiler = new Msvc($windowsPlatform);
echo " 平台: {$windowsPlatform->getName()}\n";
echo " 编译器: {$msvcCompiler->getName()}\n";
echo " ZTS: " . ($windowsPlatform->isZts() ? 'Yes' : 'No') . "\n";
echo "\n";
// 示例 5:跨平台路径处理
echo "5. 跨平台路径处理:\n";
$path = $platform->joinPath('src', 'Php', 'Backend');
echo " 组合路径: {$path}\n";
echo " 路径分隔符: '{$platform->getPathSeparator()}'\n";
echo "\n";
echo "=== 示例完成 ===\n";

@ -0,0 +1,121 @@
<?php
namespace PhpAot\Php\Platform;
/**
* Linux 平台实现
*/
class Linux extends PlatformBase
{
public function getName(): string
{
return 'Linux';
}
public function isCurrent(): bool
{
return PHP_OS === 'Linux';
}
public function getIncludeFlags(array $includePaths): string
{
if (empty($includePaths)) {
return '';
}
$flags = [];
foreach ($includePaths as $path) {
$flags[] = '-I' . escapeshellarg($path);
}
return implode(' ', $flags);
}
public function getLibraryPathFlags(array $libraryPaths): string
{
if (empty($libraryPaths)) {
return '';
}
$flags = [];
foreach ($libraryPaths as $path) {
$flags[] = '-L' . escapeshellarg($path);
}
return implode(' ', $flags);
}
public function getLibraryFlags(array $libraries): string
{
if (empty($libraries)) {
return '';
}
$flags = [];
foreach ($libraries as $lib) {
// 移除 lib 前缀和 .a/.so 后缀
$libName = basename($lib);
if (str_starts_with($libName, 'lib')) {
$libName = substr($libName, 3);
}
$libName = preg_replace('/\.(a|so)$/', '', $libName);
$flags[] = '-l' . $libName;
}
return implode(' ', $flags);
}
public function getObjectExtension(): string
{
return '.o';
}
public function getExecutableExtension(): string
{
return '';
}
public function getSharedLibraryExtension(): string
{
return '.so';
}
public function getPathSeparator(): string
{
return '/';
}
/**
* 获取 RPATH 选项
*/
public function getRpathOptions(array $paths): string
{
if (empty($paths)) {
return '';
}
$rpaths = [];
foreach ($paths as $path) {
$rpaths[] = '-Wl,-rpath,' . escapeshellarg($path);
}
return implode(' ', $rpaths);
}
/**
* 获取 PIC 选项
*/
public function getPicFlag(): string
{
return '-fPIC';
}
/**
* 获取共享库链接选项
*/
public function getSharedLinkFlag(): string
{
return '-shared';
}
}

@ -0,0 +1,129 @@
<?php
namespace PhpAot\Php\Platform;
/**
* macOS 平台实现
*/
class Macos extends PlatformBase
{
public function getName(): string
{
return 'macOS';
}
public function isCurrent(): bool
{
return strtoupper(substr(PHP_OS, 0, 6)) === 'DARWIN';
}
public function getIncludeFlags(array $includePaths): string
{
if (empty($includePaths)) {
return '';
}
$flags = [];
foreach ($includePaths as $path) {
$flags[] = '-I' . escapeshellarg($path);
}
return implode(' ', $flags);
}
public function getLibraryPathFlags(array $libraryPaths): string
{
if (empty($libraryPaths)) {
return '';
}
$flags = [];
foreach ($libraryPaths as $path) {
$flags[] = '-L' . escapeshellarg($path);
}
return implode(' ', $flags);
}
public function getLibraryFlags(array $libraries): string
{
if (empty($libraries)) {
return '';
}
$flags = [];
foreach ($libraries as $lib) {
// 移除 lib 前缀和 .a/.dylib 后缀
$libName = basename($lib);
if (str_starts_with($libName, 'lib')) {
$libName = substr($libName, 3);
}
$libName = preg_replace('/\.(a|dylib)$/', '', $libName);
$flags[] = '-l' . $libName;
}
return implode(' ', $flags);
}
public function getObjectExtension(): string
{
return '.o';
}
public function getExecutableExtension(): string
{
return '';
}
public function getSharedLibraryExtension(): string
{
return '.dylib';
}
public function getPathSeparator(): string
{
return '/';
}
/**
* 获取 RPATH 选项(macOS 需要绝对路径)
*/
public function getRpathOptions(array $paths): string
{
if (empty($paths)) {
return '';
}
$rpaths = [];
foreach ($paths as $path) {
$rpaths[] = '-Wl,-rpath,' . escapeshellarg($path);
}
return implode(' ', $rpaths);
}
/**
* 获取 PIC 选项
*/
public function getPicFlag(): string
{
return '-fPIC';
}
/**
* 获取共享库链接选项
*/
public function getSharedLinkFlag(): string
{
return '-dynamiclib';
}
/**
* 获取当前安装名称选项
*/
public function getCurrentInstallNameOption(string $path): string
{
return '-install_name ' . escapeshellarg($path);
}
}

@ -0,0 +1,71 @@
<?php
namespace PhpAot\Php\Platform;
/**
* 平台抽象基类
* 定义所有平台必须实现的接口
*/
abstract class PlatformBase
{
/**
* 获取平台名称
*/
abstract public function getName(): string;
/**
* 判断是否为当前平台
*/
abstract public function isCurrent(): bool;
/**
* 获取编译器包含路径参数
*/
abstract public function getIncludeFlags(array $includePaths): string;
/**
* 获取链接器库路径参数
*/
abstract public function getLibraryPathFlags(array $libraryPaths): string;
/**
* 获取链接库参数
*/
abstract public function getLibraryFlags(array $libraries): string;
/**
* 获取文件扩展名
*/
abstract public function getObjectExtension(): string;
/**
* 获取可执行文件扩展名
*/
abstract public function getExecutableExtension(): string;
/**
* 获取动态库扩展名
*/
abstract public function getSharedLibraryExtension(): string;
/**
* 获取路径分隔符
*/
abstract public function getPathSeparator(): string;
/**
* 规范化路径
*/
public function normalizePath(string $path): string
{
return str_replace('/', $this->getPathSeparator(), $path);
}
/**
* 组合路径
*/
public function joinPath(string ...$parts): string
{
return implode($this->getPathSeparator(), $parts);
}
}

@ -0,0 +1,58 @@
<?php
namespace PhpAot\Php\Platform;
/**
* 平台工厂类
* 自动检测并创建当前平台的实例
*/
class PlatformFactory
{
/**
* 创建当前平台的实例
*/
public static function create(): PlatformBase
{
if ((new Windows())->isCurrent()) {
return new Windows();
} elseif ((new Linux())->isCurrent()) {
return new Linux();
} elseif ((new Macos())->isCurrent()) {
return new Macos();
} else {
throw new \RuntimeException("Unsupported platform: " . PHP_OS);
}
}
/**
* 获取当前平台名称
*/
public static function getCurrentPlatformName(): string
{
return self::create()->getName();
}
/**
* 判断是否为 Windows 平台
*/
public static function isWindows(): bool
{
return (new Windows())->isCurrent();
}
/**
* 判断是否为 Linux 平台
*/
public static function isLinux(): bool
{
return (new Linux())->isCurrent();
}
/**
* 判断是否为 macOS 平台
*/
public static function isMacos(): bool
{
return (new Macos())->isCurrent();
}
}

@ -0,0 +1,145 @@
<?php
namespace PhpAot\Php\Platform;
/**
* Windows 平台实现
*/
class Windows extends PlatformBase
{
/**
* PHP 库文件信息
*/
private array $phpLibs = [];
/**
* 是否为 ZTS 模式
*/
private bool $isZts = false;
public function __construct(array $phpLibs = [], bool $isZts = false)
{
$this->phpLibs = $phpLibs;
$this->isZts = $isZts;
}
public function getName(): string
{
return 'Windows';
}
public function isCurrent(): bool
{
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
}
public function getIncludeFlags(array $includePaths): string
{
if (empty($includePaths)) {
return '';
}
$flags = [];
foreach ($includePaths as $path) {
$flags[] = '/I "' . $path . '"';
}
return implode(' ', $flags);
}
public function getLibraryPathFlags(array $libraryPaths): string
{
if (empty($libraryPaths)) {
return '';
}
$flags = [];
foreach ($libraryPaths as $path) {
$flags[] = '/LIBPATH:"' . $path . '"';
}
return implode(' ', $flags);
}
public function getLibraryFlags(array $libraries): string
{
if (empty($libraries)) {
return '';
}
$flags = [];
foreach ($libraries as $lib) {
$flags[] = '"' . $lib . '"';
}
return implode(' ', $flags);
}
public function getObjectExtension(): string
{
return '.obj';
}
public function getExecutableExtension(): string
{
return '.exe';
}
public function getSharedLibraryExtension(): string
{
return '.dll';
}
public function getPathSeparator(): string
{
return '\\';
}
/**
* 获取 PHP 库文件列表
*/
public function getPhpLibs(): array
{
return $this->phpLibs;
}
/**
* 判断是否为 ZTS 模式
*/
public function isZts(): bool
{
return $this->isZts;
}
/**
* 获取 Windows 子系统选项
*/
public function getSubsystemOptions(bool $noConsole): string
{
if (!$noConsole) {
return '';
}
return '/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup';
}
/**
* 获取 CRT 库配置
*/
public function getCrtConfig(): string
{
return '/NODEFAULTLIB:LIBCMT';
}
/**
* 获取调试选项
*/
public function getDebugOptions(bool $debugInfo): string
{
if (!$debugInfo) {
return '';
}
return '/DEBUG';
}
}
Loading…
Cancel
Save