DotNET

From NixOS Wiki
Revision as of 10:37, 29 May 2023 by imported>Mdarocha (Modernize the wiki page, removing references to the old deprecated buildDotnetPackage and adding references to buildDotnetModule)

.NET packages can be built with buildDotnetModule

More information about buildDotnetModule can be found in the nixpkgs manual Example build file:

{ fetchFromGitHub
, buildDotnetModule
}:

buildDotnetModule rec {
  pname = "some_program";
  version = "some_version";

  src = fetchFromGitHub {
    owner = "some_owner";
    repo = pname;
    rev = "v${version}";
    sha256 = "";
  };

  projectFile = "SomeProject/SomeProject.csproj"

  meta = with lib; {
    homepage = "some_homepage";
    description = "some_description";
    license = licenses.mit;
  };
}

Note that the above package will not build the first time. After adding the above definition to `all-packages.nix`, you can run the package-specific `fetch-deps` script, which will generate a file containing all the nuget dependencies of the package. Build the script with nix-build -A some-package.fetch-deps, copy that generated file (the location will be printed by the script) and set the nugetDeps</cude> attribute in buildDotnetModule to point to that generated file (ie. nugetDeps = ./deps.nix).

After that the package will build normally. Remember to re-run fetch-deps every time the package is updated.

Building non-.NET Core packages

Keep in mind that building non-.NET Core projects (ie. projects that don't build using the dotnet CLI tool) is not well supported. For those projects, you have to work on a custom derivation or override the buildDotnetModule build steps.

.NET location: Not found

If running a .NET-build executable you get the above error, make sure the DOTNET_ROOT environment variable is set:

environment.sessionVariables = {
  DOTNET_ROOT = "${pkgs.dotnet-sdk}";
};

See : https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#net-sdk-and-cli-environment-variables

TargetFramework value was not recognized

error NETSDK1013: The TargetFramework value 'net6.0-windows' was not recognized. It may be misspelled. If not, then the TargetFrameworkIdentifier and/or TargetFrameworkVersion properties must be specified explicitly.

Wontfix: The project will build only on Windows.

NativeAOT

This is relevant for NixOS only.

nix-ld is needed:

{
  programs.nix-ld.enable = true;
}

Now we will need a bunch of native dependencies. Here's an example of a shell:

with import <nixpkgs> {};
pkgs.mkShell rec {

  dotnetPkg = 
    (with dotnetCorePackages; combinePackages [
      sdk_7_0
    ]);

  deps = [
    zlib
    zlib.dev
    openssl
    dotnetPkg
  ];

  NIX_LD_LIBRARY_PATH = lib.makeLibraryPath ([
    stdenv.cc.cc
  ] ++ deps);
  NIX_LD = "${pkgs.stdenv.cc.libc_bin}/bin/ld.so";
  nativeBuildInputs = [ 
  ] ++ deps;

  shellHook = ''
    DOTNET_ROOT="${dotnetPkg}";
  '';
}

Global Tools

There is currently no mechanism to install them globally, and regular (mutable) installation does not work.

Here is a proof of concept of how .NET tools could be used declaratively.

Here's an example of using that package:

packages =                                                        
  let dotnetPkg =                                                 
    (with dotnetCorePackages; combinePackages [                   
      sdk_7_0                                                     
      sdk_6_0                                                     
    ]);                                                           
    dotnetTools = (callPackage ./dotnet-tool.nix {});     # dotnet-tool.nix is the file from the link above
  in [                                                            
    vim                                                           
    firefox                                                       
    dotnetPkg                                                     
    dotnetTools.combineTools dotnetPkg (with dotnetTools.tools; [ 
                          #  ^^^^^^^^^ here we specify the dotnet package 
                          # that will be invoked for this tool
                          # Ideally, something like dotnetPkg.withTools
                          # should be there

      fsautocomplete                                      # these are tools from dotnetTools.tools;        
      csharp-ls                                           # if a package is missing, it can be declared
      dotnet-repl                                         # manually, see the sources of dotnet-tools.nix
    ])                                                            
  ];

See also