Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Unable to load projects on .NET SDK 6.0.301 due to NuGet.Frameworks load errors #1470

Closed
baronfel opened this issue Jun 17, 2022 · 9 comments
Assignees
Labels
area: editor Extensions for Visual Studio and Visual Studio Code bug Something isn't working

Comments

@baronfel
Copy link
Member

Describe the bug

The language server extension bundles a version of NuGet dlls that is incompatible with the ones shipped in the SDK. Because MSbuild Locator is used to locate and run MSBuild DLLs from the SDK, there are version mismatches that lead to errors running targets in the build.

This was initially reported at dotnet/sdk#26065, with detailed resolution steps here.

To Reproduce

Please see the linked issue for reproduction steps.

Expected behavior

The language server should be able to load projects.

System information

  • Version of the NuGet package or extension for which the problem occurs: v0.24.210930
  • Your operating system and .NET Core version: Ubuntu 22.04, .NET SDK 6.0.301
  • For issues with extensions, the version of the IDE for which the problem occurs: Visual Studio Code version 1.68.1

Additional context

The short form of the resolution is that the NuGet.Frameworks PackageReference in the LanguageServer should be marked ExcludeAssets="runtime".

@baronfel baronfel added bug Something isn't working needs triage An initial review by a maintainer is needed labels Jun 17, 2022
@bettinaheim
Copy link
Contributor

@ricardo-espinoza Could you take a look at this?

@bettinaheim bettinaheim removed the needs triage An initial review by a maintainer is needed label Jun 21, 2022
@bettinaheim bettinaheim added the area: editor Extensions for Visual Studio and Visual Studio Code label Jun 21, 2022
@ausbin
Copy link
Contributor

ausbin commented Jun 27, 2022

I just tested and #1467 seems to resolve this. With the current Quantum SDK release (0.24.210930), I see the same behavior reported in dotnet/sdk#26065. But testing on the branch release/v0.25.2206 (which includes #1467 merged) by building the QsCompiler solution locally and using the <QscExe> setting in the project file and quantumDevKit.languageServerPath in my VSCode settings, I don't see the error spam in VSCode or when running dotnet build.

@baronfel
Copy link
Member Author

That PR looks like it would resolve the issue for now, but I would expect it to come back again with other SDK version updates. In my opinion (and that of other MSBuild team members), the correct fix long term is to update your PackageReference with ExcludeAssets="runtime".

@ausbin
Copy link
Contributor

ausbin commented Jun 27, 2022

Thanks for that suggestion, @baronfel. Could you share what that means to folks such as me who aren't msbuild gods? (That is, what does setting that option do?)

@bettinaheim
Copy link
Contributor

bettinaheim commented Jun 27, 2022

@ricardo-espinoza I double checked and saw an NuGet.ProjectModel dependency doesn't seem to have the exclude. Could you please update this and confirm the functionality? Thanks

@baronfel
Copy link
Member Author

This is the fun stuff :D The reference for 'dependency assets' in general is here, and for this scenario, we're mainly interested in two kinds of dependency asset:

  • compile - assets from a package used during compilation. these might be ref assemblies or full assemblies for example.
  • runtime - assets from a package used during actual execution. these are copied to the .deps.json file for your project and the CoreCLR will use this file to load them

When you add a PackageReference, by default you're setting a few properties that control how the assets in that package are used:

  • IncludeAssets - assets that are used. this defaults to all, meaning everything
  • ExcludeAssets - assets that are skipped/not used. this defaults to none, meaning skip nothing
  • PrivateAssets - assets that should stay local to this project and not influence any projects that consume this project. this defaults to things like contentFiles, analyzers, MSBuild props/targets, etc.

When you add a PackageReference, you're saying 'include everything from this package' by default. This means that you'll compile against the package, and require its runtime dlls in order to execute. This is what's happening now with your (implicit or explicit) Nuget dependency. You're compiling against version X, but then at runtime, when MSBuild runs to evaluate a project, you're trying to load a different version of Nuget dependencies than you compiled against - the ones that were bundled in the SDK.

