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

Effects of RUSTUP_WINDOWS_PATH_ADD_BIN change #3825

Open
smoelius opened this issue May 13, 2024 · 15 comments
Open

Effects of RUSTUP_WINDOWS_PATH_ADD_BIN change #3825

smoelius opened this issue May 13, 2024 · 15 comments
Milestone

Comments

@smoelius
Copy link
Contributor

In #3703 (comment), @djc asked:

Can one of you open a new issue discussing what the use case here is and how/why we broke it?

Dylint works similar to Clippy. It sets RUSTC_WORKSPACE_WRAPPER to the path of a dylint-driver binary, and then invokes cargo check. There are several dylint-driver binaries, each associated with a nightly toolchain. Each binary is linked against the rustc_driver and std libraries of its corresponding toolchain. On Windows, this means that the directories containing those libraries must be in PATH. If PATH does not include those directories, then the call to cargo check fails because dylint-driver cannot be loaded.

Here is an example: https://github.com/trailofbits/dylint/actions/runs/8977891579/job/24657422248#step:8:2321

@rami3l rami3l added this to the 1.28.0 milestone May 13, 2024
@sunshowers
Copy link

sunshowers commented May 14, 2024

Thanks for filing this! This is essentially what nextest has too, specifically with test binaries built by proc-macro crates. Though this has been a long-standing issue with nextest (nextest-rs/nextest#267), because ideally nextest would work with Rust installations not managed by rustup.

We expect nextest-rs/nextest#1499 to fix this the right way, by querying rustc to obtain the target libdir and adding it manually to the dylib path variable.

@djc
Copy link
Contributor

djc commented May 14, 2024

@sunshowers sounds good, thanks for chiming in!

@smoelius thanks for the detailed description. Do you think the proposed path forward for nextest would also address the dylint use cases?

@smoelius
Copy link
Contributor Author

@smoelius thanks for the detailed description. Do you think the proposed path forward for nextest would also address the dylint use cases?

I'm not sure. Is RUSTUP_WINDOWS_PATH_ADD_BIN going away?

@djc
Copy link
Contributor

djc commented May 14, 2024

@smoelius thanks for the detailed description. Do you think the proposed path forward for nextest would also address the dylint use cases?

I'm not sure. Is RUSTUP_WINDOWS_PATH_ADD_BIN going away?

There are no concrete plans in that direction, but it'd be good to avoid depending on workarounds for deprecated features.

@sunshowers
Copy link

I think a general decision to make is whether a tool needs to support Cargo installations not managed by rustup. For nextest the answer is yes, but it could be no for other tools.

@smoelius
Copy link
Contributor Author

There are no concrete plans in that direction, but it'd be good to avoid depending on workarounds for deprecated features.

OK. Dylint's CI still uses this environment variable to run one obscure doc test, but Dylint itself no longer uses it.

@sagudev
Copy link

sagudev commented May 16, 2024

In servo we also hit this with our custom linter.

bors added a commit to rust-lang/rust-clippy that referenced this issue May 16, 2024
Manually set library paths in .github/driver.sh

Fixes https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Windows.20CI.20failing

Rustup 1.27.1 no longer adds `[SYSROOT]/bin` to `PATH` by default - rust-lang/rustup#3825. This is fine for the packaged binaries since windows loads `dll`s from the folder the executable is in, but our built one is in a different folder

There's an environment variable to get the old behaviour back, but as it's deprecated and not much code I think returning to setting it manually is fine

changelog: none
@Darksonn
Copy link

This affected Tokio's CI setup too, and broke the case where we run tests on windows with proc macros. Not sure why exactly it broke us, but adding the flag seems to fix it.

@rami3l
Copy link
Member

rami3l commented May 17, 2024

@ehuss do you think Rustup is responsible for this breakage?

Modifying PATH was originally done for various reasons that are complicated and not really relevant anymore.
https://internals.rust-lang.org/t/help-test-windows-behavior-between-rustup-and-cargo/20237

AFAIK, there have not been any indications of anyone having problems.
#3703

... unfortunately that's probably because few have actually tried 😅

@rbtcollins
Copy link
Contributor

This is in a super frustrating part of unix/windows difference; I'm sad we've created some pain - but the good news seems to be it is fairly limited - 3 projects out of the entire ecosystem is not terrible ;).

