# Cargo 特性
## 你会学到什么
- 区分 Lua 版本特性、`vendored`、`module` 和 `gpu` 的作用。
- 知道默认构建为什么使用 vendored Lua 5.4,以及如何切换到其它 Lua。
- 避免 `cargo check --all-features` 造成的特性冲突误判。
- 为嵌入式、动态模块和不同 Lua 版本选择正确的验证命令。
## 适合谁读
准备集成、发布、打包或修 CI 的用户读本章。它也适合遇到 `mlua` 特性冲突、或想在 LuaJIT / Lua 5.1 等老版本上运行本 crate 时排查。
## 前置知识
- [嵌入 Lua](embedding-lua.md)
- [性能](../04-export/performance.md)
## 心智模型
`mlua-pulse` 的特性分三层:**Lua 运行时版本**、**Lua 获取方式**和**可选加速 / 模块导出**。版本特性是互斥的——每次只能启用一个 Lua 版本。Lua 获取方式决定是源码编译 Lua 还是从系统链接。最后两层是独立开关。
`Cargo.toml` 当前事实:
```toml
[dependencies.mlua]
version = "0.11.6"
default-features = false
[features]
default = ["lua54", "vendored"]
# Lua 运行时版本(互斥,请只启用一个)
lua51 = ["mlua/lua51"]
lua52 = ["mlua/lua52"]
lua53 = ["mlua/lua53"]
lua54 = ["mlua/lua54"]
lua55 = ["mlua/lua55"]
luajit = ["mlua/luajit"]
luajit52 = ["mlua/luajit52"]
luau = ["mlua/luau"]
vendored = ["mlua/vendored"]
module = ["mlua/module"]
gpu = ["tunes/gpu"]
```
因为 `mlua` 被设为 `default-features = false`,每次构建必须由本 crate 的版本特性提供一个 Lua 运行时,否则 `mlua` 会因为缺少 Lua 版本而报错。
## 最小可运行例子
默认嵌入式构建(Lua 5.4 + 源码编译):
```powershell
cargo build
cargo test
```
切换到 LuaJIT(仍从源码编译):
```powershell
cargo build --no-default-features --features luajit,vendored
```
动态 Lua 模块(Lua 5.3,链接宿主 Lua,不源码编译):
```powershell
cargo build --no-default-features --features lua53,module
```
GPU 请求:
```powershell
cargo run --release --features gpu --example foundation_loop
```
## 参数和边界
Lua 运行时版本(互斥,只能选一个):`lua51`、`lua52`、`lua53`、`lua54`、`lua55`、`luajit`、`luajit52`、`luau`。`luajit52` 是兼容 Lua 5.2 语义的 LuaJIT。`luau` 是 Roblox Luau 方言。
`vendored` 使用 `mlua/vendored`,让所选 Lua 版本从源码编译,适合 Rust 程序自带 Lua、不依赖宿主机器上安装系统 Lua 开发库。`module` 使用 `mlua/module`,把 crate 编译为动态 Lua 模块(cdylib),Lua 符号在运行时由加载它的外部 Lua 提供,因此模块构建**不要**同时开 `vendored`。`gpu` 启用 `tunes/gpu`,让导出选项里的 `{ gpu = true }` 可以请求 GPU 路径。
不要使用 `cargo check --all-features`。`mlua` 的多个 Lua 版本、模块和 vendored 场景不能用一个 all-features 命令粗暴合并,Cargo 特性没有"互斥"机制,同时启用多个 Lua 版本会导致符号冲突。
## 常见陷阱
`cargo check --no-default-features --features module` 会失败,因为没有提供 Lua 版本。模块构建必须带上一个版本特性,例如 `--features lua54,module`。
`module` 和 `vendored` 同时启用在多数平台上会冲突:vendored 会把 Lua 静态链接进 cdylib,而 module 要求符号来自宿主。模块构建应省略 `vendored`,让宿主 Lua 提供符号。
未启用 `gpu` 特性却在 Lua 里传 `{ gpu = true }`,会得到 `gpu feature is not enabled`。这比静默回退更清楚。
不要把 `gpu` 当作音质开关。它是计算路径请求,不改变编曲语义。
## 进阶用法
推荐 CI 按组合分开跑:默认 `cargo test` 覆盖 Lua 5.4 嵌入式路径;对需要支持的每个 Lua 版本单独 `cargo check --no-default-features --features <版本>,vendored`;单独 `cargo check --no-default-features --features lua54,module` 覆盖模块构建;单独 `cargo check --features gpu` 覆盖 GPU 特性编译。文档和示例不要写 `--all-features`。
发布二进制宿主时,优先默认的 `lua54,vendored`,减少用户机器对系统 Lua 的依赖。需要 LuaJIT 性能或老项目兼容 Lua 5.1 时,切换版本特性即可。发布 Lua 动态模块时,针对目标 Lua 版本和平台配置 `module`,并确保宿主已安装对应 Lua。
## 相关章节
- [性能](../04-export/performance.md)
- [嵌入 Lua](embedding-lua.md)
- [错误处理](error-handling.md)
- [README](https://github.com/limao996/mlua-pulse/blob/master/README.md)