{ description = "Browser emulator for the xteink X3 (ESP32-C3) — QEMU-based, runs any firmware .bin"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self , nixpkgs , flake-utils , }: flake-utils.lib.eachDefaultSystem ( system: let pkgs = nixpkgs.legacyPackages.${system}; # Espressif's QEMU fork (ESP32-C3 SoC). Prebuilt generic-linux binary, # made runnable on NixOS with autoPatchelfHook (no FHS/bwrap needed). qemu-esp32c3 = pkgs.stdenv.mkDerivation { pname = "qemu-esp32c3"; version = "esp-develop-9.2.2-20260417"; src = pkgs.fetchurl { url = "https://github.com/espressif/qemu/releases/download/esp-develop-9.2.2-20260417/qemu-riscv32-softmmu-esp_develop_9.2.2_20260417-x86_64-linux-gnu.tar.xz"; hash = "sha256-VH8D4EcBqSy7aZ9/fQFa3B9bXvk8u5TA3ZtxB+LYTnc="; }; sourceRoot = "qemu"; nativeBuildInputs = [ pkgs.autoPatchelfHook ]; buildInputs = with pkgs; [ pixman libgcrypt SDL2 zlib libslirp stdenv.cc.cc.lib ]; installPhase = '' mkdir -p $out cp -r bin share $out/ ''; }; # `nix run .#run-upstream -- flash.bin [extra qemu args]` runScript = pkgs.writeShellScriptBin "xteink-qemu-upstream" '' flash="''${1:?usage: run [qemu args...]}"; shift || true exec ${qemu-esp32c3}/bin/qemu-system-riscv32 \ -machine esp32c3 -L ${qemu-esp32c3}/share/qemu \ -nographic -drive file="$flash",if=mtd,format=raw "$@" ''; in { packages.qemu-esp32c3 = qemu-esp32c3; packages.default = qemu-esp32c3; apps.run-upstream = { type = "app"; program = "${runScript}/bin/xteink-qemu-upstream"; }; devShells.default = pkgs.mkShell { # Reuse nixpkgs' complete QEMU build environment; Espressif's crypto # devices additionally require libgcrypt. inputsFrom = [ pkgs.qemu ]; packages = with pkgs; [ qemu-esp32c3 esptool gnumake git libgcrypt libslirp dosfstools mtools llvmPackages.clang-unwrapped lld gcc ]; }; } ); }