为什么过程宏在我的构建脚本中看不到 dotenv 设置的环境变量?
Why does a procedural macro not see environment variables set by dotenv in my build script?
我有一个程序宏包 Proc
和二进制包 Bin
。 Bin
依赖于 Proc
。 Proc
需要填充的环境变量才能正常运行。
这是我在 Bin
中的 build.rs
中的一些代码。 Proc
使用以下代码可以成功找到env值:
fn main() {
println!("cargo:rustc-env=SOME_ENV_VALUE=somevalue");
}
然而,Proc
在 Bin
中的 build.rs
中使用此代码时无法找到环境变量(注意:在 dotenv
之后检查是否存在时打电话,我可以验证密钥是否确实存在):
fn main() {
dotenv::dotenv().unwrap();
}
这是我的 Proc
箱子:
use proc_macro::TokenStream;
#[proc_macro_derive(MyProcMacro)]
pub fn my_proc_macro(input: TokenStream) -> TokenStream {
if std::env::var("SOME_ENV_VALUE").is_err() {
panic!("Failed to retrieve env value")
}
TokenStream::new()
}
为什么 println!
命令不会失败?它可以与 dotenv
一起使用吗?否则我需要编写一些代码,将密钥从我的 env
文件复制到 println!
命令...
所有代码都在我的minimal reproduction project.
我鼓励您重新阅读 Build Scripts chapter of the Cargo docs。构建脚本是一个 单独的可执行文件,Cargo 在开始构建源代码之前构建并执行。
- 货运开始
- Cargo 执行
rustc
构建构建脚本
- Cargo 执行构建脚本
- Cargo 执行
rustc
来构建您的代码
- 货物出口
[dotenv] loads environment variables from a .env file, if available, and mashes those with the actual environment variables provided by the operating system.
它加载的变量被放入当前进程环境变量中。在您的示例中,这是构建脚本可执行文件。
[cargo:rustc-env
] tells Cargo to set the given environment variable when compiling the package
构建脚本的标准输出与 Cargo 交互,然后修改代码的编译方式,包括要设置的环境变量。
您需要加载dotenv文件和设置环境变量以便后续编译。像这个编译但未经测试的例子:
fn main() {
if let Ok(env) = dotenv::dotenv_iter() {
for (k,v) in env.flatten() {
println!("cargo:rustc-env={}={}", k, v);
}
}
}
不用担心此方法已被标记为已弃用。维护者 changed their minds.
我有一个程序宏包 Proc
和二进制包 Bin
。 Bin
依赖于 Proc
。 Proc
需要填充的环境变量才能正常运行。
这是我在 Bin
中的 build.rs
中的一些代码。 Proc
使用以下代码可以成功找到env值:
fn main() {
println!("cargo:rustc-env=SOME_ENV_VALUE=somevalue");
}
然而,Proc
在 Bin
中的 build.rs
中使用此代码时无法找到环境变量(注意:在 dotenv
之后检查是否存在时打电话,我可以验证密钥是否确实存在):
fn main() {
dotenv::dotenv().unwrap();
}
这是我的 Proc
箱子:
use proc_macro::TokenStream;
#[proc_macro_derive(MyProcMacro)]
pub fn my_proc_macro(input: TokenStream) -> TokenStream {
if std::env::var("SOME_ENV_VALUE").is_err() {
panic!("Failed to retrieve env value")
}
TokenStream::new()
}
为什么 println!
命令不会失败?它可以与 dotenv
一起使用吗?否则我需要编写一些代码,将密钥从我的 env
文件复制到 println!
命令...
所有代码都在我的minimal reproduction project.
我鼓励您重新阅读 Build Scripts chapter of the Cargo docs。构建脚本是一个 单独的可执行文件,Cargo 在开始构建源代码之前构建并执行。
- 货运开始
- Cargo 执行
rustc
构建构建脚本 - Cargo 执行构建脚本
- Cargo 执行
rustc
来构建您的代码 - 货物出口
[dotenv] loads environment variables from a .env file, if available, and mashes those with the actual environment variables provided by the operating system.
它加载的变量被放入当前进程环境变量中。在您的示例中,这是构建脚本可执行文件。
[
cargo:rustc-env
] tells Cargo to set the given environment variable when compiling the package
构建脚本的标准输出与 Cargo 交互,然后修改代码的编译方式,包括要设置的环境变量。
您需要加载dotenv文件和设置环境变量以便后续编译。像这个编译但未经测试的例子:
fn main() {
if let Ok(env) = dotenv::dotenv_iter() {
for (k,v) in env.flatten() {
println!("cargo:rustc-env={}={}", k, v);
}
}
}
不用担心此方法已被标记为已弃用。维护者 changed their minds.