DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

程序找不到 OUT_DIR

Rust 程序依赖运行时 OUT_DIR,只在 cargo run 下成功,可能来自 Cargo 的构建环境泄漏。区分编译期嵌入与外部资源部署,不把构建机路径当运行契约。

Rust 程序通过 cargo run 能读到 OUT_DIR,复制二进制后直接启动却报环境变量不存在,或者找不到生成文件。先区分构建目录与应用运行目录:OUT_DIR 是 Cargo 给构建脚本和编译过程提供的位置,不是部署后的资源发现协议。

cargo run 的成功可能来自泄漏

Cargo 从 1.77 起有一条意外行为:构建脚本的环境被传到运行应用的进程,OUT_DIR 也随之出现。核对 Rust 1.99 正式工具链所携带的 Cargo 源码,仍能看到这条转发路径;不能据此要求直接运行的二进制也拥有该变量。

相关修复已合并并列入后续 1.101.0,当前 1.99 不能写成已经移除泄漏。升级后依赖这份偶然环境的程序也需要调整,不只是部署脚本补一个值。

构建脚本内部使用 std::env::var("OUT_DIR") 是正常用途,不要全项目搜索后全部替换。要改的是应用运行时把它当业务配置的用法。

生成资源是否适合嵌入

编译时生成、随二进制固定的内容,可以在编译期纳入产物。例如构建脚本已经在 OUT_DIR 生成 config.bin,且内容适合公开随程序分发时:

static CONFIG: &[u8] =
    include_bytes!(concat!(env!("OUT_DIR"), "/config.bin"));

这会嵌入文件字节,运行时不再打开构建机上的路径。相反,仅用 env!("OUT_DIR") 把绝对路径存成字符串,仍不能保证部署机器上存在那个目录。

嵌入会增加二进制内容,并使资源更新需要重新构建;密钥、运行期可修改的配置或大量外部数据不应为了省一个路径问题塞进二进制。生成 Rust 代码的场景也要按其原有 include! 编译关系处理,不能把代码文件当普通运行时配置。

外部文件按部署契约提供

确实需要外部资源时,把文件随发布包放到明确位置,由应用的参数或专用配置项指定;不要把开发机 target/.../build/.../out 路径硬编码到生产。可写数据目录和只读程序资源也应分开。

验证时用实际发布包、实际工作目录和启动环境直接运行二进制,确认它不依赖 Cargo 注入的 OUT_DIR。还要检查资源完整性及更新方式,而不是只确认环境变量从报错中消失。若资源与程序必须配套,回退也恢复相容的整组产物。