Did you know you can test Windows binaries on Linux using cargo test --target x86_64-pc-windows-gnu with your local Wine installation?
Unfortunately, on NixOS, this fails without proper MinGW toolchain setup - which is nontrivial to setup.
This flake fixes cross-compilation for Windows GNU targets, enabling you to test with your local Wine version - this can be handy when needing to report bugs or testing new Wine builds.
Cross-compiling Rust to *-pc-windows-gnu fails due to missing libpthreads linking. MinGW toolchains are in obscure locations and Rust can't find the required pthreads library out of the box.
This flake provides the MinGW toolchains and correct RUSTFLAGS_* environment variables to enable Windows cross-compilation with your local Wine installation.
Your system needs to be configured to automatically launch EXE files with Wine to use cargo test. Therefore you need to enable binfmt support:
# On NixOS, add to your configuration.nix:
# Allow EXE files to be automatically executed through Wine
boot.binfmt.emulatedSystems = [ "x86_64-windows" "i686-windows" ];-
Enable
binfmt- Add to configuration.nix and rebuild (see Prerequisites above) -
Add Windows targets:
# Can also be sourced from rust-overlay, etc. rustup target add x86_64-pc-windows-gnu i686-pc-windows-gnu -
Add the flake - Integrate with your development environment (see Integration Guide below)
-
Run tests:
cargo test --target x86_64-pc-windows-gnu --release cargo test --target i686-pc-windows-gnu --release
Note: i686 is currently broken until nixpkgs PR #367564 is merged.
Perfect for testing with specific Wine versions instead of the outdated Wine in cross.
lib.winGnuEnv pkgs: returns the env set to merge into any shell (merge with//).lib.winGnuPackages pkgs: returns the package list to append (e.g. MinGW toolchain).
Add as input and merge its env into your shell. Examples use flake-utils. The merge happens at the end (commented).
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
helper.url = "github:Sewer56/rust-windows-gnu-helper-flake";
};
outputs = {
self,
nixpkgs,
flake-utils,
helper,
...
}:
flake-utils.lib.eachDefaultSystem (
system: let
pkgs = import nixpkgs {inherit system;};
in {
devShells.default = pkgs.mkShell (
{
packages =
[
# your existing Rust toolchain/packages
# MERGE: append MinGW toolchain for Windows GNU target
]
++ (helper.lib.winGnuPackages pkgs);
}
# MERGE: add pthreads fix to env at the end
// (helper.lib.winGnuEnv pkgs)
);
}
);
}Use devenv.yaml additional inputs and merge in devenv.nix.
# devenv.yaml
inputs:
nixpkgs:
url: github:cachix/devenv-nixpkgs/rolling
helper:
url: github:Sewer56/rust-windows-gnu-helper-flake# devenv.nix (merge at the end)
{
pkgs,
inputs,
...
}: {
packages =
[
# your packages...
]
++ (inputs.helper.lib.winGnuPackages pkgs);
env =
{
# your env...
RUST_LOG = "debug";
}
# MERGE: add pthreads fix to env at the end
// inputs.helper.lib.winGnuEnv pkgs;
}Test examples are available in the tests/ directory:
cd tests/flake-utils-example
nix developcd tests/devenv-example
devenv shell- Keep your Rust toolchain as you prefer (rustup, nixpkgs packages, etc.).
- Add
pkgs.wineto your own shell if you want to run Windows binaries.