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

Microsoft.CodeAnalysis.CSharp v4.12.0 incompatible with .NET 8 SDK #77091

Closed
mconnew opened this issue Feb 6, 2025 · 4 comments
Closed

Microsoft.CodeAnalysis.CSharp v4.12.0 incompatible with .NET 8 SDK #77091

mconnew opened this issue Feb 6, 2025 · 4 comments

Comments

@mconnew
Copy link
Member

mconnew commented Feb 6, 2025

Version Used: 4.12.0

Steps to Reproduce:

  1. Create a simple console project that has a global.json file that specifies the 8.0.0 sdk
  2. Add a package reference to a package that contains a code analyzer/code generator that references Microsoft.CodeAnalysis.CSharp v4.12.0
  3. Run dotnet build

The CoreWCF.Primitives v1.7.0 package contains an analyzer which causes this problem.

Diagnostic Id: CS9057
The full warning message is the following:
CSC : warning CS9057: The analyzer assembly 'D:\packages\NuGet\cache\corewcf.primitives\1.7.0\analyzers\dotnet\roslyn4.0\cs\CoreWCF.BuildTools.Roslyn4.0.dll' references version '4.12.0.0' of the
compiler, which is newer than the currently running version '4.11.0.0'.

Expected Behavior:
Using the latest released Microsoft.CodeAnalysis.CSharp release should work for projects targeting all supported SDK's. When looking inside the Microsoft.CodeAnalysis.CSharp nuget package, it has an implementation in a lib/net8.0 folder, but that implementation does not work without a build warning if you have the .NET 8 SDK installed and don't have the .NET 9 SDK installed.

Actual Behavior:
A build warning (which would fail a build if treat warnings as errors is on) occurs.

If the answer is the intention is to use an older version of Microsoft.CodeAnalysis.CSharp if needing to work against older SDK's, then the current versioning scheme and discoverability is a pit of failure. There's no discoverable way to find out which version is the right one to use. Examining the package dependencies shows support for .NET 7 and .NET 8, but no explicit support for .NET 9. That provides zero insight. There's a page here listing VS releases to Roslyn versions, but no easy way to map that to .NET SDK (and that would be a convoluted method anyway). There's no correlation between the version number and the lowest .NET SDK version that's supported. The only way I could find to discover this is to look at the dotnet sdk repo source code in the Versions.props file for the various release tags. That's a lot of work for something which should be discoverable/able to be worked out inside of 30 seconds.

@huoyaoyuan
Copy link
Member

The behavior is expected because of reverse order of dependency.

Analyzer is effectively a plugin program, and it must target the lowest version of main program (the compiler, Microsoft.CodeAnalysis.CSharp in this case) it aims to support.

Examining the package dependencies shows support for .NET 7 and .NET 8, but no explicit support for .NET 9.

The target framework version of the package is a totally unrelated topic. It's about hosting the compiler as a standalone program, not loading as a plugin by the compiler version bundled with SDK.

To support .NET 8 SDK, an analyzer should target the lowest roslyn version shipped with .NET 8 SDK, which is 4.8.0 in this case.

@mconnew
Copy link
Member Author

mconnew commented Feb 7, 2025

Then the issue is the discoverability of which version to consume. There's nothing implicit in the version number to know. There's no easily findable documentation if any at all.

What's the plan if a security bug is found in 4.8.0.0? Would the expectation be that we would upgrade to 4.8.1.0? The nuget package manager tooling in that situation would be recommending to move to the latest version which would be the wrong thing. As I said, this is making it really easy to do the wrong thing, and the goal should be making the uninformed choice be the right thing.

@huoyaoyuan
Copy link
Member

Then the issue is the discoverability of which version to consume. There's nothing implicit in the version number to know. There's no easily findable documentation if any at all.

Yes, the version mapping is only obvious to those who are familiar to the release cycle. There's no documentation mentioning it.

What's the plan if a security bug is found in 4.8.0.0? Would the expectation be that we would upgrade to 4.8.1.0?

Changes in host application are not actionable to plugin programs. They only depends on the API surface of host application.
The code in the package reference doesn't matter at all, because the actual running implementation is provided by entry point (.NET SDK) that loads both application (compiler) and plugin (analyzer).

The nuget package manager tooling in that situation would be recommending to move to the latest version which would be the wrong thing.

This is true, but unfortunately it's applicable to any plugin development.

@jaredpar
Copy link
Member

Using the latest released Microsoft.CodeAnalysis.CSharp release should work for projects targeting all supported SDK's.

Unfortunately, that is not how the .NET SDK works. Analyzers and generators choose which version of Microsoft.CodeAnalysis, and hence what version of the .NET SDK, that they depend on. If they choose the latest and are then consumed in an older .NET SDK then this type of error will occur.

... but that implementation does not work without a build warning if you have the .NET 8 SDK installed and don't have the .NET 9 SDK installed.

The Microsoft.CodeAnalysis.CSharp library is a general purpose library that can be used in a variety of applications. Analyzers and generators are just one of the possible application types. Warning when consuming these from an older .NET SDK would break a significant number of scenarios for no real gain.

Then the issue is the discoverability of which version to consume.

I agree the version numbers are not intuitive and it would've been simpler if the .NET SDK used a single versioning scheme for every component inside it. Unfortunately, many of the tools in the .NET SDK dual ship in many other products and hence a universal versioning scheme is not realistic.

@jaredpar jaredpar closed this as not planned Won't fix, can't repro, duplicate, stale Feb 11, 2025
@dotnet-policy-service dotnet-policy-service bot removed the untriaged Issues and PRs which have not yet been triaged by a lead label Feb 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants