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.
 
 

6.4 KiB

C++ 标准配置指南

📋 概述

PHPX 编译器现在支持独立配置 C++ 标准版本,不再需要从 cxxflags 中提取。这使得配置更加清晰和易于管理。


🚀 使用方法

1. 命令行方式

使用 --cxx-std 参数指定 C++ 标准版本:

# 使用 C++14
php bin/compiler.php app.php --cxx-std=c++14

# 使用 C++17(默认)
php bin/compiler.php app.php --cxx-std=c++17

# 使用 C++20
php bin/compiler.php app.php --cxx-std=c++20

# Windows MSVC
php bin/compiler.php app.php --cxx-std=c++17

# Linux/macOS GCC/Clang
php bin/compiler.php app.php --cxx-std=c++17

2. project.yml 配置文件方式

project.yml 中添加 cxx_std 配置项:

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)

// CompilerBase.php
$this->cxxStd = 'c++17'; // MSVC 更好的支持 C++17

原因: MSVC 对 C++17 的支持更成熟,C++14 的部分特性在 MSVC 中实现不完整。


Linux/macOS (GCC/Clang)

// 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)

示例:

# project.yml
cxx_std: c++14
# 命令行覆盖配置文件
php bin/compiler.php project.yml --cxx-std=c++17
# 最终使用 c++17

注意事项

1. 不要在 cxxflags 中重复指定

错误做法:

cxx_std: c++17
cxxflags:
  - -std=c++17  # 重复指定!

正确做法:

cxx_std: c++17
cxxflags:
  - -Wall
  - -Wextra

2. cxxflags 中的标准会被忽略

如果 cxxflags 中包含了 -std=/std:,编译器会使用 $this->cxxStd 的值,而不是 cxxflags 中的值。

代码逻辑:

// 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:基本项目

# project.yml
name: hello-world
type: bin

sources:
  - src/main.php

cxx_std: c++17

编译命令:

php bin/compiler.php project.yml

生成的编译命令:

# Windows
cl /std:c++17 /O0 ... 

# Linux
g++ -std=c++17 -O0 ...

示例 2:带额外编译选项

# project.yml
name: my-app
type: bin

sources:
  - src/*.php

cxx_std: c++17

cxxflags:
  - -Wall
  - -Wextra
  - -Wpedantic

ldflags:
  - -lm
  - -lpthread

示例 3:命令行覆盖

# project.yml
name: my-app
cxx_std: c++14  # 配置文件中的默认值
# 使用 C++17 覆盖配置文件
php bin/compiler.php project.yml --cxx-std=c++17

🎯 迁移指南

如果您之前的 project.yml 中有这样的配置:

旧配置(不推荐)

cxxflags:
  - -std=c++17
  - -Wall
  - -O2

新配置(推荐)

cxx_std: c++17

cxxflags:
  - -Wall
  - -O2

优势:

  • 配置更清晰
  • 更容易维护
  • 跨平台兼容更好
  • 避免重复和冲突

🔍 验证方法

编译时查看输出,确认 C++ 标准是否正确设置:

php bin/compiler.php project.yml --verbose

应该看到类似这样的输出:

Compiling main.cc...
g++ -std=c++17 -O0 -Wall ...

或者 Windows:

cl /std:c++17 /O0 /Wall ...

🐛 常见问题

Q1: 为什么我的 C++17 特性不起作用?

A: 检查是否正确设置了 cxx_std

cxx_std: c++17  # 确保是 c++17 而不是 c++14

或者使用命令行:

php bin/compiler.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++ 标准从 cxxflags 中独立出来,我们实现了:

  1. 配置更清晰 - cxx_std 专门用于标准版本
  2. 更易维护 - 不需要在 cxxflags 中查找标准选项
  3. 跨平台兼容 - 自动适配 MSVC 和 GCC/Clang 的标志
  4. 灵活覆盖 - 命令行可以覆盖配置文件
  5. 避免冲突 - 不会重复指定标准版本

希望这个指南能帮助您更好地使用 C++ 标准配置!