Omnisharp-roslyn: Omnisharp does not find Unity3D assemblies

Created on 17 Sep 2020  路  20Comments  路  Source: OmniSharp/omnisharp-roslyn

Hello,

I am trying to get Omnisharp to work with a Unity3D project on GNU/Linux (Kubuntu 20.04). My editor is Neovim 0.5 (pre-release) which includes its own LSP client. Neovim downloaded the latest Omnisharp release (1.37.1). The server is working, I am getting diagnostic messages, documentation and code completion, but it acts as if it does not know anything about Unity.

  • mono --version shows 6.8.0.105 for the globally installed Mono
  • The launch command used by Neovim is ~/.cache/nvim/nvim_lsp/omnisharp/run --languageserver --hostPID <PID of Neovim process>

I would assume that Omnisharp uses its bundled Mono. How can I get Omnisharp to produce log files, and where can I find them?

Screenshot_20200917_183504

mono unity

Most helpful comment

Thank you everyone for your input. To summarize, the issue is that the bundled Mono cannot find any 3rd party assemblies at all. It is the responsibility of the client to start the server with a global Mono installation. I have for now modified the run script to change one variable:

bin_dir=/usr/bin  # Previous value: ${base_dir}/bin

That way when the run script starts the server ("${mono_cmd}" "${omnisharp_cmd}" "$@") it will use usr/bin/mono as the Mono binary.

Now the next question is how to tell the server which Mono to use. From looking at the run script there does not appear to be any way of passing a command-line option or environment variable to the script. So I figure the best course of action would be to forego the run script altogether and just invoke mono and omnisharp directly. From the looks of it the script does not really do much anyway.

Is this the correct way? From what I can understand the VS Code plugin does the same. Please correct me if I'm wrong, I don't actually know TypeScript, so I'm just taking an educated step.

Screenshot_20200921_190746

All 20 comments

