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.
 
 

21 KiB

AOT 编译器命令行工具使用指南

📋 概述

PHP AOT 编译器是一个强大的命令行工具,可以将 PHP 源代码编译为原生可执行文件或 PHP 扩展。它支持多种编译选项、优化级别和构建模式。


🚀 快速开始

基本用法

# 编译单个 PHP 文件
./bin/compiler.php examples/hello.php

# 编译目录
./bin/compiler.php examples/myapp/

# 带优化编译
./bin/compiler.php examples/bench.php -O2

# 生成扩展
./bin/compiler.php my_extension/ -m ext -o myext

📖 命令格式

./bin/compiler.php <file/dir> [options]

参数说明

参数 说明 必需
<file> 要编译的 PHP 文件或目录

命令行选项详解

1. -O <level> - 优化级别

别名: --optimize
默认值: 0
取值范围: 0-3

控制 GCC 编译器的优化级别,影响生成代码的性能和大小。

级别 说明 适用场景
-O0 无优化,调试模式 开发调试
-O1 基础优化 一般用途
-O2 标准优化(推荐) 生产环境
-O3 激进优化 性能关键应用

示例:

# 无优化编译
./bin/compiler.php app.php -O0

# 标准优化
./bin/compiler.php app.php -O2

# 最大优化
./bin/compiler.php app.php -O3

2. -m <mode> / --mode <mode> - 编译模式

默认值: bin
可选值: bin, ext

指定编译输出类型:可执行文件或 PHP 扩展。

🔹 bin 模式(二进制)

生成独立的可执行文件,无需 PHP 环境即可运行。

特点:

  • 需要 main() 函数作为入口
  • 包含完整的运行时环境
  • 可直接在命令行执行
  • 不能作为 PHP 扩展加载

示例:

./bin/compiler.php myapp/ -m bin -o myapp
./myapp  # 直接运行

🔸 ext 模式(扩展)

生成 PHP 扩展(.so/.dll),需要在 PHP 环境中运行。

特点:

  • 不需要 main() 函数
  • 可以作为模块加载到 PHP
  • 支持与现有 PHP 代码集成
  • 需要 PHP 环境

示例:

./bin/compiler.php myext/ -m ext -o myext
# 在 php.ini 中添加
extension=myext

3. -o <file> / --output <file> - 输出文件名

别名: --output
默认值: 输入文件的基本名

指定生成的可执行文件或扩展的名称。

