如何在Rust库中捕获依赖它的二进制目标编译时的CARGO_PKG_NAME?
可行的实现方案
要获取依赖你的库的二进制目标名称,核心是让二进制项目在编译阶段将自身的CARGO_PKG_NAME传递给库,以下是两种可靠的实现方式:
方式一:通过构建脚本传递编译时参数
- 在库的
build.rs中接收外部传入的二进制名称,并生成可供库代码使用的常量:// 库的build.rs use std::env; use std::fs::File; use std::io::Write; use std::path::Path; fn main() { // 获取二进制项目传递的名称,以库自身名称作为默认 fallback let bin_name = env::var("BIN_PKG_NAME").unwrap_or_else(|_| env!("CARGO_PKG_NAME").to_string()); // 将名称写入编译输出目录的文件中 let out_dir = env::var("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("bin_name.rs"); File::create(&dest_path) .unwrap() .write_all(format!("pub const BIN_NAME: &str = \"{}\";", bin_name).as_bytes()) .unwrap(); } - 在库的
lib.rs中引入生成的常量:// 库的lib.rs include!(concat!(env!("OUT_DIR"), "/bin_name.rs")); pub fn get_binary_name() -> &'static str { BIN_NAME } - 依赖该库的二进制项目,在自身
build.rs中传递环境变量:// 二进制项目的build.rs use std::env; fn main() { // 将自身的CARGO_PKG_NAME传递给依赖的库 println!("cargo:rustc-env=BIN_PKG_NAME={}", env!("CARGO_PKG_NAME")); }
方式二:通过特征(Trait)让二进制项目主动提供名称
定义特征要求二进制项目实现并返回自身名称,库通过特征获取信息:
- 库中定义特征:
// 库的lib.rs pub trait BinaryNameProvider { fn binary_name() -> &'static str; } pub fn get_binary_name<P: BinaryNameProvider>() -> &'static str { P::binary_name() } - 二进制项目中实现该特征:
// 二进制项目的main.rs use your_library::{BinaryNameProvider, get_binary_name}; struct AppBinary; impl BinaryNameProvider for AppBinary { fn binary_name() -> &'static str { env!("CARGO_PKG_NAME") } } fn main() { println!("Binary name: {}", get_binary_name::<AppBinary>()); }
两种方式各有特点:
- 方式一无需二进制项目编写额外特征实现,仅需配置
build.rs,侵入性低; - 方式二更灵活,二进制项目可自定义返回的名称,不局限于
CARGO_PKG_NAME。
内容的提问来源于stack exchange,提问作者dpr
相关产品推荐
相关产品推荐