My ultimate goal is nearly the same : use emacs+lsp on Unity files. (see #1947)
I got some debug by manually running omnisharp with ./run -s <project_root_path> -v > logfile (and then killing the server process once messages where logged in the file). Not sure it is the best way.

Go to /usr/lib/mono and check what the latest version you have, then set FrameworkPathOverride to point to that folder.

For me it's worked setting it to both /usr/lib/mono/4.5 and /usr/lib/mono/4.8-api.

export FrameworkPathOverride=/lib/mono/4.5

I have not yet tried this solution (and I will) but..
I did manage to get it working on Emacs by modifying the run script in omnisharp-roselyn to take into account the globally installed mono if present and if the version is high enough.

Everything is here : https://github.com/emacs-lsp/lsp-mode/issues/2188#issuecomment-694945601

I have the issue with emacs lsp-mode, @razzmatazz do you know what could it be?

I have the issue with emacs lsp-mode, @razzmatazz do you know what could it be?

I am afraid I have no experience with Unity. My question is, does vscode manage to do it better, and if they do (and they are by far the most popular client for omnisharp-roslyn IMHO) -- then we can replicate the solutions in lsp-mode by looking at the workarounds/framework/mono discovery code VS Code does.

When OmniSharp starts on its own embedded Mono it will have no reference assemblies for desktop ..NET and Unity and other non-.NET Core development won't work or be limited.

In VS Code there is a setting to start OmniSharp on global Mono instead and that allows full compatibility with all desktop .NET development. I would imagine in this case a setting like this is needed too.

However, I don't think this is an issue for OmniSharp itself as it already provides the necessary tools for achieving this - it's just the client must make the decisions, therefore I would recommend to move this issue to the client implementation(s).

How does VSCode do this, @filipw? Is it a command line flag passed to the server? Or are you referring to omnisharp.json settings?

On VS code (Linux), I tried playing with setting ALWAYS use global mono and setting the path to the global mono (it is done via a .json file) and then restart the server several times (with the command palette of VS code). But it does not work : Unity referenced functions/classes are not recognized.

With Emacs (Linux, and my run file), it works in two steps : open the .cs file -> server started once with global mono. Then, I restart the server from Emacs (using lsp-mode) and it work.

So, I guess the issus is client depend, sadly...

@nickspoons there is a setting omnisharp.useGlobalMono which can be set to always. It then uses global Mono form the PATH to start OmniSharp.exe process. Additionally a custom path can be provided too. https://github.com/OmniSharp/omnisharp-vscode/blob/97768562a4f950db687d5d9314da4a854c9e6f4c/src/omnisharp/launcher.ts#L264-L277

@snowgoon88 if you have trouble with VS Code, please open an issue in https://github.com/OmniSharp/omnisharp-vscode and provide your OmniSharp log with omnisharp.logginglevel: "debug" enabled.

Thanks for the help everybody, I tested with emacs and vscode using the useGlobalMono and pointing to mono6 path, but it didn't work too, but I think it's my OS's fault. I use NixOS, and my mono global installation does not have msbuild updated.

ah that could be - not every mono distro has MSBuild bundled

Thank you everyone for your input. To summarize, the issue is that the bundled Mono cannot find any 3rd party assemblies at all. It is the responsibility of the client to start the server with a global Mono installation. I have for now modified the run script to change one variable:

bin_dir=/usr/bin  # Previous value: ${base_dir}/bin

That way when the run script starts the server ("${mono_cmd}" "${omnisharp_cmd}" "$@") it will use usr/bin/mono as the Mono binary.

Now the next question is how to tell the server which Mono to use. From looking at the run script there does not appear to be any way of passing a command-line option or environment variable to the script. So I figure the best course of action would be to forego the run script altogether and just invoke mono and omnisharp directly. From the looks of it the script does not really do much anyway.

Is this the correct way? From what I can understand the VS Code plugin does the same. Please correct me if I'm wrong, I don't actually know TypeScript, so I'm just taking an educated step.

Screenshot_20200921_190746

For NixOS users I fixed with this: https://github.com/NixOS/nixpkgs/pull/98435, basically, the msbuild inside the omnisharp does not work for unity, that's why using a global mono works for everybody.
Thanks for the help @filipw

I will close this because at the end, this is by design - OmniSharp doesn't ship with reference assemblies for .NET Framework. we will add a better error message in https://github.com/OmniSharp/omnisharp-roslyn/issues/2029 so that it's clear that full Mono is needed when reference assemblies are not found

@nickspoons there is a setting omnisharp.useGlobalMono which can be set to always. It then uses global Mono form the PATH to start OmniSharp.exe process. Additionally a custom path can be provided too. https://github.com/OmniSharp/omnisharp-vscode/blob/97768562a4f950db687d5d9314da4a854c9e6f4c/src/omnisharp/launcher.ts#L264-L277

Is that setting part of the configuration for omnisharp-roslyn? I don't see it documented on the configuration page: https://github.com/OmniSharp/omnisharp-roslyn/wiki/Configuration-Options

Or is it VSCode specific or something else?

@axelson That's a VSCode setting, regarding how the OmniSharp-roslyn process is started.

Is there a way of setting this option outside of VSCode as well? Like a command-line parameter, environment variable or configuration file?

Hi I'm on Windows using nvim lspconfig omnisharp language server. It doesn't recognize the assemblies as well. When loading a basic script it says that it couldn't find monobehavior class

@HiPhish Thanks!

Mono binaries on latest MacOS's are installed elsewhere..
Thought I post it here as it could be of any help for others.

bin_dir=/Library/Frameworks/Mono.framework/Versions/Current/bin

Schermafbeelding 2021-02-03 om 23 47 35

Note: Unity doesn't generate _.sln_ and _.csproj_ files. So for _Neovim_ you have to create them yourself, in case of new projects. Or open a _.cs_ file in VS or Rider and let them auto generate it for you.

Was this page helpful?
0 / 5 - 0 ratings