命名规则:

  • 只能包含字母、数字和下划线
  • 不能包含连字符(-)或星号(*
  • 不能是 C++ 保留关键字
  • 不能与现有目录同名

示例:

# 自定义输出名称
./bin/compiler.php app.php -o my_application

# 带连字符的名称会自动转换
./bin/compiler.php my-app.php -o my_app  # ✅ 正确
./bin/compiler.php my-app.php -o my-app  # ❌ 错误,会转换为 my_app

4. -j <num> / --job <num> - 并行编译任务数

默认值: 4

控制编译过程中并行处理的任务数量,影响编译速度。

建议配置:

  • 单核 CPU: -j 1
  • 双核 CPU: -j 2
  • 四核 CPU: -j 4 (默认)
  • 八核及以上: -j 8 或更高

示例:

# 单线程编译(适合调试)
./bin/compiler.php large_project/ -j 1

# 多线程编译(适合生产)
./bin/compiler.php large_project/ -j 8

5. -v / --verbose - 详细输出

别名: --verbose
类型: 开关(无参数)

启用详细输出模式,显示编译过程的详细信息。

输出内容:

  • 每个文件的处理状态
  • 跳过不支持语法的通知
  • 编译进度信息
  • 生成的中间文件路径

示例:

./bin/compiler.php app.php -v

# 输出示例:
# prepare: /path/to/app.php
# generate stub file: /path/to/app.php
# convert: /path/to/app.php
# format: /path/to/build/app.cpp
# Starting parallel compilation with 4 jobs for 5 files
# Successfully compiled 5 files

6. -f / --force - 强制编译

别名: --force
类型: 开关

即使缓存存在也强制重新编译。

使用场景:

  • 修改了底层 C++ 代码
  • 怀疑缓存有问题
  • 需要完全重新编译

示例:

# 强制重新编译
./bin/compiler.php app.php -f

# 结合优化使用
./bin/compiler.php app.php -O2 -f

7. -p / --profile - 性能分析

别名: --profile
类型: 开关

启用性能分析功能,生成可用于性能分析的可执行文件。

输出内容:

  • 函数执行时间统计
  • 内存使用情况
  • 调用次数统计

示例:

# 编译带性能分析的版本
./bin/compiler.php benchmark.php -p -O2

# 运行后会生成性能报告
./benchmark
cat benchmark.prof

8. --no-literal-strings - 禁用字符串优化

类型: 开关

禁用字面量字符串优化,所有字符串将在运行时动态创建。

默认行为:

  • 字符串常量会被提取到全局数组
  • 减少重复字符串的内存占用
  • 提高字符串比较性能

禁用后的影响:

  • 增加内存使用
  • 降低字符串操作性能
  • 可能减少编译时间

示例:

# 禁用字符串优化
./bin/compiler.php app.php --no-literal-strings

9. --debug-line - 启用调试行

默认值: 0

在生成的 C++ 代码中包含源文件行号信息,用于调试。

示例:

# 启用调试行信息
./bin/compiler.php app.php --debug-line 1

10. --debug - 启用调试模式

类型: 开关

启用详细的调试信息输出。

示例:

# 启用调试信息
./bin/compiler.php app.php --debug

11. -h / --help - 显示帮助

类型: 开关

显示帮助信息和所有可用选项。

示例:

./bin/compiler.php -h

输出:

PHP AOT Compiler v1.0.0

USAGE:
    ./bin/compiler.php <file/dir> [options]

ARGUMENTS:
    <file>    Input PHP file/directory to compile

OPTIONS:
    -O <level>           Optimization level (0-3, default: 0)
    -p, --profile        Enable performance profiling
    -o, --output <file>  Output binary name (default: input basename)
    -v, --verbose        Verbose output
    -h, --help           Show this help message
    -f, --force          Force compile even if cache exists
    -m, --mode <mode>    Compilation mode, -m bin(binary) or -m ext(extension), default: bin
    -j, --job <num>      Number of parallel compilation jobs (default: 4)
    --no-literal-strings Disable literal strings optimization
    -I, --include-path   Add an additional C++ include directory (repeatable)
    -D, --define <macro> Define a preprocessor macro (repeatable, e.g. -D FOO=bar)
    --dry                Dry run: only generate C++ code, skip compilation and linking
    --lto                Enable Link Time Optimization (-flto)
    --format             Enable clang-format code formatting (disabled by default)
    --cxx-std <ver>      C++ standard version (c++17, c++20, etc., default: c++17)
    --march <arch>       Target CPU instruction set (e.g. native, x86-64-v3, armv8-a)
    -l, --link-lib <lib> Link against a library (repeatable, e.g. -lcurl)
    -L, --link-path <dir> Add a library search path (repeatable, e.g. -L/usr/local/lib)
    --build-dir <dir>    Specify build directory for generated C++ code

EXAMPLES:
    ./bin/compiler.php examples/hello.php
    ./bin/compiler.php examples/bench.php -O2
    ./bin/compiler.php examples/bench.php -O2 
    ./bin/compiler.php examples/extension -O2 -o myapp -m ext
    ./bin/compiler.php examples/app.php -O3 -o myapp -v

🎯 典型使用场景

场景一:开发环境调试

# 无优化,启用详细输出,单线程
./bin/compiler.php src/app.php -O0 -v -j 1

场景二:生产环境部署

# 标准优化,多线程编译
./bin/compiler.php src/app.php -O2 -j 8

场景三:性能关键应用

# 最大优化,启用性能分析
./bin/compiler.php benchmark.php -O3 -p

场景四:构建 PHP 扩展

# 生成扩展模块
./bin/compiler.php extension_src/ -m ext -o myext -O2

场景五:大型项目

# 使用配置文件,多目录编译
./bin/compiler.php project.yml -O2 -j 16 -v

场景六:使用外部 C++ 库

# 添加自定义头文件路径和预处理器宏
./bin/compiler.php app.php -I /opt/mylib/include -I ../shared/include -D MY_DEBUG=1 -O2

12. -I <dir> / --include-path <dir> - 添加头文件搜索路径

别名: --include-path
类型: 可重复参数

添加额外的 C++ 头文件(.h / .hpp)搜索目录。编译器的 include 路径由两部分组成:

  1. 系统默认路径(PHP 头文件、PHPX 头文件等)
  2. 用户通过 -I 指定的自定义路径

适用场景:

  • 引用外部 C/C++ 库的头文件
  • 项目有自定义的 C++ 扩展代码
  • 多个项目共享的头文件目录

可重复使用: 可以多次指定 -I 添加多个目录:

./bin/compiler.php app.php \
    -I /opt/openssl/include \
    -I /opt/mylib/include \
    -I ../shared/headers

与 C++ 编译器等价: -I <dir> 直接传递给 GCC/Clang/MSVC 的 -I 选项。


13. -D <macro> / --define <macro> - 定义预处理器宏

别名: --define
类型: 可重复参数

定义 C++ 预处理器宏,等价于在 C++ 代码中使用 #define。使用 name=value 格式。

适用场景:

  • 条件编译(#ifdef MY_FEATURE / #ifndef MY_FEATURE
  • 功能开关(-D ENABLE_LOGGING=1
  • 调试标志(-D DEBUG_LEVEL=3
  • 版本号定义(-D APP_VERSION=\"2.0\"

格式说明:

格式 等价 C++ 代码 说明
-D FOO #define FOO 无值宏(值为空)
-D FOO=1 #define FOO 1 整数值宏
-D FOO=bar #define FOO bar 字符串值宏
-D FOO=\"bar\" #define FOO "bar" 引号字符串宏

可重复使用: 可以多次指定 -D 定义多个宏:

./bin/compiler.php app.php \
    -D MY_DEBUG=1 \
    -D LOG_LEVEL=3 \
    -D APP_NAME=\\"MyApp\"

与 C++ 编译器等价:

编译器 产生的编译标志
GCC / Clang -D<macro>
MSVC /D<macro>

示例: 条件编译控制功能开关:

# 启用调试日志
./bin/compiler.php app.php -D ENABLE_LOGGING=1 -O2

# 生产环境(关闭调试)
./bin/compiler.php app.php -O2

14. --lto - 链接时优化

类型: 开关(无参数)

启用链接时优化(Link Time Optimization, LTO),允许编译器在链接阶段跨编译单元进行优化,可显著提升运行时性能和减小二进制体积。

编译器适配:

编译器 编译阶段标志 链接阶段标志
GCC -flto -flto
Clang -flto -flto
MSVC /GL /LTCG

适用场景:

  • 生产环境部署(配合 -O2-O3
  • 对性能有极致要求的应用
  • 需要减小二进制体积的场景
  • 会增加链接时间

示例:

# 启用 LTO 的生产环境编译
./bin/compiler.php app.php -O2 --lto

# 与自定义 include 和 define 组合使用
./bin/compiler.php app.php -O3 --lto -I /opt/lib/include -D NDEBUG=1

15. --format - 代码格式化

类型: 开关(无参数)
默认: 关闭

启用 clang-format 对生成的 C++ 代码进行自动格式化。由于格式化会增加编译时间,默认关闭。需要系统中安装了 clang-format 才能生效。

适用场景:

  • 需要审查生成的 C++ 代码
  • 团队开发需要统一的代码风格
  • 会增加编译时间

示例:

# 编译时启用代码格式化
./bin/compiler.php app.php --format

# 结合优化使用
./bin/compiler.php app.php -O2 --format

如果系统未安装 clang-format,使用 --format 时会显示警告并跳过格式化。


别名: --link-lib
类型: 可重复参数

指定要链接的库,等价于 GCC/Clang 的 -l<lib> 选项。实际产生的标志为 -l<lib>

适用场景:

  • 链接第三方 C/C++ 库(如 -lcurl-lssl
  • 链接自定义编译的静态库/动态库
  • 多库依赖的项目

可重复使用: 可以多次指定 -l 链接多个库:

./bin/compiler.php app.php \
    -lcurl \
    -lssl \
    -lcrypto

# 等价的长格式
./bin/compiler.php app.php --link-lib curl --link-lib ssl --link-lib crypto

与 GCC/Clang 等价: -l<lib> 直接传递给链接器的 -l 选项,链接 lib<lib>.solib<lib>.a


别名: --link-path
类型: 可重复参数

添加库文件搜索路径,等价于 GCC/Clang 的 -L<dir> 选项。实际产生的标志为 -L<dir>

适用场景:

  • 链接非标准路径下的库文件
  • 使用自定义编译的本地库
  • 链接项目内部的私有库

可重复使用: 可以多次指定 -L 添加多个搜索路径:

./bin/compiler.php app.php \
    -L/usr/local/lib \
    -L/opt/custom/lib \
    -lmycustom

# 等价的长格式
./bin/compiler.php app.php --link-path /usr/local/lib --link-path /opt/custom/lib --link-lib mycustom

与 GCC/Clang 等价: -L<dir> 直接传递给链接器的 -L 选项。


18. --march <arch> - 目标 CPU 指令集

类型: 单值参数

指定编译器生成针对特定 CPU 架构优化的代码。等价于 GCC/Clang 的 -march=<arch> 选项。

常用值:

说明
native 自动检测并优化当前 CPU 支持的指令集
x86-64-v3 x86-64 微架构级别 3 (AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE)
x86-64-v4 x86-64 微架构级别 4 (AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL)
armv8-a ARMv8-A 基础架构
armv8.1-a ARMv8.1-A
armv8.2-a ARMv8.2-A
armv9-a ARMv9-A

注意: --march 仅适用于 GCC/Clang 编译器。MSVC 不支持此选项,请使用 --cxx-flags /arch:AVX2 等方式。

示例:

# 优化当前机器运行的 CPU
./bin/compiler.php app.php --march=native -O2

# 特定目标架构
./bin/compiler.php app.php --march=x86-64-v3 -O2

# ARM 平台
./bin/compiler.php app.php --march=armv8-a -O2

与 GCC/Clang 等价: --march=<arch> 直接传递给编译器的 -march=<arch> 选项。


🔧 编译器选择

默认编译器

编译器会根据操作系统自动选择合适的 C++ 编译器:

平台 默认编译器 说明
macOS clang++ 系统自带,性能优秀
Linux g++ GNU 编译器集合
Windows cl (MSVC) Microsoft Visual C++

通过环境变量切换编译器

你可以通过设置环境变量来覆盖默认的编译器选择。

方法一:PHPX_CC(推荐)

# macOS 使用 GCC(如果已安装)
export PHPX_CC=g++
php bin/compiler.php examples/hello.php

# Linux 使用 Clang
export PHPX_CC=clang++
php bin/compiler.php examples/hello.php

# Windows 使用 Clang
set PHPX_CC=clang++
php bin\compiler.php examples\hello.php

方法二:CXX(标准环境变量)

# 使用标准的 CXX 环境变量
export CXX=clang++
php bin/compiler.php examples/hello.php

优先级PHPX_CC > CXX > 平台默认

通过配置文件指定编译器

在项目 YAML 配置文件中,可以使用 cpp-compiler 选项指定编译器:

name: myapp
type: bin
cpp-compiler: clang++  # 或 g++, cl
sources:
  - src/*.php

支持的编译器名称:

  • clang++ / clang - LLVM Clang 编译器
  • g++ / gcc - GNU GCC 编译器
  • cl / msvc - Microsoft Visual C++(仅 Windows)

检查当前使用的编译器

编译时会显示使用的编译器信息:

$ php bin/compiler.php examples/hello.php
Initialized new architecture: macOS + Clang
prepare: examples/hello.php
prepare completed: 1 source files in total
...

📁 支持的输入类型

1. 单个 PHP 文件

./bin/compiler.php hello.php

2. 目录

./bin/compiler.php src/

编译器会自动扫描目录下所有的 .php 文件。

3. YAML 配置文件

./bin/compiler.php project.yml

project.yml 示例:

name: myapp
type: bin
sources:
  - src/*.php
  - lib/**/*.php
  - main.php

🔧 编译过程详解

阶段一:预处理 (Prepare)

prepare: /path/to/file.php
  • 解析 PHP 文件
  • 检查语法错误
  • 检测不支持的语法
  • 生成抽象语法树 (AST)

阶段二:生成存根文件 (Generate Stub)

generate stub file: /path/to/file.php
  • 生成 .stub.php 文件
  • 提取函数声明
  • 生成参数信息头文件

阶段三:转换为 C++ (Convert)

convert: /path/to/file.php
  • 将 PHP AST 转换为 C++ 代码
  • 生成对应的 .cpp 文件
  • 处理类型映射

阶段四:格式化 (Format)(需 --format 开启)

format: /path/to/build/file.cpp
cd /path && clang-format -i /path/to/build/file.cpp
  • 🔘--format 参数显式开启
  • 使用 clang-format 格式化 C++ 代码
  • 确保代码风格一致

阶段五:并行编译 (Parallel Compilation)

Starting parallel compilation with 4 jobs for 5 files
Successfully compiled 5 files
  • 使用多个进程并行编译 C++ 文件
  • 生成目标文件 (.o)
g++ ... -o app ...
  • 链接所有目标文件
  • 链接 PHPX 库和 PHP 库
  • 生成最终可执行文件

性能优化技巧

1. 选择合适的优化级别

# 开发阶段:快速编译
-O0

# 测试阶段:平衡编译时间和性能
-O1

# 生产阶段:最大化性能
-O2 或 -O3

2. 调整并行任务数

根据 CPU 核心数调整:

# 查看 CPU 核心数
nproc

# 设置为 CPU 核心数的 1.5 倍
-j $(($(nproc) * 3 / 2))

3. 使用缓存

编译器会自动缓存已编译的文件,下次编译时会跳过未更改的文件。

# 第一次编译(慢)
./bin/compiler.php app.php

# 第二次编译(快,使用缓存)
./bin/compiler.php app.php

# 强制重新编译
./bin/compiler.php app.php -f

🐛 故障排除

问题一:编译失败 "No valid source file found"

原因: 没有找到有效的 PHP 文件

解决方法:

# 检查文件路径是否正确
ls -la your_file.php

# 使用绝对路径
./bin/compiler.php /absolute/path/to/file.php

问题二:类名冲突

原因: 输出名称与现有类名冲突

解决方法:

# 使用不同的输出名称
./bin/compiler.php app.php -o myapp_binary

问题三:内存不足

原因: 并行任务数过多导致内存耗尽

解决方法:

# 减少并行任务数
./bin/compiler.php large_project.php -j 2

问题四:不支持的语法

原因: 使用了 AOT 编译器不支持的 PHP 语法

输出示例:

unsupported syntax: Dynamic property creation is not supported
skip: /path/to/file.php

解决方法:

  1. 查看 UNSUPPORTED_SYNTAX.md
  2. 修改代码使用支持的语法
  3. 或将代码封装到函数中

📊 编译选项组合示例

示例组合

# 快速开发构建
./bin/compiler.php app.php -O0 -j 1

# 标准生产构建
./bin/compiler.php app.php -O2 -j 8 -v

# 高性能构建
./bin/compiler.php app.php -O3 -j 16 -p

# 外部库集成构建
./bin/compiler.php app.php -I /opt/mylib/include -D ENABLE_FEATURE=1 -O2

# 调试构建
./bin/compiler.php app.php -O0 -v --debug

# 扩展构建
./bin/compiler.php ext/ -m ext -o myext -O2 -v

📝 最佳实践

1. 开发环境

# 使用脚本自动化
#!/bin/bash
./bin/compiler.php src/app.php -O0 -v -j 1

2. CI/CD 流水线

# 持续集成
./bin/compiler.php tests/ -O2 -j $(nproc) -v

3. 生产部署

# 生产环境
./bin/compiler.php release/app.php \
    -O2 \
    -j $(nproc) \
    -o app \
    -v \
    --force

4. 性能测试

# 基准测试
./bin/compiler.php benchmark.php -O3 -p -o benchmark_optimized

🎓 高级主题

1. 自定义编译流程

可以通过修改 src/config/compiler_options.php 添加自定义选项。

2. 扩展编译器

实现自定义的 Preprocessor 或 Translator 来扩展编译器功能。

3. 性能调优

分析编译过程中的瓶颈:

time ./bin/compiler.php large_project.php -v

📚 相关资源


最后更新: 2024 年 3 月 19 日
适用版本: PHP AOT Compiler v1.0.0