{ pkgs }:
let
  msys2-env = pkgs.stdenvNoCC.mkDerivation rec {
    name = "msys2-env";
    srcs = import ./msys2_packages.nix { inherit pkgs; };
    buildInputs = [ pkgs.gnutar pkgs.zstd ];
    phases = [ "installPhase" ];
    installPhase = (pkgs.lib.strings.concatStringsSep "\n" (["mkdir $out"] ++ (map (p: "tar xvf ${p} -C $out") srcs)));
  };
  silenceFontconfig = # silence flood of "Fontconfig error: Cannot load default config file: No such file: (null)"
    ''
    export FONTCONFIG_PATH=$HOME/fonts
    mkdir $FONTCONFIG_PATH
    cat > $FONTCONFIG_PATH/fonts.conf << EOF
    <fontconfig>
    </fontconfig>
    EOF
    '';
  pyo3-mingw-config = pkgs.writeTextFile {
    name = "pyo3-mingw-config";
    text =
      ''
      implementation=CPython
      version=3.11
      shared=true
      abi3=false
      lib_name=python3.11
      lib_dir=${msys2-env}/clang64/lib
      pointer_width=64
      build_flags=WITH_THREAD
      suppress_build_script_link_lines=false
      '';
  };
in rec {
  llvm-nac3 = pkgs.stdenvNoCC.mkDerivation rec {
    pname = "llvm-nac3-msys2";
    version = "14.0.6";
    src-llvm = pkgs.fetchurl {
      url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-${version}.src.tar.xz";
      sha256 = "sha256-BQki7KrKV4H99mMeqSvHFRg/IC+dLxUUcibwI0FPYZo=";
    };
    src-clang = pkgs.fetchurl {
      url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/clang-${version}.src.tar.xz";
      sha256 = "sha256-K1hHtqYxGLnv5chVSDY8gf/glrZsOzZ16VPiY0KuQDE=";
    };
    buildInputs = [ pkgs.wineWowPackages.stable ];
    phases = [ "unpackPhase" "patchPhase" "configurePhase" "buildPhase" "installPhase" ];
    unpackPhase =
      ''
      mkdir llvm
      tar xf ${src-llvm} -C llvm --strip-components=1
      mv llvm/Modules/* llvm/cmake/modules  # work around https://github.com/llvm/llvm-project/issues/53281
      mkdir clang
      tar xf ${src-clang} -C clang --strip-components=1
      cd llvm
      # build of llvm-lto fails and -DLLVM_BUILD_TOOLS=OFF does not disable it reliably because cmake
      rm -rf tools/lto
      '';
    patches = [ ../llvm/llvm-future-riscv-abi.diff ];
    configurePhase =
      ''
      export HOME=`mktemp -d`
      export WINEDEBUG=-all
      export WINEPATH=Z:${msys2-env}/clang64/bin
      ${silenceFontconfig}
      mkdir build
      cd build
      wine64 cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_UNWIND_TABLES=OFF -DLLVM_ENABLE_THREADS=ON -DLLVM_TARGETS_TO_BUILD=X86\;ARM\;RISCV -DLLVM_LINK_LLVM_DYLIB=OFF -DLLVM_ENABLE_FFI=OFF -DFFI_INCLUDE_DIR=fck-cmake -DFFI_LIBRARY_DIR=fck-cmake -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_INSTALL_PREFIX=Z:$out
      '';
    buildPhase =
      ''
      wine64 ninja -j $NIX_BUILD_CORES
      '';
    installPhase =
      ''
      wine64 ninja install
      '';
    dontFixup = true;
  };
  llvm-tools-irrt = pkgs.runCommandNoCC "llvm-tools-irrt" {}
    ''
    mkdir -p $out/bin
    ln -s ${llvm-nac3}/bin/clang.exe $out/bin/clang-irrt.exe
    ln -s ${llvm-nac3}/bin/llvm-as.exe $out/bin/llvm-as-irrt.exe
    '';
  nac3artiq = pkgs.rustPlatform.buildRustPackage {
    name = "nac3artiq-msys2";
    src = ../../.;
    cargoLock = {
      lockFile = ../../Cargo.lock;
    };
    nativeBuildInputs = [ pkgs.wineWowPackages.stable ];
    buildPhase =
      ''
      export HOME=`mktemp -d`
      export WINEDEBUG=-all
      export WINEPATH=Z:${msys2-env}/clang64/bin\;Z:${llvm-nac3}/bin\;Z:${llvm-tools-irrt}/bin
      ${silenceFontconfig}
      export PYO3_CONFIG_FILE=Z:${pyo3-mingw-config}
      export CC=clang
      export LLVM_SYS_140_PREFIX=Z:${llvm-nac3}
      wine64 cargo build --release -p nac3artiq
      '';
    installPhase =
      ''
      mkdir $out $out/nix-support
      cp target/release/nac3artiq.dll $out/nac3artiq.pyd
      echo file binary-dist $out/nac3artiq.pyd >> $out/nix-support/hydra-build-products
      '';
    doCheck = false;  # https://git.m-labs.hk/M-Labs/nac3/issues/358
    checkPhase =
      ''
      wine64 cargo test --release
      '';
    dontFixup = true;
  };
  nac3artiq-pkg = pkgs.stdenvNoCC.mkDerivation {
    name = "nac3artiq-msys2-pkg";
    nativeBuildInputs = [ pkgs.pacman pkgs.fakeroot pkgs.libarchive pkgs.zstd ];
    src = nac3artiq;
    phases = [ "buildPhase" "installPhase" ];
    buildPhase =
      ''
      ln -s ${./PKGBUILD} PKGBUILD
      ln -s $src/nac3artiq.pyd nac3artiq.pyd
      makepkg --config ${./makepkg.conf} --nodeps
      '';
    installPhase =
      ''
      mkdir $out $out/nix-support
      cp *.pkg.tar.zst $out
      echo file msys2 $out/*.pkg.tar.zst >> $out/nix-support/hydra-build-products
      '';
  };
  wine-msys2 = pkgs.writeShellScriptBin "wine-msys2"
    ''
    export WINEDEBUG=-all
    export WINEPATH=Z:${msys2-env}/clang64/bin\;Z:${llvm-nac3}/bin\;Z:${llvm-tools-irrt}/bin
    export PYO3_CONFIG_FILE=Z:${pyo3-mingw-config}
    exec ${pkgs.wineWowPackages.stable}/bin/wine64 cmd
    '';
  wine-msys2-build = pkgs.writeShellScriptBin "wine-msys2-build"
    ''
    export HOME=`mktemp -d`
    export WINEDEBUG=-all
    export WINEPATH=Z:${msys2-env}/clang64/bin
    ${silenceFontconfig}
    exec ${pkgs.wineWowPackages.stable}/bin/wine64 $@
    '';
}