From a4f127f1399d62f68fc123e630e0abba16ef5b96 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 6 Mar 2026 11:48:18 +0800 Subject: [PATCH 1/2] Remove .envrc Switched over to nix flakes Signed-off-by: Daniel Schaefer --- .envrc | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .envrc diff --git a/.envrc b/.envrc deleted file mode 100644 index 30da14fd..00000000 --- a/.envrc +++ /dev/null @@ -1,5 +0,0 @@ -export DIRENV_WARN_TIMEOUT=20s - -eval "$(devenv direnvrc)" - -use devenv From 2baa94d628c601ad60db37d2795628645d1dfc74 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 6 Mar 2026 11:47:31 +0800 Subject: [PATCH 2/2] Add windows cross build from linux using flake.nix Signed-off-by: Daniel Schaefer --- README.md | 7 ++++ flake.nix | 85 +++++++++++++++++++++++++++++++++++++++++ framework_tool/build.rs | 8 +++- 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0e88c5bf..2d1641ca 100644 --- a/README.md +++ b/README.md @@ -206,11 +206,18 @@ nix build .#uefi # Run the CLI tool directly nix run .#tool -- --help +# Cross-compile for Windows (from Linux, no Windows needed) +nix build .#windows + # Run the UEFI app in QEMU nix run .#qemu # Enter a development shell with all dependencies nix develop + +# Enter a cross-compilation shell for Windows +nix develop .#cross-windows +cargo build --target x86_64-pc-windows-gnu -p framework_tool ``` ### Building with Cargo diff --git a/flake.nix b/flake.nix index 0aa9abf6..c42a9162 100644 --- a/flake.nix +++ b/flake.nix @@ -21,12 +21,23 @@ # Read toolchain from rust-toolchain.toml rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + # Toolchain extended with Windows cross-compilation target + rustToolchainWindows = rustToolchain.override { + targets = [ "x86_64-pc-windows-gnu" ]; + }; + # Create a custom rustPlatform with our toolchain rustPlatform = pkgs.makeRustPlatform { cargo = rustToolchain; rustc = rustToolchain; }; + # rustPlatform with Windows cross-compilation target + rustPlatformWindows = pkgs.makeRustPlatform { + cargo = rustToolchainWindows; + rustc = rustToolchainWindows; + }; + # Common build inputs for OS builds commonBuildInputs = with pkgs; [ openssl @@ -57,6 +68,7 @@ "framework_lib" "framework_tool" "framework_uefi" + "res" ".cargo" ]; includedFiles = [ @@ -129,6 +141,60 @@ LIBGIT2_NO_VENDOR = "1"; }; + # MinGW cross-compiler for Windows builds + mingw = pkgs.pkgsCross.mingwW64.stdenv.cc; + mingwPthreads = pkgs.pkgsCross.mingwW64.windows.pthreads; + + # Build function for Windows cross-compilation (Linux -> Windows) + buildFrameworkToolWindows = { release ? false }: + let + profile = if release then "release" else "debug"; + in + rustPlatformWindows.buildRustPackage { + pname = "framework_tool"; + version = "0.5.0"; + + src = buildSrc; + + cargoLock = { + lockFile = ./Cargo.lock; + outputHashes = gitDependencyHashes; + }; + + buildType = profile; + buildNoDefaultFeatures = true; + + # Disable cargo-auditable as it's incompatible with cross-compilation + auditable = false; + + buildPhase = '' + runHook preBuild + cargo build \ + ${if release then "--release" else ""} \ + --target x86_64-pc-windows-gnu \ + -p framework_tool + runHook postBuild + ''; + + # Skip check phase - can't run .exe on Linux + doCheck = false; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp target/x86_64-pc-windows-gnu/${profile}/framework_tool.exe $out/bin/ + runHook postInstall + ''; + + nativeBuildInputs = [ mingw ]; + + CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = "${mingw}/bin/x86_64-w64-mingw32-gcc"; + CC_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-gcc"; + CXX_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-g++"; + AR_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-ar"; + CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L native=${mingwPthreads}/lib"; + }; + # Build function for UEFI application buildFrameworkUefi = { release ? false, features ? [] }: let @@ -186,6 +252,8 @@ framework-tool-release = buildFrameworkTool { release = true; }; framework-uefi-debug = buildFrameworkUefi { release = false; }; framework-uefi-release = buildFrameworkUefi { release = true; }; + framework-tool-windows = buildFrameworkToolWindows { release = true; }; + framework-tool-windows-debug = buildFrameworkToolWindows { release = false; }; # Wrapper script to run the UEFI build in an emulator run-qemu = pkgs.writeShellScriptBin "run-framework-uefi-qemu" '' @@ -261,6 +329,8 @@ tool-debug = framework-tool-debug; uefi = framework-uefi-release; uefi-debug = framework-uefi-debug; + windows = framework-tool-windows; + windows-debug = framework-tool-windows-debug; run-qemu = run-qemu; run-qemu-release = run-qemu-release; }; @@ -273,6 +343,21 @@ qemu-release = flake-utils.lib.mkApp { drv = run-qemu-release; }; }; + devShells.cross-windows = pkgs.mkShell { + packages = [ + rustToolchainWindows + ]; + + # Ensure build scripts (e.g. libgit2-sys) use the native host compiler + HOST_CC = "cc"; + + CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = "${mingw}/bin/x86_64-w64-mingw32-gcc"; + CC_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-gcc"; + CXX_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-g++"; + AR_x86_64_pc_windows_gnu = "${mingw}/bin/x86_64-w64-mingw32-ar"; + CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L native=${mingwPthreads}/lib"; + }; + devShells.default = pkgs.mkShell { packages = with pkgs; [ rustToolchain diff --git a/framework_tool/build.rs b/framework_tool/build.rs index 87d2140e..cc4c1096 100644 --- a/framework_tool/build.rs +++ b/framework_tool/build.rs @@ -2,12 +2,16 @@ fn main() { // Add app icon if std::env::var_os("CARGO_CFG_WINDOWS").is_some() { winresource::WindowsResource::new() - .set_icon("..\\res\\framework_startmenuicon.ico") + .set_icon("../res/framework_startmenuicon.ico") .compile() .unwrap(); } - if !cfg!(debug_assertions) { + let is_msvc = std::env::var("CARGO_CFG_TARGET_ENV") + .map(|v| v == "msvc") + .unwrap_or(false); + + if !cfg!(debug_assertions) && is_msvc { // Statically link vcruntime to allow running on clean install static_vcruntime::metabuild();