Skip to content

Convert language server project into .NET tool#82154

Merged
dibarbet merged 3 commits intodotnet:mainfrom
dibarbet:tool
Jan 28, 2026
Merged

Convert language server project into .NET tool#82154
dibarbet merged 3 commits intodotnet:mainfrom
dibarbet:tool

Conversation

@dibarbet
Copy link
Member

@dibarbet dibarbet commented Jan 26, 2026

Enable the language server to be published and consumed as a .NET tool. This simplifies publishing (removing custom targets) and simplifies consumption as a plugin

Both the tool package name and command used to invoke it will be roslyn-language-server
e.g.
dotnet tool install roslyn-language-server
dotnet tool run roslyn-language-server

@dibarbet dibarbet requested a review from a team as a code owner January 26, 2026 20:23
@CyrusNajmabadi
Copy link
Contributor

Love the simplification. Could you put something in the PR stating why this is being done?

@CyrusNajmabadi
Copy link
Contributor

a simple dotnet tool install command

Nice! what would be put in the <tool> part in this case?

@dibarbet
Copy link
Member Author

Nice! what would be put in the <tool> part in this case?

Currently under bikeshedding 😆

Tentatively thinking roslyn-ls but we're open to other ideas. In this PR right now its Microsoft.CodeAnalysis.LanguageServer

@dibarbet dibarbet requested a review from a team as a code owner January 27, 2026 01:50
Verify that the SymbolPublishingExclusionsFile.txt contains the required entries for the native SQLite library.
These don't have symbols we need to publish and they cause symbol check to fail.
-->
<Target Name="ValidateSymbolPublishingExclusions"
Copy link
Member Author

Choose a reason for hiding this comment

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

SymbolPublishingExclusionsFile excludes a couple of binaries that we don't own from symbol publishing (they cause symbol check to fail with cryptic errors). Exclusion is based on the path in the nuget package.

Previously that path was quite static, but .NET tool packaging includes the tfm in that path. This target ensures the path in SymbolPublishingExclusionsFile matches the TFM, with a nice error message.

@dibarbet
Copy link
Member Author

@jasonmalinowski this has changed a bit, so probably should get a re-review

<IsPackable>true</IsPackable>
<PackAsTool>true</PackAsTool>
<PackageId>roslyn-language-server</PackageId>
<ToolCommandName>roslyn-language-server</ToolCommandName>
Copy link
Member Author

@dibarbet dibarbet Jan 27, 2026

Choose a reason for hiding this comment

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

The user visible nuget package and tool command will both be roslyn-language-server.

The project name here and the actual executable will still be Microsoft.CodeAnalysis.LanguageServer - I did not rename those as

  1. Generally they aren't user visible (other than the process name)
  2. Its a more complicated with outside impacts (e.g. telemetry).

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks. roslyn-language-server makes sense to me :)

dibarbet added a commit that referenced this pull request Feb 12, 2026
#82387)

Mono runtime does not support ReadyToRun compilation. VMR builds with
Mono were failing with `NETSDK1094: Unable to optimize assemblies for
performance` because `PublishReadyToRun` was unconditionally enabled for
Release builds.

## Changes

- Add `DotNetBuildUseMonoRuntime` check to `PublishReadyToRun` condition
in LanguageServer project
- R2R remains enabled for Release builds with standard runtimes
- R2R is now disabled when building with Mono runtime

```xml
<!-- Before -->
<PublishReadyToRun Condition="'$(Configuration)' == 'Release' ">true</PublishReadyToRun>

<!-- After -->
<PublishReadyToRun Condition="'$(Configuration)' == 'Release' AND '$(DotNetBuildUseMonoRuntime)' != 'true' ">true</PublishReadyToRun>
```

> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `bcnvsblobprodcus378.vsblob.vsassets.io`
> - Triggering command: `/usr/share/dotnet/dotnet
/usr/share/dotnet/dotnet
/usr/share/dotnet/sdk/10.0.102/NuGet.Build.Tasks.Console.dll
Recursive=True;CleanupAssetsForUnsupportedProjects=True;DisableParallel=False;Force=False;ForceEvaluate=False;HideWarningsAndErrors=False;IgnoreFailedSources=False;Interactive=False;NoCache=False;NoHttpCache=False;RestorePackagesConfig=False
/usr/share/dotnet/sdk/10.0.102/MSBuild.dll
/home/REDACTED/work/roslyn/roslyn/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Microsoft.CodeAnalysis.LanguageServer.csproj
Configuration=Release;NuGetInteractive=false;EnableDefaultCompileItems=false;EnableDefaultEmbeddedResourceItems=false;EnableDefaultNoneItems=false;MSBuildRestoreSessionId=7ffb2b8c-a068-4049-94e1-0a9559ccf395;MSBuildIsRestoring=True;ExcludeRestorePackageIm`
(dns block)
> - `vb4vsblobprodcus33.vsblob.vsassets.io`
> - Triggering command: `/usr/share/dotnet/dotnet dotnet build
src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Microsoft.CodeAnalysis.LanguageServer.csproj
-c Release` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/dotnet/roslyn/settings/copilot/coding_agent)
(admins only)
>
> </details>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Mono builds fail due to missing R2R while compiling
Roslyn</issue_title>
> <issue_description>Mono builds don't do R2R. The vmr builds started
failing because Roslyn tries to find a pack for doing R2R:
> 
> ```
>
/home/tester/workdir/dotnet/sdk/sdk/11.0.100-preview.2.26081.104/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(122,5):
error NETSDK1094: Unable to optimize assemblies for performance: a valid
runtime package was not found. Either set the PublishReadyToRun property
to false, or use a supported runtime identifier when publishing. When
targeting .NET 6 or higher, make sure to restore packages with the
PublishReadyToRun property set to true.
[/home/tester/workdir/dotnet/src/roslyn/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Microsoft.CodeAnalysis.LanguageServer.csproj]
> ```
> The regression probably happened in
#82154 where `PublishReadyToRun`
changed from:
> ```
> <PublishReadyToRun Condition="'$(RuntimeIdentifier)' != '' AND
'$(Configuration)' == 'Release' ">true</PublishReadyToRun>
> ```
> to
> ```
> <PublishReadyToRun Condition="'$(Configuration)' == 'Release'
">true</PublishReadyToRun>
> ```
> 
> cc @ViktorHofer @dibarbet @omajid </issue_description>
> 
> <agent_instructions>please fix this by checking
DotNetBuildUseMonoRuntime before r2r publishing in the roslyn language
server</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@dibarbet</author><body>
> > can we change back to include the `'$(RuntimeIdentifier)' != ''`?
> 
> If I recall correctly, no, with the runtimeidentifier check publishing
as a tool did not correctly run R2R.
> 
> > If not, we need to handle the Mono case specially (using
DotNetBuildUseMonoRuntime)?
> 
> @tmds to confirm, you mean in the condition check to make sure
`DotNetBuildUseMonoRuntime` is not true before setting
`PublishReadyToRun`?
> </body></comment_new>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #82385

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/dotnet/roslyn/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
@akhera99 akhera99 modified the milestones: Next, 18.5 Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants