-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Passing environment variables from down-stream to up-stream library #4121
Comments
I need this too! My use case is to dynamically search for the most appropriate value of
In all cases I need to provide Cargo with an absolute path, which is also very impractical. I have tried providing the full pre-built lib binaries in my project tree, together with all the .h files. Library links fine as it can be configured via The sequence would be:
This is so annoying that I am starting to look for Rust native physics libraries to replace Box2D altogether. Which is a shame as I'm otherwise super happy with both Box2D and the wrapped2d. Cheers! |
I need this too to be able to cross-compile with openssl dependency without having to invoke cargo like this every time: |
+1 for the cross compilation scenario. When you depend on a crate that uses |
Me too, I want to set ARMV7_LINUX_ANDROIDEABI_OPENSSL_DIR to use a prebuilt openssl. |
I also want Cargo to pass environment variables configuring the location of OpenSSL headers and libraries. In my case I'm cross compiling and the variables depend on the current target/toolchain. |
Any progress on this, or guidance on how to get started with a PR? I have a use case where a crate needs to know the install location of a closed source SDK, which typically isn't placed in a user's $PATH since it can be useful to have multiple SDK versions installed at the same time. Alternatively, adding an |
…les. This DOES NOT WORK. What's needed is a solution for rust-lang/cargo#4121.
same thing with libzmq here |
I'm interested in a similar feature, where the major pain point is overriding OPENSSL_DIR with one that would be provided by a top-level crate that depends on openssl-sys. Since many crates depend on openssl, using a modified openssl-sys that won't cause conflicts with other dependencies is almost impossible. |
This would be super useful! My current solution is to put the build command (e.g. |
Also looking for this. Having to manually specify env vars on the command line before every build is not very ergonomic and caused more than a few of my builds to fail. |
I need this too. One crate uses a wasm file, while another crate depends on the former crate and need to specify a custom wasm file. |
Has anyone tried using cargo-make as a potential workaround for this problem? |
🙏 |
+1 🙏 |
Same thing building stuff for Android, where some packages require env vars pointing to binaries in the NDK (eg I'm not convinced this is really a question of passing env vars from one crate to another. It feels more like local config. As others have suggested, I think an |
This issue is particularly awkward when it comes to things like rust-analyzer and RLS running within an editor like Visual Studio Code since it's particularly difficult to control the environment of cargo in this case. Incidentally my use case is exactly the same as the OP; I need to be able to set the |
It's often impractical to use an environment variable to specify FFMPEG_DIR (such as when builds are run via rust-analyzer/RLE for editor diagnostics during development) so we also support parsing an environment.json file like: { "FFMPEG_DIR": "/path/to/ffmpeg-build/" } and re-export all values into the environment Addresses: rust-lang/cargo#4121
It's often impractical to use an environment variable to specify FFMPEG_DIR (such as when builds are run via rust-analyzer/RLE for editor diagnostics during development) so we also support parsing an environment.json file like: { "FFMPEG_DIR": "/path/to/ffmpeg-build/" } and re-export all values into the environment Addresses: rust-lang/cargo#4121
It's often impractical to use an environment variable to specify FFMPEG_DIR (such as when builds are run via rust-analyzer/RLE for editor diagnostics during development) so this enables support for parsing an environment.json file like: { "FFMPEG_DIR": "/path/to/ffmpeg-build/" } Addresses: rust-lang/cargo#4121
It's often impractical to use an environment variable to specify FFMPEG_DIR (such as when builds are run via rust-analyzer/RLE for editor diagnostics during development) so this enables support for parsing an environment.json file like: { "FFMPEG_DIR": "/path/to/ffmpeg-build/" } Addresses: rust-lang/cargo#4121
Faced with this issue, I tried looking at modifying ffmpeg-sys to refer to an My original plan had been that it would look for an {
"FFMPEG_DIR": "/path/to/ffmpeg-build/"
} at the very top of my project but I found that cargo doesn't expose enough information (as far as I could tell) to locate the top level Cargo.toml for a build. My current solution looks for an environment.json that's adjacent to the ffmpeg-sys Cargo.toml which isn't really ideal because now I have to have a fork of ffmpeg-sys for the sake of configuring it. For me this is still preferable to dealing with environment variables but I think it would be much nicer if there was some way to locate the top level of a project within a build.rs. I wonder if the Cargo maintainers would be open to supporting something like this directly in Cargo and avoid needing to modify projects like ffmpeg-sys? I basically just added the following snippet to the top of their // It's often impractical to use an environment variable to specify
// FFMPEG_DIR so we also support parsing an environment.json file
// Ref: rust-lang/cargo#4121
let manifest_dir_env = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR evironment variable unset");
let env_path = Path::new(&manifest_dir_env).join("environment.json");
if let Ok(env) = fs::read_to_string(env_path) {
let env: Value = serde_json::from_str(&env).expect("Failed to parse environment.json");
if let Some(env_map) = env.as_object() {
for key in env_map.keys() {
if let Some(env_value) = env[key].as_str() {
// Simply re-export as an actual environment variable for consistent handling below...
env::set_var(key, env_value);
}
}
}
} And Cargo could essentially do exactly the same thing automatically except looking for an With this approach then VSCode diagnostics via rust-analyzer Just Works(tm) for me again so I definitely think it would be good for Cargo to have some kind of general solution like this that lets us eradicate the need to configure build environment variables. Environment variables are a nightmare to deal with when considering editor/IDE integrations if each different integration needs to provide some inconsistent mechanism for configuring the environment (not currently available for vscode/rust-analyzer). Compared to the suggestions to add some way of configuring the environment within a Config.toml I think having a seperate |
Just to try and collate some of the related issues where people have been struggling with similar kinds of environment variable configurations: #97 |
Some custom build scripts (especially for -sys packages) expect to query environment variables to locate build resources (such as pre-built binaries) but these cause lots of trouble when considering the numerous different ways in which cargo may be invoked. For example each editor that invokes cargo as part of providing development diagnostics needs to offer some way to configure environment variables or users need to find their own way of controlling the environment variables of these different tools which is burdensome and can lead to an inconsistent duplication of state across tools. This introduces support for reading an (optional) environment.json found at the root of the current workspace that may contain a map of environment variable key, value pairs. These variables will be exported to all build scripts run under the workspace. The removes any need to configure tools and editors independently. The configuration is separate from any Config.toml since it's likely that the state shouldn't be under version control in many situations (generally locating resources for the project within a specific user's development environment). Fixes: rust-lang/issues/4121 Fixes: rust-lang/rls/issues/915 Fixes: rust-lang/vscode-rust/issues/791 Fixes: rust-lang/rust-analyzer/pull/6099 Fixes: intellij-rust/intellij-rust/issues/1569
I took a stab at making a pull request for addressing this issue: #8839 It's basically a first draft implementation of what I described above and works for my use case. Could be good to know if it could work for others here too. |
How to set different env vars if --release is set? For example: I'd like to set:
if --release is not set and "info" otherwise. |
(Moved and re-phrased from #97)
Currently cargo can pass env vars from up-stream dependencies to down-stream, with user-defined metadata.
But what's still lacking is the reversed control, where up-stream library expects a env var to be set to build successfully, and down-stream must fill the env var for it.
This scenario is common in FFI libraries wrapping existing C lib, for example meh/rust-ffmpeg-sys expects the env var
FFMPEG_DIR
to be set to the path of pre-built C FFMpeg libs & binaries.The text was updated successfully, but these errors were encountered: