NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
16.54k stars 13.02k forks source link

Cannot execute dotnet generated binary files on NixOS #166467

Open SDAChess opened 2 years ago

SDAChess commented 2 years ago

Describe the bug

When trying to execute dotnet generated binaries, the dotnet linker fails to find the root of the dotnet installation (DOTNET_ROOT).

Steps To Reproduce

Create the following files: Test.csproj

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
            <OutputType>Exe</OutputType>
            <TargetFramework>net5.0</TargetFramework>
    </PropertyGroup>

</Project>

Program.cs

using System;

class TestClass
{
    static void Main(string[] args)
    {
        Console.WriteLine(args.Length);
    }
}

Execute dotnet build to compile the "project".

Executing dotnet run works fine but ./bin/Debug/net5.0/Test crashes with the following error:

A fatal error occurred. The required library libhostfxr.so could not be found.
If this is a self-contained application, that library should exist in [/tmp/test/bin/Debug/net5.0/].
If this is a framework-dependent application, install the runtime in the global location [/usr/share/dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location or register the runtime location in [/etc/dotnet/install_location].

The .NET runtime can be found at:
  - https://aka.ms/dotnet-core-applaunch?missing_runtime=true&arch=x64&rid=nixos.21.11-x64&apphost_version=5.0.12

Setting the DOTNET_ROOT environment variable to the path given by whereis dotnet fixes the issue.

Additional context

I tested this on dotnet-sdk_5 and dotnet-sdk_6 packages and both have the same issue.

Notify maintainers

Hello, @kuznero :wave:

rissson commented 2 years ago

Can you precise which nixpkgs version (ideally the commit) you tested this on?

SDAChess commented 2 years ago
21.11.336103.40ef692a55b

If that is what you are looking for?

mdarocha commented 2 years ago

Well, as you see in the error, dotnet-sdk expects the framework to be found under /usr. This won't work on NixOS, since it doesn't use the standard FHS.

I see several approaches to fix this:

  1. Just use dotnet <your-app>.dll. Every dotnet build generates a native binary and a platform-independant .dll file, which contains all logic. In the default framework-dependant build, the native binary does the equivalent to running dotnet <your-app>.dll
  2. Configure your system to set either DOTNET_ROOT or install_location. This can be made into a NixOS module. But I don't think this fits the existing NixOS modules - no other compiler has a module, and I don't think global installation of such tools should be encouraged (instead using per-project shell.nix or similar)
  3. Patch the SDK available in nixpkgs to generate binaries that are capable of finding the proper dotnet folder. This hovewer brings a lot of downsides - having to maintain complicated patches, and this will make dotnet applications generated on nixos different from the ones generated with main dotnet sdk. This will also require us to build SDK from source.
mdarocha commented 1 year ago

The workaround to this problem should probably be better documented in the nixpkgs manual.

YoshiRulz commented 9 months ago

Configure your system to set [...] DOTNET_ROOT [...] using per-project shell.nix or similar

Something like this?

pkgs.mkShell {
    packages = [ pkgs.dotnet-sdk ]; # including dotnet-runtime here means the CLI is its copy and it doesn't see the SDK...
    shellHook = ''export DOTNET_ROOT="${pkgs.dotnet-runtime}"'';
}

Can't the dotnet-runtime package include a hook for this in /nix-support?

mdarocha commented 9 months ago

Configure your system to set [...] DOTNET_ROOT [...] using per-project shell.nix or similar

Something like this?

pkgs.mkShell {
  packages = [ pkgs.dotnet-sdk ]; # including dotnet-runtime here means the CLI is its copy and it doesn't see the SDK...
  shellHook = ''export DOTNET_ROOT="${pkgs.dotnet-runtime}"'';
}

Can't the dotnet-runtime package include a hook for this in /nix-support?

Yup, something like this.

Adding it to a setup hook seems like a good idea that might make dev shells easier to work with. Dunno if it will affect packages installed with nix-env or nixosConfiguration, and if it will break any packages in nixpkgs. You can still make a PR and we'll test it out.