You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:52:51