如何在build.rs中识别当前编译的Cargo目标?
问题描述
我在Cargo.toml中配置了两个二进制目标:
bin = [ { name = "first", path = "bin/first.rs" }, { name = "second", path = "bin/second.rs" }, ] [lib] name = "some_lib" crate-type = [ "cdylib", "rlib", ] [target."cfg(windows)".build-dependencies] winresource = "0.1"
编译后会生成first.exe和second.exe两个可执行文件。为给Windows平台的可执行文件设置自定义图标,我编写了如下build.rs脚本:
use std::io; #[cfg(windows)] use winresource::WindowsResource; fn main() -> io::Result<()> { println!("cargo:rerun-if-changed=build.rs"); #[cfg(windows)] { WindowsResource::new() // 路径可以是绝对路径,也可以是相对于 crate 根目录的路径 .set_icon("icon_for_first.ico") .compile()?; } Ok(()) }
但该脚本会将图标应用到所有可执行文件,而非仅first.exe。请问是否有办法在build.rs中检查当前正在编译的目标?
解决方案
Cargo在执行build.rs时会通过环境变量传递当前编译的目标信息,你可以读取CARGO_BIN_NAME环境变量来判断当前编译的二进制目标名称,从而仅为指定目标设置图标。
修改后的build.rs脚本如下:
use std::env; use std::io; #[cfg(windows)] use winresource::WindowsResource; fn main() -> io::Result<()> { println!("cargo:rerun-if-changed=build.rs"); #[cfg(windows)] { // 获取当前编译的二进制目标名称 if let Some(bin_name) = env::var_os("CARGO_BIN_NAME") { // 仅为名为"first"的二进制目标设置图标 if bin_name == "first" { WindowsResource::new() .set_icon("icon_for_first.ico") .compile()?; } // 如需为其他目标设置图标,可添加额外分支 // else if bin_name == "second" { // WindowsResource::new().set_icon("icon_for_second.ico").compile()?; // } } } Ok(()) }
关键说明
CARGO_BIN_NAME仅在编译二进制目标时存在,编译库目标时不会设置该变量,因此不会影响你的some_lib库编译。- 若需要为多个二进制目标设置不同图标,只需添加对应的条件分支即可。
内容的提问来源于stack exchange,提问作者Star
相关产品推荐
相关产品推荐

