Describe the problem you are trying to solve
On Windows, when the directory where the project files are located is too long, cargo fails with various file-related errors.
Describe the solution you'd like
Rust should handle long path ok. We just have to add a longPathAware to the app manifest:
https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
Notes
This issue only occurs if the file paths cargo wants to touch are too long.
This happens with paths like these:
C:\Users\User\AppData\Local\Yarn\Cache\v6\.tmp\19aa03367eb9c4791798fcfbbdd8d7d4.e2c16fa02b2d9250fe13c2054c37a11aef5c0da3.prepare\native\target\x86_64-pc-windows-msvc\release\.fingerprint\semver-parser-dc26c18a352c24f5\lib-semver_parser-dc26c18a352c24f5.json
I think this would be a very hard problem to solve, if not impossible. Some issues I can think of:
\\?\) everywhere, but I think that would be very difficult and problematic. We already have problems with device paths on various filesystems. They are also not user-friendly, so would probably need some abstraction that could show different representations.Thanks for the response! Maybe there's a workaround I could apply to handle this? Like setting a custom CARGO_TARGET_DIR - would that work? I think it should work...
It could be disable by the regedit.msc. so just stopping checking it in the cargo for windows'll be fine.
Rust doesn't have a way to embed the app manifest AFAIK.
If your CI has the MSVC toolsets installed, you have all that you need. Don't have them? Here is the direct download link.
The default registry key needed for that is OFF, so I don't think it would help most people
But for the people who DO have it on, it would help. In my opinion, that's a pretty good start! And when developers start seeing that their colleague got it working, they will ask "hey dude, what did you do?", and soon their IT department will turn the switch on for all new dev computers.
All the windows-interfacing APIs (in C and Rust) would need to be audited/updated for the larger constant.
If your windows-interfacing APIs are still using a static 260-char buffer, it's past time to fix that code. All Windows APIs have a way to query the required buffer length. The typical way is calling the function with a 0-length buffer, and the return code is the required length. Any skilled Windows developer should know that.
All of rustc and cargo would need to handle this.
Yep. Let's start with this tool (this issue is about Cargo, right?). When it's done, other executables will copy the solution. Lead by example!
IIRC, MSVC's linker can't handle long filenames, so it probably wouldn't work even if we tried.
Have you tried? Or are you assuming other tools might not work as an excuse not to try? How will the situation improve if every maintainer used the argument "tool X is not updated, so I'm not updating tool Y" ? I strongly believe that if everyone does their part, the ecosystem will quickly improve for everybody.
Many other tools would not be able to handle these paths
Maybe they already do, but unless cargo is updated, we'll never know. And what's the worst-case here? That cargo supports it, and we find out that a downstream tool gives an error. Then we can create an issue and a PR for that downstream tool, and keep making progress.
We could maybe try to use canonicalized UNC paths everywhere
Good point, excellent explanation. This is not a very good solution. The manifest solution seems a better approach.
I just ran into this issue because I have a crate with a long name, over 100 characters each, so the path to the crate's location in the target folder exceeds the 260 character limit. Because of this, even cargo build fails. Does anyone following this issue know of any workarounds?
Most helpful comment
If your CI has the MSVC toolsets installed, you have all that you need. Don't have them? Here is the direct download link.
But for the people who DO have it on, it would help. In my opinion, that's a pretty good start! And when developers start seeing that their colleague got it working, they will ask "hey dude, what did you do?", and soon their IT department will turn the switch on for all new dev computers.
If your windows-interfacing APIs are still using a static 260-char buffer, it's past time to fix that code. All Windows APIs have a way to query the required buffer length. The typical way is calling the function with a 0-length buffer, and the return code is the required length. Any skilled Windows developer should know that.
Yep. Let's start with this tool (this issue is about Cargo, right?). When it's done, other executables will copy the solution. Lead by example!
Have you tried? Or are you assuming other tools might not work as an excuse not to try? How will the situation improve if every maintainer used the argument "tool X is not updated, so I'm not updating tool Y" ? I strongly believe that if everyone does their part, the ecosystem will quickly improve for everybody.
Maybe they already do, but unless cargo is updated, we'll never know. And what's the worst-case here? That cargo supports it, and we find out that a downstream tool gives an error. Then we can create an issue and a PR for that downstream tool, and keep making progress.
Good point, excellent explanation. This is not a very good solution. The manifest solution seems a better approach.