Recently, I’ve been trying to cross-compile a .NET application for Windows using a Nix derivation, but I haven’t been able to get it working.
Normally, this would be straightforward with:
dotnet publish -r win-x64
However, I want to build it through my Nix derivation instead.
From what I’ve read about cross-compilation in Nix, it should look something like this:
toworkWin = let
winPkgs = pkgs.pkgsCross.mingwW64;
in
winPkgs.callPackage ./towork.nix {};
It’s worth noting that towork.nix is just a buildDotnetModule derivation.
When I try to build it, I get the following error:
error: Missing source (url and hash) for host RID: win-x64
I also tried modifying dotnetBuildFlags to manually add -r win-x64, but that did not work either. The build failed because buildDotnetModule was already passing a -r option internally, resulting in an error saying that multiple -r options were provided.
Even if that had worked, I would rather avoid hardcoding win-x64 directly in the derivation, since that would break the flake system abstraction and feel like a very clunky way to “cross-compile”.
To work around the missing RID issue, I then tried using dotnetCorePackages from the native pkgs set instead of winPkgs, since the native package set includes support for the win-x64 RID:
toworkWin = let
winPkgs = pkgs.pkgsCross.mingwW64;
in
winPkgs.callPackage ./towork.nix {
inherit (pkgs) dotnetCorePackages;
};
However, that also fails, this time while building which for MinGW:
error: Cannot build '/nix/store/7axj21lp5x00qbsldk8l4waq7h3y5jmn-which-x86_64-w64-mingw32-2.23.drv'.
Reason: builder failed with exit code 2.
...
which.c:534:36: error: implicit declaration of function 'geteuid'; did you mean 'getpid'? [-Wimplicit-function-declaration]
534 | show_tilde = (!tty_only && geteuid() != superuser);
| ^~~~~~~
| getpid
Am I approaching .NET cross-compilation in Nix incorrectly? Is there a proper way to build a buildDotnetModule package targeting win-x64 without running into these issues?