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

dx: warn about long paths disabled #11140

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

earloc
Copy link
Contributor

@earloc earloc commented Nov 2, 2024

Summary of the changes

  • refactored Directory.Targets.props to centralize import of common targets
  • introducing check for enabled long path support on windows
  • added docs to guide contributors on how to enable long path support

Now, when building with build.cmd, the following Warningis generated:

{{PATH-TO-REPOSITORY}}\eng\targets\CheckLongPathSupport.targets(26,5): error LongPathsDisabled: Long paths support is required for this project. See 'docs/contributing/LongPaths.md' on how to overcome this. 

Opening VS will show the warning as well, with clickable link to docs/contributing/LongPaths.md :
image

fixes #11139

@earloc earloc requested review from a team as code owners November 2, 2024 13:14
@earloc
Copy link
Contributor Author

earloc commented Nov 2, 2024

@davidwengier, @ryzngard
Took me some time to recover some long forgotten msbuild wizardry, but finally got a proposal to integrate the check for long path support when working with this repo on a windows machine together.

As the original errors already happen during project load-time (f.e.: in VS, the affected project refuses to load), this was a bit tricky to achieve, but I feel this is unobtrusive enough to ease up the overall first-time experience when working with this repo.

Only "donwside" of the current approach is, that this check might be carried out for every project within the solution - which might put some additional time on top of overall build-time. This may be somehow refactored in a way, that the imported target only gets imported once, but I didn`t manage to achieve this so far.

Curious about your thoughts on this...

Copy link
Contributor

@davidwengier davidwengier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues from me.

@DustinCampbell
Copy link
Member

I'd be very interested in @jaredpar taking a look to make sure we're following the best practices. I know that dotnet/roslyn does something specific for long paths.

@earloc
Copy link
Contributor Author

earloc commented Nov 4, 2024

@DustinCampbell fyi: this change basically adopts what roslyn does, but integrates it in a slightly different way. Mostly due to the fact that those nasty path-too-long-errors might pop up very early (at load-time). This is why I decided to utilize InitialTargets in favor of BeforeTargets="BeforeBuild" , as the error(s) prevented the build from reaching this target at all.

@DustinCampbell
Copy link
Member

@DustinCampbell fyi: this change basically adopts what roslyn does, but integrates it in a slightly different way. Mostly due to the fact that those nasty path-too-long-errors might pop up very early (at load-time). This is why I decided to utilize InitialTargets in favor of BeforeTargets="BeforeBuild" , as the error(s) prevented the build from reaching this target at all.

I totally understand @earloc! That's why I was hoping @jaredpar would take a look, since he manages so much of the infrastructure in Roslyn and Razor. 😄

@earloc
Copy link
Contributor Author

earloc commented Nov 15, 2024

@jaredpar you probably have a ton of other things on your plate. Would appreciate any feedback on this here if you find the time 👌.

Also, I'm wondering if this might be packaged into a standalone nuget, which projects would be able to just pull in 🤔.

'path-too-long'-errors may occur very early when building / loading projects, so we ensure this check get's executed by utilizing 'InitialTargets',
see https://learn.microsoft.com/en-us/visualstudio/msbuild/how-to-specify-which-target-to-build-first?view=vs-2022#use-the-initialtargets-attribute
-->
<Project InitialTargets="EnsureLongPathSupport">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a <Project> here seems a bit heavy. Why are you not just replicating the target that Roslyn is using

  <Target Name="_CheckLongPathSupport" BeforeTargets="BeforeBuild" Condition="'$(MSBuildRuntimeType)' == 'Full'">
    <PropertyGroup>
      <_RoslynLongPathsEnabled>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem', 'LongPathsEnabled', null, RegistryView.Registry64, RegistryView.Registry32))</_RoslynLongPathsEnabled>
    </PropertyGroup>
    
    <Warning Condition="'$(_RoslynLongPathsEnabled)' != '1'" Text="Long paths are required for this project. Please run eng\enable-long-paths.reg" />
  </Target> 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally intended to do so. However, when relying on BeforeTargets="BeforeBuild" this target won't execute. Instead, only this generic

error MSB4248: Cannot expand metadata in expression "$([MSBuild]::ValueOrDefault('%(FullPath )', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))". The item metadata "%(FullPath)" ca nnot be applied to the path "TestFiles\IntegrationTests\ComponentDesignTimeCodeGenerationTest\GenericComponent_GenericE ventCallbackWithGenericTypeParameter_NestedTypeInference\TestComponent.mappings.txt".

Error pops up during build.cmd.

I guess this is due to the fact that above error occurs too early (at project load time) and therfore BeforeBuild never gets executed. see previous comment

As for the different check when to do the registry-lookup:

I felt it would be a bit cleaner to actually check for the paltform (as of dotnet/msbuild#539) instead of relying on some implicit side-effect via (Condition="'$(MSBuildRuntimeType)' == 'Full'").

Wouldn't fight about this, though ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Questinable might be: Should this really be done via msbuild-mechanisms, or might it be sufficient to just include it in build.-cmd, which is windows-only by design ;).

I preferred the first, because then this warning would also be generated when doing an ordinary dotnet build - not sure if this is actually supported / recommended, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally intended to do so. However, when relying on BeforeTargets="BeforeBuild" this target won't execute. Instead, only this generic

Do we have a binlog where this error occurs? That seems very off.

Basically my mental model is that this works for roslyn, why can't it work for razor? Nested project builds are also one of my "that is probably going to have impact we don't like so be wary". This is why I'm focused on this part of the change.

Copy link
Contributor Author

@earloc earloc Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaredpar Gathering a binlog is new to me, but seems to be straight forward to collect. I will have a look into this. Very appreciating someone paying so much attention into such nitty-gritty details 👌.
Will keep you updated.

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Import Project="Packaging.targets" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this line necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaredpar dunno, this was originally included in Directory.Build.targets

I refactored it into Common.targets and kept including it, there.

Comment on lines 84 to 94
### Common error: path too long (on windows)
If you encounter errors pointing to `path-too-long` errors, like:
```
Path: {{SOME-PATH}} exceeds the OS max path limit. The fully qualified file name must be less than 260 characters.
```
or
```
error LongPathsDisabled: Long paths are required for this project. See 'docs/contributing/LongPaths.md'.
```
see [LongPaths](LongPaths.md) on how to deal with this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this section. Instead I would add a line in the windows section above that Long path support is required and link to Longpaths.md

Copy link
Contributor Author

@earloc earloc Nov 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed and done, just put an additional requirement in the top section.

Comment on lines 37 to 48
### Use [subst] to shorten your local path
> :warning: While this might work in your particular environment, chances are high that future changes might introduce even longer paths, which might then again result in above errors.
> Also, [subst] has no way to make a substitution permanent, so you might need to repeat this step after reboots, or ensure it get's executed at startup.
>
If you don't want to / can't enable long path support globally, try shortening your local path with [subst] where `R` is a free drive-letter, e.g.:

> ```ps1
> $dir = pwd
> subst R: $dir
> cd R:\
> ```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this section. The requirement of the repository is to enable long paths. Don't want to outline alternatives even if we say we don't support them.

Copy link
Contributor Author

@earloc earloc Nov 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed and done.

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

Successfully merging this pull request may close these issues.

dx: better guide potential contributors on dealing with 'path-too-long'-errors on windows
4 participants