For apps that operate almost on a plugin model, where some external host dictates the versions of dependencies, we want to use the following semantics: 'compile against a known, potentially lower version of dependency X, but don't include any of the runtime assets for X because my hosting/execution environment will provide the actual DLL'. The way you express this in PackageReference form is through the ExcludeAssets="runtime" form - telling NuGet restore to not include the runtime assets of that dependency in your application.

This is what we tell MSBuild Task authors to do, too - because their task will operate entirely inside an MSBuild context, they should mark their MSBuild PackageReference in this way. Your situation is just one step further - because the .NET SDK also includes the same dependency on NuGet that you're trying to use in your library.

Does that help?

@filipw
Copy link
Contributor

filipw commented Jun 28, 2022

FWIW what we did to address the same problem in OmniSharp, is we delete Nuget.* libraries from the release build prior to packaging https://github.com/OmniSharp/omnisharp-roslyn/blob/master/build.cake#L599-L603 and then simply let them be loaded from the discovered SDK

@anpaz
Copy link
Member

anpaz commented Jul 15, 2022

@baronfel,
Thanks for the pointers. We have incorporated the ExcludeAssets="runtime" to the Nuget.Frameworks on the LanguageServer project in #1462.
The good news is that indeed the dlls are not copied to the output folder and the language server loads correctly.
The bad news is that the tests are failing. Turns out MSTest has also its dependency on Nuget.Frameworks (see microsoft/vstest#3154). Applying the ExcludeAssets=runtime does not work and just prevents the tests to run all together. If ExcludeAssets is not included, the LanguageServer fails to load the dll. It's unclear to me how we can proceed. Any other suggestions?

@ricardo-espinoza
Copy link
Contributor

Thanks all for the pointers and recommendations. With the change mentioned by Andrés, we have addressed the blocking issue reported by @baronfel. We have unfortunately disabled the Language Server tests temporarily, and we're actively working on bringing them back up by addressing this dependency in them too. For now marking the issue as closed. The update will be reflected in the next QDK release.

waf added a commit to waf/CSharpRepl that referenced this issue Nov 10, 2022
The NuGet.* libraries should not be bundled with csharprepl and we should instead use the ones included in the SDK.

You can see other projects in the .NET community making similar fixes:

microsoft/qsharp-compiler#1470
OmniSharp/omnisharp-roslyn#2308
OmniSharp/omnisharp-roslyn#2436

If we don't do this, we get issues with the MSBuildWorkspaces and MSBuildLocators unable to load the nuget libraries due to dependency conflicts. It mostly affects our "load solution" / "load project" features.
mattstern31 added a commit to mattstern31/CSharp-Repl-Services that referenced this issue Nov 11, 2023
The NuGet.* libraries should not be bundled with csharprepl and we should instead use the ones included in the SDK.

You can see other projects in the .NET community making similar fixes:

microsoft/qsharp-compiler#1470
OmniSharp/omnisharp-roslyn#2308
OmniSharp/omnisharp-roslyn#2436

If we don't do this, we get issues with the MSBuildWorkspaces and MSBuildLocators unable to load the nuget libraries due to dependency conflicts. It mostly affects our "load solution" / "load project" features.
syedrizvinet added a commit to syedrizvinet/Repl-Tests-CSharp that referenced this issue Apr 24, 2024
The NuGet.* libraries should not be bundled with csharprepl and we should instead use the ones included in the SDK.

You can see other projects in the .NET community making similar fixes:

microsoft/qsharp-compiler#1470
OmniSharp/omnisharp-roslyn#2308
OmniSharp/omnisharp-roslyn#2436

If we don't do this, we get issues with the MSBuildWorkspaces and MSBuildLocators unable to load the nuget libraries due to dependency conflicts. It mostly affects our "load solution" / "load project" features.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: editor Extensions for Visual Studio and Visual Studio Code bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants