Skip to content
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

Get cargo environment without running code #14045

Open
alexallmont opened this issue Jun 11, 2024 · 0 comments
Open

Get cargo environment without running code #14045

alexallmont opened this issue Jun 11, 2024 · 0 comments
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-triage Status: This issue is waiting on initial triage.

Comments

@alexallmont
Copy link

Problem

Currently it’s only possible to see the environment by running an executable (#4879). It would be excellent if this could be extended to print/save the environment without launching anything.

My use case is to improve the debug workflow in IDEs. For example, this test ran fine without debug but panicked in debug because outside the context of cargo test the environment is not available and it can’t find a shared object file (see note 2 below for details).

This could be resolved if we saved the environment as part of build, test --no-run, or another subcommand so the environment could be handed over to the debugger, or be used as a template for a developer to work with.

Proposed Solution

One solution would be adding a new a flag to save environment to a text file when built, e.g.

  • cargo build --save-env=<filename>
  • cargo test --no-run --save-env=<filename>
  • (I assume--save-env would be useful from some non-build commands too?)

Ideally the save env output would quote each value. For example, some vars from my current conifig:

VSCODE_GIT_ASKPASS_EXTRA_ARGS=""
LESSCLOSE="/usr/bin/lesspipe %s %s"
TERM="xterm-256color"

(If those were unquoted, then sourcing would have issues parsing the %s. There's a note on this here easier: https://stackoverflow.com/questions/15235729/sourcing-env-output.)

The saved environment could then be parsed or picked up directly by external tooling. For example, all you would need to do in VSCode is add this to your settings.json: "lldb.launch.envFile": "<filename>".

I'm not sure if this solution is idiomatic so I’m very open to suggestions. A longer-term solution would be commands for interrogating environment/settings in detail, but that's big feature, probably a separate ticket entirely.

Notes

1. Previous related work

In #4879, @joshtriplett requested output for LD_LIBRARY_PATH during cargo run so developers can run their cargo-built executables outside cargo. This was resolved in PR #12498 and now cargo run -vv and cargo test -vv print the environment. The problem is this is always part of a run, e.g. cargo test -vv it's in the output Running 'CARGO=foo CARGO_CRATE_NAME=etc...'. To prep for debug in this case, nothing should be launched, just the environment is needed.

2. How binary is picked up in example above

In my main example, the project uses a crate that has a custom build.rs with a C shared lib; the build file has a cargo:rustc-link-searchpointing to the out/lib folder where the .so lives. When running a regular test in the IDE, it works fine because under the hood it’s just running a regular cargo test which sets up LD_LIBRARY_PATH (and any other CARGO environment vars) from any search paths.

However, when running in debug, the IDE can’t just run cargo test, it first has to cargo build (or cargo test --no-run) to generate an executable and then launch the debugger with it. The problem is there is no neat way extract the environment to hand over to the debugger; the fix to #4879 allows you to see the environment but it’s mixed in with other build/run output, and of course the code is launched which you want to avoid if going into a debug session immediately afterwards.

3. Comparison with and without debug

If using VSCode, copy this code and you'll see a "Run Tests | Debug" hover annotation above a test. If you click on "Run Tests" you'll see different output to "Debug"

#[test]
fn dump_env() {
    for (key, value) in std::env::vars() {
        println!("{key}: {value}");
    }
}

Example "Run Test" snippet:

---- dump_env stdout ----
BROWSER: /vscode/vscode-server/bin/linux-x64/dc...
CARGO: /root/.rustup/toolchains/stable-x86_64-unkn...
CARGO_HOME: /root/.cargo
CARGO_MANIFEST_DIR: /workspaces/pyrust
CARGO_PKG_AUTHORS: 

Example "Debug" snippet:

---- dump_env stdout ----
LESSOPEN: | /usr/bin/lesspipe %s
VSCODE_HANDLES_SIGPIPE: true
REMOTE_CONTAINERS: true
SHELL: /bin/bash
REMOTE_CONTAINERS_IPC: /tmp/vscode...

i.e. none of the CARGO_ or LD_LIBRARY_PATH envs are set in debug.

4. Workarounds

  • Run the test without the debugger cargo test -vv.
  • From the output, cut and paste the parts of the environment needed, e.g. LD_LIBRARY_PATH so VSCode/lldb can find the shared lib, debug settings (launch.json if VSCode).
  • Re-run the test with the debugger.

Alternatively, temporarily add a dump_env function to your project to save the environment, and add that to your lldb.launch.envFile or similar setting.

@alexallmont alexallmont added C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-triage Status: This issue is waiting on initial triage. labels Jun 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-triage Status: This issue is waiting on initial triage.
Projects
None yet
Development

No branches or pull requests

1 participant