Cross Compile Rust for Windows

Hi,

I’m trying to set up a nix-shell that can compile rust programs for windows. I mostly followed this guide but with the addition of the x86_64-pc-windows-gnu cargo target. When I try to use cargo to build for this target I get the following error:

error: linker `x86_64-w64-mingw32-gcc` not found
  |
  = note: No such file or directory (os error 2)

error: aborting due to previous error

To try and fix this I added pkgs.pkgsCross.mingwW64.gcc to my shell.nix's buildInputs. After a long compilation attempt my nix-shell command fails with the below:

configure: error: could not determine how to read list of mounted file systems
builder for '/nix/store/zmd8lg97kbq3k1f8qn8503ikzbmw3c4c-coreutils-8.31-x86_64-w64-mingw32.drv' failed with exit code 1
cannot build derivation '/nix/store/1avnd47l9pz81lz09zf2awg343a2fwxy-gcc-debug-wrapper-8.3.0.drv': 1 dependencies couldn't be built
error: build of '/nix/store/1avnd47l9pz81lz09zf2awg343a2fwxy-gcc-debug-wrapper-8.3.0.drv' failed

What is the best way to make a mingw linker available for cargo to build windows binaries?

5 Likes

Is this a sensible question?

Maybe to reduce the scope of my question, is there a way to install a mingw compatible compiler on Nix? If I can do that maybe I can figure out how to get a similar thing working with the rust overlay.

1 Like

The nix-shell file looks like this:

with import <nixpkgs> {
  crossSystem = {
    config = "x86_64-w64-mingw32";
  };
};

mkShell {
  # buildInputs = [ zlib ];
}

Install the toolchain with rustup:

rustup toolchain install stable-x86_64-pc-windows-gnu

Put in .cargo/config the following lines:

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"

Sorry, I haven’t updated this in a while.

My equivalent nix-shell (using Niv, and the Mozilla overlay) is:

let 
  sources = import ./nix/sources.nix;
  rust = import ./nix/rust.nix{inherit sources;};
  pkgs = (import <nixpkgs>{ crossSystem = {config = "x86_64-w64-mingw32";}; });
in 
  pkgs.mkShell {
    nativeBuildInputs = [ rust ];
  }

And a rust.nix:

{sources ? import ./sources.nix}:
let
  pkgs = import sources.nixpkgs{ overlays = [ (import sources.nixpkgs-mozilla) ]; };
  channel = "nightly";
  date = "2020-10-14";
  targets = [ "x86_64-pc-windows-gnu" ];
  chan = (pkgs.rustChannelOfTargets channel date targets);
in chan

My .cargo/config is identical to yours, and after entering the shell I cans see that the corresponding compiler does exist in the path:


which x86_64-w64-mingw32-gcc /nix/store/ir564pg2s96nmrc3xlvfh065wk9hblj6-x86_64-w64-mingw32-stage-final-gcc-debug-wrapper-8.3.0/bin/x86_64-w64-mingw32-gcc

This gets me a shell with a mingw compiler and a rust toolchain. I can build native Linux executables fine. However, when I try to cross-compile for x86_64-pc-windows-gnu I get a linker error related to pthreads:


= note: /nix/store/n8rscm777z53g1cg6knwwphik3aprx6j-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: cannot find -l:libpthread.a collect2: error: ld returned 1 exit status

error: aborting due to previous error; 2 warnings emitted


This pthreads issue is where I’ve been stuck for the past couple days. It’s also not clear to me why cargo seems to still be linking with ld instead of gcc despite .cargo/config. Any ideas?

1 Like

Make sure to include pkgs-mingw.windows.mingw_w64_pthreads in your buildInputs (NOT nativeBuildInputs). That finally got the pthreads thing to work for me.

1 Like

I am having this same problem.
When i add mingw_w64_pthreads:

 note: /nix/store/na3khzhlqiq89pf75hmys8icr3qxgy13-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: cannot find -l:libpthread.a
          collect2: error: ld returned 1 exit status

When i also add statndard windows.pthreads:
(it goes on and on, this is just the end.)

          /nix/store/na3khzhlqiq89pf75hmys8icr3qxgy13-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: /home/eli/Desktop/Code/Rust/vdcp-spoof/target/x86_64-pc-windows-gnu/release/deps/libring-ba44c9cabb44a5a9.rlib(ring-ba44c9cabb44a5a9.ring.dtsgsr3y-cgu.0.rcgu.o):ring.dtsgsr3y-cgu.:(.text+0x34fb): undefined reference to `LIMBS_less_than'
          /nix/store/na3khzhlqiq89pf75hmys8icr3qxgy13-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: /home/eli/Desktop/Code/Rust/vdcp-spoof/target/x86_64-pc-windows-gnu/release/deps/libring-ba44c9cabb44a5a9.rlib(ring-ba44c9cabb44a5a9.ring.dtsgsr3y-cgu.0.rcgu.o):ring.dtsgsr3y-cgu.:(.text+0x352c): undefined reference to `GFp_bn_from_montgomery_in_place'
          collect2: error: ld returned 1 exit status

Any ideas?