From 8edf5aab228d93b79e2c6b6a3f2402fffdc4c4ab Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Fri, 10 Jan 2025 09:21:00 +0100 Subject: [PATCH] windows: compile.nix fixes --- flake.lock | 1 + nix/compile.nix | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/flake.lock b/flake.lock index a8ebe3c2..8a7132ff 100644 --- a/flake.lock +++ b/flake.lock @@ -114,6 +114,7 @@ "original": { "owner": "oxalica", "repo": "rust-overlay", + "rev": "19b70f147b9c67a759e35824b241f1ed92e46694", "type": "github" } } diff --git a/nix/compile.nix b/nix/compile.nix index c9cbebd5..32f0e076 100644 --- a/nix/compile.nix +++ b/nix/compile.nix @@ -4,6 +4,52 @@ let log = v: builtins.trace v v; + targetIsWindows = target == "x86_64-w64-mingw32"; + + pkgsNative = import pkgsSrc { inherit system; }; + + # HACK: work around https://github.com/NixOS/nixpkgs/issues/177129 + # Though this is an issue between Clang and GCC, + # so it may not get fixed anytime soon... + empty-libgcc_eh = pkgsNative.stdenv.mkDerivation { + pname = "empty-libgcc_eh"; + version = "0"; + dontUnpack = true; + installPhase = '' + mkdir -p "$out"/lib + "${pkgsNative.binutils}"/bin/ar r "$out"/lib/libgcc_eh.a + ''; + }; + + # HACK: winapi contains a bunch of statically linked libraries embedded in the + # repo. Its build.rs would normally correctly find these files, but I guess + # cargo2nix gets in the way somehow. We download the repo manually so we can + # link into it. + # + # Btw... where did these static library files come from? We just trust them? + winapi-rs = pkgsNative.fetchFromGitHub { + owner = "retep998"; + repo = "winapi-rs"; + rev = "0.3.9"; # Must match the version found in Cargo.lock + hash = "sha256-/Qoz8kNsjnDEqkH/vciuzGAT1dpL7d94nbQnQh5sGQw="; + }; + + # HACK: see winapi-rs comment, same applies here but for the windows crate. + windows-rs-0-48-5 = pkgsNative.fetchFromGitHub { + owner = "microsoft"; + repo = "windows-rs"; + rev = "0.48.5"; # Must match the version found in Cargo.lock + hash = "sha256-24c1TBaNu742eZUlzo0ChVlln2tJALc8KUs+fbqP9po="; + }; + + # HACK: see winapi-rs comment, same applies here but for the windows crate. + windows-rs-0-52-0 = pkgsNative.fetchFromGitHub { + owner = "microsoft"; + repo = "windows-rs"; + rev = "0.52.0"; # Must match the version found in Cargo.lock + hash = "sha256-ZhsIAtiVPuBeNlkYnPEMrZh4FZJKnQyynXws5zv+8KI="; + }; + pkgs = if target != null then import pkgsSrc { inherit system; @@ -80,6 +126,17 @@ let # [2] hardeningDisable = [ "pie" ]; }; + + overrideArgs = old: + if targetIsWindows then { + rustcLinkFlags = old.rustcLinkFlags or [] ++ [ + "-L${pkgs.windows.pthreads}/lib" + "-L${empty-libgcc_eh}/lib" + "-L${winapi-rs}/x86_64/lib" + "-L${windows-rs-0-48-5}/crates/targets/x86_64_gnu/lib" + "-L${windows-rs-0-52-0}/crates/targets/x86_64_gnu/lib" + ]; + } else {}; }) (pkgs.rustBuilder.rustLib.makeOverride { @@ -147,9 +204,20 @@ let (pkgs.rustBuilder.rustLib.makeOverride { name = "libsodium-sys"; + overrideArgs = old: { features = [ ]; # [4] }; + + # libsodium-sys doesn't consider windows-gnu to be a "supported" build + # target, even though libsodium itself releases official mingw builds. + # Use nix's own libsodium, via a special envvar, instead. + overrideAttrs = drv: if targetIsWindows then { + setBuildEnv = '' + ${drv.setBuildEnv} + export SODIUM_LIB_DIR=${pkgs.libsodium}/lib + ''; + } else {}; }) (pkgs.rustBuilder.rustLib.makeOverride { @@ -158,6 +226,17 @@ let features = [ ]; # [4] }; }) + + (pkgs.rustBuilder.rustLib.makeOverride { + name = "timeago"; + overrideArgs = old: + if targetIsWindows then { + rustcLinkFlags = old.rustcLinkFlags or [] ++ [ + "-L${pkgs.windows.pthreads}/lib" + "-L${empty-libgcc_eh}/lib" + ]; + } else {}; + }) ]; /* We ship some parts of the code disabled by default by putting them behind a flag. @@ -204,11 +283,18 @@ let ]; # segfault with static-pie "x86_64-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static-pie" ]; + "x86_64-pc-windows-gnu" = [ + "target-feature=+crt-static" + "link-arg=-static-pie" + ]; }; + # NixOS and Rust/Cargo triples do not match for ARM, fix it here. rustTarget = if target == "armv6l-unknown-linux-musleabihf" then "arm-unknown-linux-musleabihf" + else if targetIsWindows then + "x86_64-pc-windows-gnu" else target;