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

Cargo with explicit manifest path has wrong warnings/errors paths #8506

Closed
rickvanprim opened this issue Jul 18, 2020 · 9 comments
Closed

Cargo with explicit manifest path has wrong warnings/errors paths #8506

rickvanprim opened this issue Jul 18, 2020 · 9 comments
Labels
C-bug Category: bug

Comments

@rickvanprim
Copy link

When running a command like cargo build --manifest-path Some/Nested/crate, cargo will invoke rustc with a working directory of Some/Nested/crate and a relative source path of src/lib.rs. This is problematic because it means that all the warnings and errors output by rustc will use src/lib.rs as the path instead of Some/Nested/crate/src/lib.rs, and as a result the VSCode problem matcher is unable to find any of the files. I tested taking the command output by cargo's verbose, and running it with the full relative path, and as expected the warnings/errors have the correct relative path. It seems like cargo either shouldn't change the working directory (which I imagine is done for a good reason, also mentioned in #8148), or it should prepend the manifest path directory before printing the output.

@rickvanprim rickvanprim added the C-bug Category: bug label Jul 18, 2020
@alexcrichton
Copy link
Member

This is a feature of Cargo where errors and path names (especially for debuginfo) are always relative to the workspace root. IDEs need to account for workspaces when building Cargo projects and most projects have a workspace root at the root of the repository as well.

@rickvanprim
Copy link
Author

I don't think trying to force all Rust projects (or workspaces) to exist at the root of a VSCode Workspace is reasonable. There are definitely cases, such as mine, where Rust is just a piece of the larger whole, and not the sole thing.

That aside, back when I was using a Rust workspace, where the workspace Cargo.toml location was at the root, but the crates themselves were much deeper in the hierarchy, error/warning paths did work correctly. However, I cannot use Rust workspaces as I have multiple disjoint Rust targets I am trying to build which are at odds with the Cargo feature model (see #8144).

It sounds like my only option for continuing to use Cargo and get warnings/errors to work is to supply a rustc_wrapper that changes the working directory back to my VSCode Workspace root and modifies all the paths on the command line to be relative to that? I suspect, as called out above, that this might break build.rs or similar though?

I'm guessing you would be opposed to having an option to specify a base path or entirely virtual workspace for Cargo to use?

@alexcrichton
Copy link
Member

To be clear we're not trying to force anything. I'm trying to explain how things work today and what tools IDEs have to learn about compilations (e.g. cargo metadata). We cannot change this behavior of Cargo since many folks rely on it.

@rickvanprim
Copy link
Author

Thanks for the response Alex. Just to make sure we're on the same page, I'm observing the following behavior:

With no workspace, rustc runs at the root of the target crate, dependencies are fed in with absolute paths.
With a workspace, rustc runs at the root of the workspace, the target crate uses a relative path from the workspace root, and dependencies use a relative path from the workspace root.

Does that sound correct?

Based on this, it seems like Cargo has all the functionality I want, it's just a matter of being able to set what that base path is without needing to have a Cargo workspace (seeing as this is unfortunately not an option for me).

Does that seem reasonable?

Fortunately with what I've discovered this morning, it seems like I can make things work as is due to dependencies using absolute paths, but it would certainly be nicer to get this working properly with VSCode Workspace relative paths and akin to how Cargo workspaces work.

@alexcrichton
Copy link
Member

Yes that all sounds correct, and it's true that Cargo doesn't have a knob to specify the base directory. What it does give, though, is cargo metadata which allows learning what commands are relative to.

@rickvanprim
Copy link
Author

I think we may be talking about slightly different things here. The rust-analyzer extension for VSCode does the correct thing (as far as I can tell) when it produces diagnostics via the language server. The issue I'm referring to here is when you run a VSCode Build Task and populate the Problems window via a ProblemMatcher which relies on being able to extract a predictable path from the text output of the process (in this case Cargo). Basically the paths it parses either need to be absolute, or they need to be relative to a fixed point (by default the VSCode Workspace root). While the fixed point for the relative paths can be customized, it's per build task, which means if your task builds more than one crate, there's not a singular value that will work.

Hopefully that helps explain why the only relative path solution I'm currently aware of involves trying to insert a shim somewhere to process those paths, or adding functionality to Cargo to do it.

As to the debug stuff you mentioned, I've only been able to test this stuff on MacOS so I'm unsure the behavior on Windows/Linux. If it's important, I can test this there as well. On MacOS, I get stuff like the following in my dSYM:

0x0000000b: DW_TAG_compile_unit
              DW_AT_producer	("clang LLVM (rustc version 1.44.0-nightly (b2e36e6c2 2020-04-22))")
              DW_AT_language	(DW_LANG_Rust)
              DW_AT_name	("src/main.rs/@/10535i0ue19d2woc")
              DW_AT_stmt_list	(0x00000000)
              DW_AT_comp_dir	("/Users/USER/Code/RustScratchPad/executable")
              DW_AT_low_pc	(0x00000001000015c0)
              DW_AT_high_pc	(0x00000001000015d2)

0x0000047c: DW_TAG_compile_unit
              DW_AT_producer	("clang LLVM (rustc version 1.44.0-nightly (b2e36e6c2 2020-04-22))")
              DW_AT_language	(DW_LANG_Rust)
              DW_AT_name	("/Users/USER/Code/RustScratchPad/library/src/lib.rs/@/1t364vcsf7afur46")
              DW_AT_stmt_list	(0x00000405)
              DW_AT_comp_dir	("/Users/USER/Code/RustScratchPad/library")
              DW_AT_low_pc	(0x0000000100001780)
              DW_AT_high_pc	(0x00000001000017c8)

It seems like this works because there's still an absolute path included (DW_AT_comp_dir) regardless of whether Cargo specified a relative or absolute path to the source file. I don't have enough insight into this to have an opinion. I know with MSVC, PDBs default to absolute paths unless specified otherwise as a linker argument. Shrug.

@alexcrichton
Copy link
Member

Er yes so these are problems to work around or problems to solve, but I'm pointing out how this is unlikely to change in Cargo. I don't know how best this would be fixed in IDEs, though.

@rickvanprim
Copy link
Author

Could you explain the current design behind working directories and paths? It seems a bit inconsistent right now in that all crates seem to be compiled with the working directory of either the root crate or the Cargo workspace, and only the root crate/Cargo workspace crates use relative paths for their root lib.rs/main.rs. Everything else, as far as I can tell, uses absolute paths. I'm assuming there's a deliberate reason for this special case? It increasingly leads me to suspect that the build process isn't relying on the working directory, or that the working directory is being set for the other crates, but they are still being fed absolute paths.

If everything used absolute paths, that would also address my issue. I was originally thinking relative paths would be nicer for the paths embedded in the output, but by default any non-local and non-vendored Cargo dependencies will end up using absolute paths, so some sort of post-build path sanitization is likely to be needed regardless. Thoughts?

@alexcrichton
Copy link
Member

There isn't really a special case here. The design is that paths are printed relative to the workspace in use. The workspace may only have on crate if no [workspace] annotations are used.

Sorry I don't have a ton of time to talk about this issue. If you'd like to open a feature request please feel free, but this issue as-is as a bug report isn't correct on Cargo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

2 participants