# 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++ 标准配置!