Skip to content

Commit e86c4a0

Browse files
committed
Add windows cross build from linux using flake.nix
Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent d5dad4c commit e86c4a0

3 files changed

Lines changed: 98 additions & 2 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,18 @@ nix build .#uefi
206206
# Run the CLI tool directly
207207
nix run .#tool -- --help
208208

209+
# Cross-compile for Windows (from Linux, no Windows needed)
210+
nix build .#windows
211+
209212
# Run the UEFI app in QEMU
210213
nix run .#qemu
211214

212215
# Enter a development shell with all dependencies
213216
nix develop
217+
218+
# Enter a cross-compilation shell for Windows
219+
nix develop .#cross-windows
220+
cargo build --target x86_64-pc-windows-gnu -p framework_tool
214221
```
215222
216223
### Building with Cargo

flake.nix

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,23 @@
2121
# Read toolchain from rust-toolchain.toml
2222
rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
2323

24+
# Toolchain extended with Windows cross-compilation target
25+
rustToolchainWindows = rustToolchain.override {
26+
targets = [ "x86_64-pc-windows-gnu" ];
27+
};
28+
2429
# Create a custom rustPlatform with our toolchain
2530
rustPlatform = pkgs.makeRustPlatform {
2631
cargo = rustToolchain;
2732
rustc = rustToolchain;
2833
};
2934

35+
# rustPlatform with Windows cross-compilation target
36+
rustPlatformWindows = pkgs.makeRustPlatform {
37+
cargo = rustToolchainWindows;
38+
rustc = rustToolchainWindows;
39+
};
40+
3041
# Common build inputs for OS builds
3142
commonBuildInputs = with pkgs; [
3243
openssl
@@ -57,6 +68,7 @@
5768
"framework_lib"
5869
"framework_tool"
5970
"framework_uefi"
71+
"res"
6072
".cargo"
6173
];
6274
includedFiles = [
@@ -129,6 +141,60 @@
129141
LIBGIT2_NO_VENDOR = "1";
130142
};
131143

144+
# MinGW cross-compiler for Windows builds
145+
mingw = pkgs.pkgsCross.mingwW64.stdenv.cc;
146+
mingwPthreads = pkgs.pkgsCross.mingwW64.windows.pthreads;
147+
148+
# Build function for Windows cross-compilation (Linux -> Windows)
149+
buildFrameworkToolWindows = { release ? false }:
150+
let
151+
profile = if release then "release" else "debug";
152+
in
153+
rustPlatformWindows.buildRustPackage {
154+
pname = "framework_tool";
155+
version = "0.5.0";
156+
157+
src = buildSrc;
158+
159+
cargoLock = {
160+
lockFile = ./Cargo.lock;
161+
outputHashes = gitDependencyHashes;
162+
};
163+
164+
buildType = profile;
165+
buildNoDefaultFeatures = true;
166+
167+
# Disable cargo-auditable as it's incompatible with cross-compilation
168+
auditable = false;
169+
170+
buildPhase = ''
171+
runHook preBuild
172+
cargo build \
173+
${if release then "--release" else ""} \
174+
--target x86_64-pc-windows-gnu \
175+
-p framework_tool
176+
runHook postBuild
177+
'';
178+
179+
# Skip check phase - can't run .exe on Linux
180+
doCheck = false;
181+
182+
installPhase = ''
183+
runHook preInstall
184+
mkdir -p $out/bin
185+
cp target/x86_64-pc-windows-gnu/${profile}/framework_tool.exe $out/bin/
186+
runHook postInstall
187+
'';
188+
189+
nativeBuildInputs = [ mingw ];
190+
191+
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = "${mingw}/bin/x86_64-w64-mingw32-gcc";
192+
CC_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-gcc";
193+
CXX_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-g++";
194+
AR_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-ar";
195+
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L native=${mingwPthreads}/lib";
196+
};
197+
132198
# Build function for UEFI application
133199
buildFrameworkUefi = { release ? false, features ? [] }:
134200
let
@@ -186,6 +252,8 @@
186252
framework-tool-release = buildFrameworkTool { release = true; };
187253
framework-uefi-debug = buildFrameworkUefi { release = false; };
188254
framework-uefi-release = buildFrameworkUefi { release = true; };
255+
framework-tool-windows = buildFrameworkToolWindows { release = true; };
256+
framework-tool-windows-debug = buildFrameworkToolWindows { release = false; };
189257

190258
# Wrapper script to run the UEFI build in an emulator
191259
run-qemu = pkgs.writeShellScriptBin "run-framework-uefi-qemu" ''
@@ -261,6 +329,8 @@
261329
tool-debug = framework-tool-debug;
262330
uefi = framework-uefi-release;
263331
uefi-debug = framework-uefi-debug;
332+
windows = framework-tool-windows;
333+
windows-debug = framework-tool-windows-debug;
264334
run-qemu = run-qemu;
265335
run-qemu-release = run-qemu-release;
266336
};
@@ -273,6 +343,21 @@
273343
qemu-release = flake-utils.lib.mkApp { drv = run-qemu-release; };
274344
};
275345

346+
devShells.cross-windows = pkgs.mkShell {
347+
packages = [
348+
rustToolchainWindows
349+
];
350+
351+
# Ensure build scripts (e.g. libgit2-sys) use the native host compiler
352+
HOST_CC = "cc";
353+
354+
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = "${mingw}/bin/x86_64-w64-mingw32-gcc";
355+
CC_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-gcc";
356+
CXX_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-g++";
357+
AR_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-ar";
358+
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L native=${mingwPthreads}/lib";
359+
};
360+
276361
devShells.default = pkgs.mkShell {
277362
packages = with pkgs; [
278363
rustToolchain

framework_tool/build.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ fn main() {
22
// Add app icon
33
if std::env::var_os("CARGO_CFG_WINDOWS").is_some() {
44
winresource::WindowsResource::new()
5-
.set_icon("..\\res\\framework_startmenuicon.ico")
5+
.set_icon("../res/framework_startmenuicon.ico")
66
.compile()
77
.unwrap();
88
}
99

10-
if !cfg!(debug_assertions) {
10+
let is_msvc = std::env::var("CARGO_CFG_TARGET_ENV")
11+
.map(|v| v == "msvc")
12+
.unwrap_or(false);
13+
14+
if !cfg!(debug_assertions) && is_msvc {
1115
// Statically link vcruntime to allow running on clean install
1216
static_vcruntime::metabuild();
1317

0 commit comments

Comments
 (0)