为什么Rust的Cargo会二次重编译部分包?两次构建产物是否一致?
问题解答
1. 二次重编译的原因
该现象不是memchr等第三方包的故障,根本原因是通过环境变量RUSTFLAGS全局传入链接器参数的配置方式,触发了Cargo的缓存校验规则变更。
Cargo的构建缓存会绑定完整的编译上下文配置:
- 首次编译时,Cargo会同时编译适配Host架构的公共依赖(用于支撑编译期执行的过程宏、build.rs构建逻辑等)和适配目标armv7架构的依赖、业务项目,此时缓存的配置不包含你额外传入的链接器参数
- 第二次编译时,Cargo检测到全局
RUSTFLAGS传入的链接器配置变更,会重新编译所有受链接参数影响的依赖包(memchr、aho-corasick、regex这类底层库的编译结果会受链接配置影响),完成编译后缓存的配置才和实际传入的参数完全匹配 - 第三次编译时所有配置与缓存一致,因此无需重新编译
你对配置逻辑的猜测是正确的,交叉编译的链接器不属于目标架构的默认内置配置,你可以将链接器配置写入Cargo的本地配置文件,替代全局RUSTFLAGS传参即可避免重复编译,操作方式如下:
在项目根目录创建.cargo/config.toml文件,添加如下配置:
[target.armv7-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc"
修改后删除build.sh脚本里的RUSTFLAGS环境变量配置即可。
2. 两次构建产物的一致性
第一次和第二次的构建产物不完全一致,不可互用。
第一次的产物未应用你指定的交叉编译链接器参数,第二次的产物才是完全符合你配置要求的输出,最终使用的可执行文件请以第二次及之后无重新编译动作的构建产出为准。
内容的提问来源于stack exchange,提问作者maloo
相关产品推荐
相关产品推荐

