Clx:用C++20将Lua编译为原生可执行文件
速览
Clx通过C++20标准将Lua代码编译成原生可执行文件,无需额外运行时。它利用现代C++特性优化生成的二进制性能,并支持跨平台分发。该工具适合需要将Lua脚本打包为独立应用的场景,如游戏或嵌入式系统。
AI 深度解读
背景
Lua 是一种轻量、高效的脚本语言,广泛应用于游戏、嵌入式系统和配置脚本。然而,Lua 传统上以解释器或字节码虚拟机(如 LuaJIT)运行,虽然支持即时编译(JIT),但依然存在解释器开销、启动延迟以及分发时需依赖运行时环境等问题。随着对可部署、高性能可执行文件的需求增长,将 Lua 提前编译(AOT)为原生可执行文件的方案受到关注。Clx 正是这样一个跨平台项目,它通过现代 C++ 工具链(C++20)将 Lua 代码编译为独立的原生可执行文件,旨在提供可预测的性能、快速启动和集成性。
核心内容
Clx 是一个跨平台的提前编译(AOT)Lua 编译器与运行时,利用现代 C++ 工具链生成独立的原生可执行文件。它并不追求在所有工作负载下都成为最快的 Lua 实现,而是专注于以下目标:
- 提供提前编译生成原生代码
- 产出可部署的独立可执行文件
- 可预测的运行时性能
- 快速启动时间
- 与现有 C++ 工具链无缝集成
- 通过现代原生编译器获得强大的优化机会
快速开始
克隆仓库后执行构建脚本,编译一个示例 Lua 文件并运行:
git clone https://github.com/samyeyo/clx.git
cd clx
./build.sh install # Windows 下使用 build.bat install
clx examples/hello/hello.lua
./hello
Hello clx !
核心特性
- 在众多适合 AOT 的工作负载上具有竞争力的性能
- 无字节码解释器开销——直接编译为独立原生可执行文件
- 激进优化——借助 Clang/GCC/MSVC 的现代优化能力
- 二进制文件小巧——面向体积的构建可生成极紧凑的可执行文件(使用
--minimal标志,Lua 程序可小于 100KB) - 兼容 Lua 5.5——支持协程、元方法、表等特性
- 16 字节标记值(8 字节负载 + 独立类型标签)
- 内联字符串优化(≤6 字节的字符串直接存储在值中,无需分配内存)
- 快速路径表访问缓存
- 轻量级 AOT 运行时
- 提供 Clx C++ API:可以使用面向值的 API 开发可移植原生模块
示例
Clx 附带示例,包含一个使用 Sokol Clx 二进制模块的图形演示,展示如何用标准 Lua 代码开发原生桌面应用:
pong:完全用 Lua 编写并编译为独立原生可执行文件的游戏Mandelbrot:用 Lua 编写的 Mandelbrot 分形查看器,同样编译为独立原生可执行文件
当前状态
Clx 目前处于 Beta 阶段。编译器已能编译非平凡的 Lua 应用,但兼容性工作和优化改进仍在进行中。
支持的后端编译器
- Linux:
g++(推荐 TCO 支持)或clang++ - macOS:
clang++(Xcode)或通过 Homebrew 安装的g++(支持 TCO) - Windows:
g++(LLVM)或 MSVC - 需要 CMake 3.15+ 进行构建
注意:构建 clx 时使用的编译器会通过 CMake 固定,并用于所有 Lua 脚本编译,以确保运行时库与生成代码的 ABI 兼容。如需更换后端,请用不同编译器重新构建 clx。
构建命令
- POSIX:
./build.sh(Release)、./build.sh debug、./build.sh clean、./build.sh install、./build.sh uninstall - Windows:
./build.bat(Release)、./build.bat debug、./build.bat clean、./build.bat install、./build.bat uninstall - 也可直接使用 CMake:
mkdir -p build && cmake -S . -B build && cmake --build build
编译产物
构建后可在 build/ 目录找到:
clx:编译器可执行文件libclx.a:静态运行时库libclx_size.a:面向体积优化的静态运行时库
编译器用法
./build/clx file.lua:编译为可执行文件(默认标志)./build/clx --object file.lua:生成目标文件(.o/.obj)./build/clx --static file.lua:生成静态 clx 模块(.a/.lib)./build/clx --cpp file.lua:生成 C++ 源代码,不编译./build/clx file.lua -O2:将未知的 clx 标志转发给后端编译器./build/clx file.lua --output f.exe:自定义输出文件名./build/clx file.lua --debug:无优化,保留调试符号./build/clx file.lua --minimal:仅包含 base 和 package 模块./build/clx file.lua --fast:优化速度./build/clx file.lua --size:优化体积(默认)./build/clx --version:打印版本./build/clx --help:显示帮助
Lua 5.5 兼容性现状
- 核心语言:大部分已实现
- 表与元方法:已实现
- 协程:已实现
- 模块系统:已实现
- 多数标准库:已实现
详细状态参见compatibility.md。
未支持/不支持的功能: load()/dofile()/loadfile()/string.dump()—— 动态代码加载需要运行时解释器debug模块 —— 在纯 AOT 模型中非常复杂- 传统 Lua C API 不被支持,二进制模块应使用 clx C++ API 编写
测试
运行 ./tests/run.sh(POSIX)或 ./tests/run.bat(Windows)。每个 tests/ 下的 .lua 文件会被编译为二进制并执行,测试输出 [OK] 或 [FAIL] 断言。
性能基准
结果以相对于标准 Lua 5.5 解释器的加速倍数表示。测试环境:Intel® Core™ i5 Ultra 125U CPU @ 4.30GHz · Linux · GCC 13.3.0 · 10 次运行
