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.
 
 

360 lines
6.3 KiB

# C++ 标准配置指南
## 📋 概述
PHPX 编译器现在支持独立配置 C++ 标准版本,不再需要从 `cxxflags` 中提取。这使得配置更加清晰和易于管理。
---
## 🚀 使用方法
### 1. 命令行方式
使用 `--cxx-std` 参数指定 C++ 标准版本:
```bash
# 使用 C++14
php bin/tpc.php app.php --cxx-std=c++14
# 使用 C++17(默认)
php bin/tpc.php app.php --cxx-std=c++17
# 使用 C++20
php bin/tpc.php app.php --cxx-std=c++20
# Windows MSVC
php bin/tpc.php app.php --cxx-std=c++17
# Linux/macOS GCC/Clang
php bin/tpc.php app.php --cxx-std=c++17
```
---
### 2. project.yml 配置文件方式
`project.yml` 中添加 `cxx_std` 配置项:
```yaml
name: my-app
type: bin
sources:
- src/main.php
- src/utils.php
# C++ 标准版本(独立配置)
cxx_std: c++17
# 其他编译选项(不包含 C++ 标准)
cxxflags:
- -Wall
- -Wextra
ldflags:
- -lm
```
**注意:**
-`cxx_std` 专门用于指定 C++ 标准
-`cxxflags` 用于其他编译选项(如警告、优化等)
- ❌ 不要在 `cxxflags` 中包含 `-std=c++XX``/std:c++XX`
---
## 📊 支持的 C++ 标准
| 标准 | MSVC 标志 | GCC/Clang 标志 | 说明 |
|------|----------|----------------|------|
| c++14 | `/std:c++14` | `-std=c++14` | 默认(Unix) |
| c++17 | `/std:c++17` | `-std=c++17` | **推荐**(Windows 默认) |
| c++20 | `/std:c++20` | `-std=c++20` | 最新标准 |
| c++23 | `/std:c++23` | `-std=c++23` | 实验性支持 |
---
## 💡 平台默认值
### Windows (MSVC)
```php
// CompilerBase.php
$this->cxxStd = 'c++17'; // MSVC 更好的支持 C++17
```
**原因:** MSVC 对 C++17 的支持更成熟,C++14 的部分特性在 MSVC 中实现不完整。
---
### Linux/macOS (GCC/Clang)
```php
// CompilerBase.php
$this->cxxStd = 'c++14';
```
**原因:** C++14 是最广泛支持的标准,兼容性最好。
---
## 🔧 优先级规则
C++ 标准的设置遵循以下优先级(从高到低):
1. **命令行参数** `--cxx-std=XXX`(最高优先级)
2. **project.yml 配置** `cxx_std: XXX`
3. **平台默认值**(Windows: c++17, Unix: c++14)
**示例:**
```yaml
# project.yml
cxx_std: c++14
```
```bash
# 命令行覆盖配置文件
php bin/tpc.php project.yml --cxx-std=c++17
# 最终使用 c++17
```
---
## ⚠ 注意事项
### 1. 不要在 cxxflags 中重复指定
**错误做法:**
```yaml
cxx_std: c++17
cxxflags:
- -std=c++17 # 重复指定!
```
**正确做法:**
```yaml
cxx_std: c++17
cxxflags:
- -Wall
- -Wextra
```
---
### 2. cxxflags 中的标准会被忽略
如果 `cxxflags` 中包含了 `-std=``/std:`,编译器会使用 `$this->cxxStd` 的值,而不是 `cxxflags` 中的值。
**代码逻辑:**
```php
// Windows
if (!str_contains($this->cxxflags, '/std:')) {
$cmd .= ' /std:' . $this->cxxStd; // 使用 cxxStd
}
// Unix
if (!str_contains($this->cxxflags, ' -std=')) {
$cmd .= ' -std=' . $this->cxxStd; // 使用 cxxStd
}
```
---
### 3. 选择合适的 C++ 标准
| 场景 | 推荐标准 | 原因 |
|------|---------|------|
| 最大兼容性 | c++14 | 所有编译器都支持 |
| 现代特性 | c++17 | 结构化绑定、if constexpr 等 |
| 最新特性 | c++20 | concepts、coroutines、modules |
| Windows 项目 | c++17 | MSVC 支持更好 |
| Linux 项目 | c++14 或 c++17 | 根据需求选择 |
---
## 📝 完整示例
### 示例 1:基本项目
```yaml
# project.yml
name: hello-world
type: bin
sources:
- src/main.php
cxx_std: c++17
```
编译命令:
```bash
php bin/tpc.php project.yml
```
生成的编译命令:
```bash
# Windows
cl /std:c++17 /O0 ...
# Linux
g++ -std=c++17 -O0 ...
```
---
### 示例 2:带额外编译选项
```yaml
# project.yml
name: my-app
type: bin
sources:
- src/*.php
cxx_std: c++17
cxxflags:
- -Wall
- -Wextra
- -Wpedantic
ldflags:
- -lm
- -lpthread
```
---
### 示例 3:命令行覆盖
```yaml
# project.yml
name: my-app
cxx_std: c++14 # 配置文件中的默认值
```
```bash
# 使用 C++17 覆盖配置文件
php bin/tpc.php project.yml --cxx-std=c++17
```
---
## 🎯 迁移指南
如果您之前的 `project.yml` 中有这样的配置:
### ❌ 旧配置(不推荐)
```yaml
cxxflags:
- -std=c++17
- -Wall
- -O2
```
### ✅ 新配置(推荐)
```yaml
cxx_std: c++17
cxxflags:
- -Wall
- -O2
```
**优势:**
- ✅ 配置更清晰
- ✅ 更容易维护
- ✅ 跨平台兼容更好
- ✅ 避免重复和冲突
---
## 🔍 验证方法
编译时查看输出,确认 C++ 标准是否正确设置:
```bash
php bin/tpc.php project.yml --verbose
```
应该看到类似这样的输出:
```
Compiling typephp_main.cc...
g++ -std=c++17 -O0 -Wall ...
```
或者 Windows:
```
cl /std:c++17 /O0 /Wall ...
```
---
## 🐛 常见问题
### Q1: 为什么我的 C++17 特性不起作用?
A: 检查是否正确设置了 `cxx_std`
```yaml
cxx_std: c++17 # 确保是 c++17 而不是 c++14
```
或者使用命令行:
```bash
php bin/tpc.php app.php --cxx-std=c++17
```
---
### Q2: cxxflags 中的 -std= 会被忽略吗?
A: 是的,编译器会优先使用 `$this->cxxStd` 的值。建议在 `cxxflags` 中不要包含 `-std=``/std:`
---
### Q3: 可以在不同文件中使用不同的 C++ 标准吗?
A: 不可以。C++ 标准是整个项目的统一配置,所有文件使用相同的标准。
---
### Q4: C++20 支持如何?
A:
- **MSVC**: 需要 Visual Studio 2019 16.11+ 或 VS 2022
- **GCC**: 需要 GCC 10+
- **Clang**: 需要 Clang 10+
如果您的编译器不支持 C++20,请使用 C++17。
---
## 📚 相关资源
- [C++14 特性](https://en.cppreference.com/w/cpp/14)
- [C++17 特性](https://en.cppreference.com/w/cpp/17)
- [C++20 特性](https://en.cppreference.com/w/cpp/20)
- [MSVC 编译器选项](https://docs.microsoft.com/cpp/build/reference/std-specify-language-standard-version)
- [GCC C++ 标准](https://gcc.gnu.org/projects/cxx-status.html)
---
## 🎉 总结
通过将 C++ 标准从 `cxxflags` 中独立出来,我们实现了:
1.**配置更清晰** - `cxx_std` 专门用于标准版本
2.**更易维护** - 不需要在 `cxxflags` 中查找标准选项
3.**跨平台兼容** - 自动适配 MSVC 和 GCC/Clang 的标志
4.**灵活覆盖** - 命令行可以覆盖配置文件
5.**避免冲突** - 不会重复指定标准版本
希望这个指南能帮助您更好地使用 C++ 标准配置!