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.
 
 

443 lines
8.0 KiB

# 配置优先级规则说明
## 📋 概述
PHPX 编译器的配置遵循明确的优先级规则,确保用户可以灵活地控制编译行为。
---
## 🎯 优先级顺序(从高到低)
```
1. 命令行参数(最高优先级)
2. YAML 配置文件
3. 平台默认值(最低优先级)
```
---
## 💡 工作原理
### 执行流程
```mermaid
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[开始编译]
```
### 详细说明
1. **构造函数阶段**
- 解析命令行参数
- **不立即应用**到属性
- 仅处理 `--help``--version`
2. **YAML 解析阶段**(仅当输入是 `.yml` 文件时)
- 读取 `project.yml` 配置
- 应用到编译器属性
- 设置默认值
3. **命令行参数应用阶段**
- 检查哪些命令行参数被定义
- **覆盖** YAML 配置或默认值
- 确保命令行参数优先级最高
---
## 📊 配置项示例
### 示例 1:C++ 标准版本
#### YAML 配置
```yaml
# project.yml
cxx-std: c++14
```
#### 命令行覆盖
```bash
php bin/compiler.php project.yml --cxx-std=c++17
```
#### 结果
✅ 使用 **c++17**(命令行优先级更高)
---
### 示例 2:构建模式
#### YAML 配置
```yaml
# project.yml
build-mode: bin
```
#### 命令行覆盖
```bash
php bin/compiler.php project.yml --mode=ext
```
#### 结果
✅ 使用 **ext**(命令行优先级更高)
---
### 示例 3:编译选项
#### YAML 配置
```yaml
# project.yml
cxx-flags:
- -Wall
- -O2
```
#### 命令行覆盖
```bash
php bin/compiler.php project.yml -O3
```
#### 结果
✅ 优化级别为 **3**(命令行优先级更高)
✅ cxx-flags 仍为 `-Wall -O2`(YAML 配置)
---
## 🔍 不同输入类型的处理
### 类型 1:YAML 配置文件
```bash
php bin/compiler.php project.yml --cxx-std=c++17
```
**执行流程:**
1. ✅ 解析 `project.yml`
2. ✅ 应用 YAML 中的配置
3. ✅ 用 `--cxx-std=c++17` 覆盖
**适用场景:**
- 大型项目
- 需要复杂配置
- 团队协作
---
### 类型 2:单个 PHP 文件
```bash
php bin/compiler.php hello.php --cxx-std=c++17 -O2
```
**执行流程:**
1. ❌ 跳过 YAML 解析
2. ✅ 直接应用命令行参数
3. ✅ 使用平台默认值作为基础
**适用场景:**
- 快速测试
- 简单脚本
- 临时编译
---
### 类型 3:目录
```bash
php bin/compiler.php src/ --mode=ext --cxx-std=c++17
```
**执行流程:**
1. ❌ 跳过 YAML 解析
2. ✅ 扫描目录中的所有 PHP 文件
3. ✅ 应用命令行参数
4. ✅ 使用平台默认值作为基础
**适用场景:**
- 批量编译
- 扩展模块
- 多文件项目
---
## 📝 完整示例
### 项目配置
```yaml
# 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:使用默认配置
```bash
php bin/compiler.php project.yml
```
**结果:**
- cxx-std: **c++14**(来自 YAML)
- build-mode: **bin**(来自 YAML)
- cxx-flags: **-Wall -Wextra**(来自 YAML)
---
### 场景 2:部分覆盖
```bash
php bin/compiler.php project.yml --cxx-std=c++17
```
**结果:**
- cxx-std: **c++17**(命令行覆盖)
- build-mode: **bin**(来自 YAML)
- cxx-flags: **-Wall -Wextra**(来自 YAML)
---
### 场景 3:完全覆盖
```bash
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:单文件编译
```bash
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 中设置默认值
```yaml
# project.yml - 团队共享的默认配置
name: my-app
build-mode: bin
cxx-std: c++17
cxx-flags:
- -Wall
- -Wextra
```
---
### 2. 命令行用于临时覆盖
```bash
# 开发时使用调试模式
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. 单文件快速测试
```bash
# 不需要 YAML,直接编译
php bin/compiler.php test.php -O2 --cxx-std=c++17
```
---
## 🐛 常见问题
### Q1: 为什么命令行参数没有生效?
A: 确保使用了正确的参数名称:
```bash
# ✅ 正确
php bin/compiler.php project.yml --cxx-std=c++17
# ❌ 错误(参数名不对)
php bin/compiler.php project.yml --cxx_std=c++17
```
---
### Q2: YAML 和命令行都设置了同一个值,哪个生效?
A: **命令行参数始终优先**
```yaml
# project.yml
cxx-std: c++14
```
```bash
php bin/compiler.php project.yml --cxx-std=c++17
# 结果:使用 c++17
```
---
### Q3: 可以在 YAML 中设置优化级别吗?
A: 目前不支持。优化级别只能通过命令行设置:
```bash
php bin/compiler.php project.yml -O2
```
---
### Q4: 如何查看当前使用的配置?
A: 编译时会显示相关信息:
```
prepare: project.yml
...
C++ standard: c++17
Build mode: bin
Optimization: O2
...
```
---
## 📚 技术实现
### 代码位置
**Translator.php:**
```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(); // 直接命令行
}
}
```
---
## 🎉 总结
### 核心原则
1.**命令行参数优先级最高** - 用户可以随时覆盖
2.**YAML 提供默认值** - 简化日常使用
3.**平台默认值兜底** - 确保总能运行
4.**清晰的执行顺序** - 易于理解和调试
### 优先级图示
```
用户意图
命令行参数 ────────→ 最高优先级,立即生效
YAML 配置 ─────────→ 中等优先级,提供默认值
平台默认值 ────────→ 最低优先级,保证可用性
```
遵循这些规则,您可以灵活地控制编译行为!