I have no strongly held view on what the right answer here is, but see #3036 (comment) - and there is a lot of previous discussion and work such as rust-lang/cargo#11917 and #3178

I do think its important that rustup is consistent on all platforms except where we really cannot (and the edge case of linked toolchains missing binaries is one such place). And we are now consistent again, so with the limited breakage, I'm inclined to suggest we shouldn't panic but should take some time to look at that the impact is on these downstream projects...

we could solve this by documenting what they need to do, or possibly by some sort of config they could opt-into ... but if we offer that, we should offer it for all platforms IMO.

@sunshowers
Copy link

sunshowers commented May 17, 2024

(Note that this introduces an inconsistency -- on Unix platforms, with rustup-managed cargo, you still don't need to do anything special with proc macro tests -- but on Windows you do.)

Wanted to reiterate that any projects that are broken by this are also probably broken by scenarios where rustup is not in use (e.g. distro-packaged cargo).

@rbtcollins
Copy link
Contributor

@sunshowers I think that visible inconsistency is properly at a higher layer though: it is a symptom of dlopen semantics on the underlying platforms. Because PATH affects both command line lookup and dlopen, we can't have detach them,

@ChrisDenton
Copy link
Member

Is there a minimal example of the proc-macro test issue? This could perhaps be fixed on the rustc/cargo side of things by being more explicit about where to load a specific DLL from.

Maybe a possible workaround for rustup is to have a third mode that adds the bin path to the end of PATH?

@sunshowers
Copy link

Thanks for filing this! This is essentially what nextest has too, specifically with test binaries built by proc-macro crates. Though this has been a long-standing issue with nextest (nextest-rs/nextest#267), because ideally nextest would work with Rust installations not managed by rustup.

We expect nextest-rs/nextest#1499 to fix this the right way, by querying rustc to obtain the target libdir and adding it manually to the dylib path variable.

This is now out as part of cargo-nextest 0.9.72. With this, nextest no longer depends on whether it's being invoked via a rustup-wrapped cargo.

@rami3l rami3l modified the milestones: 1.28.0, On Deck Aug 9, 2024
@ferdnyc
Copy link

ferdnyc commented Sep 15, 2024

@sunshowers I think that visible inconsistency is properly at a higher layer though: it is a symptom of dlopen semantics on the underlying platforms. Because PATH affects both command line lookup and dlopen, we can't have detach them,

That's true, but there's an escape hatch on Windows because an executable will ALWAYS look in its own directory for DLLs, first and always. Regardless of %PATH%, regardless of things like C:\Windows\System32\, etc...

Just arranging to have an executable's DLL dependencies end up in the same directory as that executable is almost always a surer way of ensuring that the application can be run, vs. any sort of path shenanigans.

Do that, and while it might be helpful to have C:\path\to\my\binary\ on the path, so that you can run C:\path\to\my\binary\program.exe as just program.exe, it's no longer required to be on the path because you can always just run C:\path\to\my\binary\program.exe by its full path, and it will pick up any DLL in C:\path\to\my\binary\ even if that directory isn't on the path.

We expect nextest-rs/nextest#1499 to fix this the right way, by querying rustc to obtain the target libdir and adding it manually to the dylib path variable.

(TBH, what people need to get over, when building applications for Windows, is this idea that there should be a "libdir" at all. There should not; the bindir IS the libdir. They are one and the same. Import libraries can go in the "libdir", if you're installing libs to be used by other projects. But DLLs belong in the same output directory as the executables.)

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

No branches or pull requests

9 participants