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.
8.0 KiB
8.0 KiB
配置优先级规则说明
📋 概述
PHPX 编译器的配置遵循明确的优先级规则,确保用户可以灵活地控制编译行为。
🎯 优先级顺序(从高到低)
1. 命令行参数(最高优先级)
↓
2. YAML 配置文件
↓
3. 平台默认值(最低优先级)
💡 工作原理
执行流程
graph TD
A[启动编译器] --> B[解析命令行参数]
B --> C{输入类型?}
C -->|YAML 文件| D[解析 YAML 配置]
C -->|单 PHP 文件| E[跳过 YAML]
C -->|目录| F[跳过 YAML]
D --> G[应用命令行参数覆盖]
E --> G
F --> G
G --> H[开始编译]
详细说明
-
构造函数阶段
- 解析命令行参数
- 不立即应用到属性
- 仅处理
--help和--version
-
YAML 解析阶段(仅当输入是
.yml文件时)- 读取
project.yml配置 - 应用到编译器属性
- 设置默认值
- 读取
-
命令行参数应用阶段
- 检查哪些命令行参数被定义
- 覆盖 YAML 配置或默认值
- 确保命令行参数优先级最高
📊 配置项示例
示例 1:C++ 标准版本
YAML 配置
# project.yml
cxx-std: c++14
命令行覆盖
php bin/compiler.php project.yml --cxx-std=c++17
结果
✅ 使用 c++17(命令行优先级更高)
示例 2:构建模式
YAML 配置
# project.yml
build-mode: bin
命令行覆盖
php bin/compiler.php project.yml --mode=ext
结果
✅ 使用 ext(命令行优先级更高)
示例 3:编译选项
YAML 配置
# project.yml
cxx-flags:
- -Wall
- -O2
命令行覆盖
php bin/compiler.php project.yml -O3
结果
✅ 优化级别为 3(命令行优先级更高)
✅ cxx-flags 仍为 -Wall -O2(YAML 配置)
🔍 不同输入类型的处理
类型 1:YAML 配置文件
php bin/compiler.php project.yml --cxx-std=c++17
执行流程:
- ✅ 解析
project.yml - ✅ 应用 YAML 中的配置
- ✅ 用
--cxx-std=c++17覆盖
适用场景:
- 大型项目
- 需要复杂配置
- 团队协作
类型 2:单个 PHP 文件
php bin/compiler.php hello.php --cxx-std=c++17 -O2
执行流程:
- ❌ 跳过 YAML 解析
- ✅ 直接应用命令行参数
- ✅ 使用平台默认值作为基础
适用场景:
- 快速测试
- 简单脚本
- 临时编译
类型 3:目录
php bin/compiler.php src/ --mode=ext --cxx-std=c++17
执行流程:
- ❌ 跳过 YAML 解析
- ✅ 扫描目录中的所有 PHP 文件
- ✅ 应用命令行参数
- ✅ 使用平台默认值作为基础
适用场景:
- 批量编译
- 扩展模块
- 多文件项目
📝 完整示例
项目配置
# project.yml
name: my-app
build-mode: bin
version: 1.0.0
cxx-std: c++14
cxx-flags:
- -Wall
- -Wextra
ld-flags:
- -lm
sources:
- src/main.php
- src/utils.php
场景 1:使用默认配置
php bin/compiler.php project.yml
结果:
- cxx-std: c++14(来自 YAML)
- build-mode: bin(来自 YAML)
- cxx-flags: -Wall -Wextra(来自 YAML)
场景 2:部分覆盖
php bin/compiler.php project.yml --cxx-std=c++17
结果:
- cxx-std: c++17(命令行覆盖)
- build-mode: bin(来自 YAML)
- cxx-flags: -Wall -Wextra(来自 YAML)
场景 3:完全覆盖
php bin/compiler.php project.yml --cxx-std=c++20 --mode=ext -O3
结果:
- cxx-std: c++20(命令行覆盖)
- build-mode: ext(命令行覆盖)
- optimize-level: 3(命令行覆盖)
- cxx-flags: -Wall -Wextra(来自 YAML,未被覆盖)
场景 4:单文件编译
php bin/compiler.php test.php --cxx-std=c++17 -O2
结果:
- cxx-std: c++17(命令行)
- build-mode: bin(默认值)
- optimize-level: 2(命令行)
- 无 YAML 配置
⚙️ 支持的配置项
可从 YAML 读取的配置
| 配置项 | YAML 键 | 命令行参数 | 说明 |
|---|---|---|---|
| 项目名称 | name |
--output |
输出文件名 |
| 构建模式 | build-mode / type |
--mode |
bin 或 ext |
| C++ 标准 | cxx-std |
--cxx-std |
c++14/17/20 |
| 编译选项 | cxx-flags |
- | C++ 编译标志 |
| 链接选项 | ld-flags |
- | 链接器标志 |
| 源文件 | sources |
- | 源文件列表 |
| 忽略列表 | ignore |
- | 忽略的文件 |
只能从命令行设置的配置
| 配置项 | 命令行参数 | 说明 |
|---|---|---|
| 优化级别 | -O <level> |
0-3 |
| 调试信息 | --debug |
启用调试 |
| 性能分析 | --profile |
启用 profiling |
| Sanitizer | --sanitize |
内存检测 |
| 并行任务 | -j <num> |
并行编译数 |
| 隐藏控制台 | --no-console |
Windows GUI |
🎨 最佳实践
1. YAML 中设置默认值
# project.yml - 团队共享的默认配置
name: my-app
build-mode: bin
cxx-std: c++17
cxx-flags:
- -Wall
- -Wextra
2. 命令行用于临时覆盖
# 开发时使用调试模式
php bin/compiler.php project.yml --debug
# 发布时使用优化
php bin/compiler.php project.yml -O3
# 测试不同的 C++ 标准
php bin/compiler.php project.yml --cxx-std=c++20
3. 单文件快速测试
# 不需要 YAML,直接编译
php bin/compiler.php test.php -O2 --cxx-std=c++17
🐛 常见问题
Q1: 为什么命令行参数没有生效?
A: 确保使用了正确的参数名称:
# ✅ 正确
php bin/compiler.php project.yml --cxx-std=c++17
# ❌ 错误(参数名不对)
php bin/compiler.php project.yml --cxx_std=c++17
Q2: YAML 和命令行都设置了同一个值,哪个生效?
A: 命令行参数始终优先。
# project.yml
cxx-std: c++14
php bin/compiler.php project.yml --cxx-std=c++17
# 结果:使用 c++17
Q3: 可以在 YAML 中设置优化级别吗?
A: 目前不支持。优化级别只能通过命令行设置:
php bin/compiler.php project.yml -O2
Q4: 如何查看当前使用的配置?
A: 编译时会显示相关信息:
prepare: project.yml
...
C++ standard: c++17
Build mode: bin
Optimization: O2
...
📚 技术实现
代码位置
Translator.php:
// 1. 构造函数:解析但不应用
public function __construct(string $rootPath)
{
$this->climate->arguments->parse();
// 不立即应用参数
}
// 2. YAML 解析:应用配置
protected function parseProjectYaml(string $path): array
{
// 读取 YAML 并应用到属性
$this->cxxStd = $cfg['cxx-std'] ?? 'c++17';
$this->buildMode = $cfg['build-mode'] ?? 'bin';
// ...
}
// 3. 应用命令行:覆盖配置
protected function applyCommandLineArguments(): void
{
if ($this->climate->arguments->defined('cxx-std')) {
$this->cxxStd = $this->climate->arguments->get('cxx-std');
}
// ...
}
// 4. getFiles:控制流程
public function getFiles(string $path): array
{
if (is_yml($path)) {
$this->parseProjectYaml($path); // 先 YAML
$this->applyCommandLineArguments(); // 后命令行
} else {
$this->applyCommandLineArguments(); // 直接命令行
}
}
🎉 总结
核心原则
- ✅ 命令行参数优先级最高 - 用户可以随时覆盖
- ✅ YAML 提供默认值 - 简化日常使用
- ✅ 平台默认值兜底 - 确保总能运行
- ✅ 清晰的执行顺序 - 易于理解和调试
优先级图示
用户意图
↓
命令行参数 ────────→ 最高优先级,立即生效
↓
YAML 配置 ─────────→ 中等优先级,提供默认值
↓
平台默认值 ────────→ 最低优先级,保证可用性
遵循这些规则,您可以灵活地控制编译行为!