如何为不同平台指定不同的Cargo二进制文件名?
解决Cargo跨平台二进制文件名差异问题
我希望通过cargo install安装工具时,Linux平台生成的二进制文件名为termcalc,其他平台使用tc——因为Linux系统自带/usr/sbin/tc工具,避免命名冲突,Linux用户可以通过alias tc=termcalc或者直接调用termcalc使用。但之前的配置无法生效:
[[target.'cfg(not(linux))'.bin]] name = "tc" path = "src/bin.rs" [[target.'cfg(linux)'.bin]] name = "termcalc" path = "src/bin.rs"
问题原因
Cargo的[[target]]配置块只支持具体的目标三元组(比如x86_64-unknown-linux-gnu),不支持直接用cfg()条件表达式,所以你写的cfg(not(linux))和cfg(linux)不会被正确解析,导致配置失效。
解决方案
方案1:用build.rs动态修改二进制名称(推荐)
这是最简洁的方法,不需要拆分文件:
- 在项目根目录创建
build.rs文件,写入以下代码:
fn main() { let bin_name = if cfg!(target_os = "linux") { "termcalc" } else { "tc" }; println!("cargo:rustc-bin-name={}", bin_name); }
- 修改
Cargo.toml,只保留一个通用的[[bin]]块:
[[bin]] name = "tc" # 默认名称,会被build.rs覆盖 path = "src/bin.rs"
执行cargo build或cargo install时,build.rs会根据目标系统自动替换二进制文件名:Linux下生成termcalc,其他平台生成tc。
方案2:拆分不同平台的入口文件
如果不想用build.rs,可以创建两个入口文件,通过条件编译选择:
在
src目录下创建两个文件:src/tc.rs:内容和原src/bin.rs完全一致,用于非Linux平台src/termcalc.rs:内容和原src/bin.rs完全一致,用于Linux平台
修改
Cargo.toml添加带条件的[[bin]]块:
[[bin]] name = "tc" path = "src/tc.rs" required-features = ["not-linux"] [[bin]] name = "termcalc" path = "src/termcalc.rs" required-features = ["linux"] [features] linux = [] not-linux = []
- 同样需要创建
build.rs来根据平台启用对应feature:
fn main() { if cfg!(target_os = "linux") { println!("cargo:rustc-cfg=feature=\"linux\""); } else { println!("cargo:rustc-cfg=feature=\"not-linux\""); } }
这个方法需要维护两份相同的入口代码,不如方案1高效,优先推荐方案1。
内容的提问来源于stack exchange,提问作者Rtbo
相关产品推荐
相关产品推荐

