{ description = "Additional packages for ARTIQ"; inputs.artiqpkgs.url = git+https://github.com/m-labs/artiq.git; inputs.daxpkgs = { url = git+https://gitlab.com/duke-artiq/dax.git; inputs = { artiqpkgs.follows = "artiqpkgs"; nixpkgs.follows = "artiqpkgs/nixpkgs"; sipyco.follows = "artiqpkgs/sipyco"; }; }; outputs = { self, artiqpkgs, daxpkgs }: let pkgs = import artiqpkgs.inputs.nixpkgs { system = "x86_64-linux"; }; msys2 = import ./msys2 { inherit pkgs; }; sipycoDependenciesFile = ./msys2/sipyco_dependencies.txt; artiqDependenciesFile = ./msys2/artiq_dependencies.txt; comtoolsDependenciesFile = ./msys2/comtools_dependencies.txt; pythonparserDependenciesFile = ./msys2/pythonparser_dependencies.txt; # reads filename and return list of non-empty lines from it readStringListFromFile = (filename: builtins.filter (x: builtins.lessThan 0 (builtins.length (pkgs.lib.strings.stringToCharacters x))) (builtins.filter builtins.isString (builtins.split "\n| |\t" (builtins.readFile filename)))); condaDeps = with pkgs; [ zlib xorg.libSM xorg.libICE xorg.libX11 xorg.libXau xorg.libXi xorg.libXrender libselinux libGL ]; # Use the full Anaconda distribution, which already contains conda-build and its many dependencies. condaInstaller = pkgs.fetchurl { url = "https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh"; sha256 = "1xx8a7jmyd93lkj9zvhmdn66zv10k421n6zszp85imsjk8yv96sk"; }; condaInstallerEnv = pkgs.buildFHSEnv { name = "conda-installer-env"; targetPkgs = pkgs: condaDeps; extraBwrapArgs = [ "--bind" "/nix" "/nix" ]; }; condaInstalled = pkgs.stdenvNoCC.mkDerivation { name = "conda-installed"; src = condaInstaller; buildInputs = [ condaInstallerEnv ]; phases = [ "buildPhase" "installPhase" ]; buildPhase = '' cp $src conda-installer.sh chmod +x conda-installer.sh # keep the same file length to avoid breaking embedded payload offsets sed -i 0,/unset\ LD_LIBRARY_PATH/s//\#nset\ LD_LIBRARY_PATH/ conda-installer.sh ''; installPhase = '' conda-installer-env -c "./conda-installer.sh -p $out -b" substituteInPlace $out/lib/python3.12/site-packages/conda/gateways/disk/__init__.py \ --replace "os.chmod(path, 0o2775)" "pass" ''; }; condaBuilderEnv = pkgs.buildFHSEnv { name = "conda-builder-env"; targetPkgs = pkgs: condaDeps ++ [ condaInstalled ]; extraBwrapArgs = [ "--bind" "/nix" "/nix" ]; }; makeCondaRecipe = (constituent: '' # conda build breaks if write permissions aren't set on source files. cp --no-preserve=mode,ownership -R ${constituent.src} workaround-conda cd workaround-conda tar cf ../${constituent.name}.tar . cd .. rm -rf workaround-conda mkdir -p conda/${constituent.name} cat << EOF > conda/${constituent.name}/meta.yaml package: name: ${constituent.name} version: ${constituent.version} source: url: ../../${constituent.name}.tar {% set data = load_setup_py_data() %} build: noarch: python entry_points: # NOTE: conda-build cannot distinguish between console and gui scripts {% for entry_point_type, entry_points in data.get("entry_points", dict()).items() -%} {% for entry_point in entry_points -%} - {{ entry_point }} {% endfor %} {% endfor %} ignore_prefix_files: True requirements: run: ${pkgs.lib.concatStringsSep "\n" (map (s: " - ${s}") constituent.dependencies)} EOF cat << EOF > conda/${constituent.name}/build.sh #!/bin/bash set -e ${constituent.preSetup or ""} python setup.py install \ --prefix=\$PREFIX \ --single-version-externally-managed \ --record=record.txt \ --no-compile EOF chmod 755 conda/${constituent.name}/build.sh '' ); makeCondaChannel = constituents: pkgs.stdenvNoCC.mkDerivation { name = "conda-channel"; buildInputs = [ condaBuilderEnv ]; phases = [ "buildPhase" "installPhase" ]; buildPhase = pkgs.lib.concatStringsSep "\n" (map makeCondaRecipe constituents); installPhase = '' HOME=`pwd` mkdir $out conda-builder-env -c " ${pkgs.lib.concatStringsSep "\n" (map (constituent: "conda build --no-anaconda-upload --no-test --output-folder $out conda/${constituent.name}") constituents)} " mkdir $out/nix-support for package in $out/*/*.tar.bz2; do echo file conda $package >> $out/nix-support/hydra-build-products done ''; }; in rec { inherit pkgs; inherit makeCondaChannel; inherit (msys2) makeMsys2Package makeMsys2Repos; packages.x86_64-linux = rec { inherit (artiqpkgs.packages.x86_64-linux) artiq openocd-bscanspi; korad_ka3005p = pkgs.python3Packages.buildPythonPackage { pname = "korad_ka3005p"; version = "1.1"; src = pkgs.fetchFromGitHub { owner = "m-labs"; repo = "korad_ka3005p"; rev = "a1898409cb188b388ed1cf84e76ca69e9c8a74eb"; sha256 = "0h20qss70nssqiagc2fx75mravq1pji7rizhag3nq8xrcz2w20nc"; }; propagatedBuildInputs = [ artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco artiqpkgs.packages.x86_64-linux.asyncserial ]; }; novatech409b = pkgs.python3Packages.buildPythonPackage { pname = "novatech409b"; version = "1.1"; src = pkgs.fetchFromGitHub { owner = "m-labs"; repo = "novatech409b"; rev = "3bd559753972f07d881df66b7c6819afc5436053"; sha256 = "1g9qv6fn5h7d393mb1v7w8sg6fimqg34blqdj22qnayb4agw1wyg"; }; propagatedBuildInputs = [ artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco artiqpkgs.packages.x86_64-linux.asyncserial ]; }; lda = pkgs.python3Packages.buildPythonPackage { name = "lda"; version = "1.1"; src = pkgs.fetchFromGitHub { owner = "m-labs"; repo = "lda"; rev = "2d8af1e9080a4c1ab4a32370b3f926bfba8c00b2"; sha256 = "sha256-bImAsQiGmMauasltUrlkCRU3+p40d41DTlJvOjCfrP0="; }; propagatedBuildInputs = [ artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco ]; postPatch = '' substituteInPlace lda/hidapi.py \ --replace "hidapi_lib_path = None"\ "hidapi_lib_path = '${pkgs.hidapi}/lib/libhidapi-libusb.so.0'" ''; }; thorlabs_tcube = pkgs.python3Packages.buildPythonPackage { pname = "thorlabs_tcube"; version = "1.1"; src = pkgs.fetchFromGitHub { owner = "m-labs"; repo = "thorlabs_tcube"; rev = "0cb0c15fc7e660a150e193245f5338d48f8b97db"; sha256 = "1n4zmjcj2kpd97217y602pq6x8s80w39fgyi6qjmal92aicqdg07"; }; propagatedBuildInputs = [ artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco artiqpkgs.packages.x86_64-linux.asyncserial ]; }; newfocus8742 = pkgs.python3Packages.buildPythonPackage { pname = "newfocus8742"; version = "0.2"; src = pkgs.fetchFromGitHub { owner = "quartiq"; repo = "newfocus8742"; rev = "9f6092b724b33b934aa4d3a1d6a20c295cd1d02d"; sha256 = "0qf05ghylnqf3l5vjx5dc748wi84xn6p6lb6f9r8p6f1z7z67fb8"; }; propagatedBuildInputs = [ artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco pkgs.python3Packages.pyusb ]; # no unit tests so do a simple smoke test checkPhase = "python -m newfocus8742.aqctl_newfocus8742 -h"; }; hut2 = pkgs.python3Packages.buildPythonPackage { pname = "hut2"; version = "0.2"; src = pkgs.fetchFromGitHub { owner = "quartiq"; repo = "hut2"; rev = "68369d5d63d233827840a9a752d90454a4e03baa"; sha256 = "0r832c0icz8v3w27ci13024bqfslj1gx6dwhjv11ksw229xdcghd"; }; propagatedBuildInputs = [ artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco ]; # no unit tests without hardware so do a simple smoke test checkPhase = "python -m hut2.aqctl_hut2 -h"; }; flake8-artiq = daxpkgs.packages.x86_64-linux.flake8-artiq; dax = daxpkgs.packages.x86_64-linux.dax.overridePythonAttrs (oa: { nativeBuildInputs = (oa.nativeBuildInputs or []) ++ [ pkgs.qt6.wrapQtAppsHook ]; doCheck = false; }); trap-dac-utils = daxpkgs.packages.x86_64-linux.trap-dac-utils; dax-applets = pkgs.python3Packages.buildPythonPackage rec { pname = "dax-applets"; version = "0.0.0"; src = pkgs.fetchgit { url = "https://gitlab.com/duke-artiq/dax-applets.git"; rev = "0f0196b6941b0c44a33c85d8c02047ca65466463"; sha256 = "0mx6yjvprhdnkdigwns8mg6v5daqxpgbv7mf63fa76i1iv2wvak4"; }; nativeBuildInputs = [ pkgs.qt6.wrapQtAppsHook ]; dontWrapQtApps = true; propagatedBuildInputs = [ artiqpkgs.packages.x86_64-linux.artiq ] ++ (with pkgs.python3Packages; [ numpy pyqt6 pyqtgraph ]); doCheck = false; }; linien-client = pkgs.python3Packages.buildPythonPackage rec { pname = "linien-client"; version = "0.5.3"; src = pkgs.fetchFromGitHub { owner = "linien-org"; repo = "linien"; rev = "v${version}"; sha256 = "sha256-VOT/mw4o9dbkrtMxL0Ar5UcnxsZ7CYcoTj+VVrWADR4="; }; propagatedBuildInputs = (with pkgs.python3Packages; [ numpy paramiko plumbum rpyc scipy ]); doCheck = false; # tests ask for pyqt, migen, etc. patchPhase = '' echo ${version} > linien/VERSION substituteInPlace setup_client.py --replace "\"uuid>=1.30\"," "" substituteInPlace setup_client.py --replace "rpyc>=4.0,<5.0" "rpyc>=4.0" ln -s setup_client.py setup.py ''; }; linien-gui-internal = pkgs.python3Packages.buildPythonPackage rec { pname = "linien-gui-internal"; inherit (linien-client) version src; propagatedBuildInputs = (with pkgs.python3Packages; [ click numpy paramiko plumbum pyqtgraph pyqt5 rpyc scipy superqt appdirs ]) ++ [ linien-client ]; doCheck = false; patchPhase = '' echo ${version} > linien/VERSION substituteInPlace setup_gui.py --replace "rpyc>=4.0,<5.0" "rpyc>=4.0" ln -s setup_gui.py setup.py ''; postInstall = '' # conflicts with linien-client rm -rf $out/lib/python3.12/site-packages/linien/__pycache__ ''; }; # replace broken (as usual) setuptools launcher linien-gui = pkgs.stdenvNoCC.mkDerivation { name = "linien-gui"; phases = [ "installPhase" "fixupPhase" ]; installPhase = '' mkdir -p $out/bin cat > $out/bin/linien << EOF #!${pkgs.python3.withPackages(ps: [ linien-gui-internal ])}/bin/python import linien.gui.app linien.gui.app.run_application() EOF chmod 755 $out/bin/linien ''; nativeBuildInputs = [ pkgs.qt5.wrapQtAppsHook ]; dontWrapQtApps = true; postFixup = '' wrapQtApp "$out/bin/linien" ''; }; conda-channel = makeCondaChannel [ { name = "sipyco"; version = artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco.version; src = artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco.src; dependencies = [ "numpy" "pybase64" ]; } { name = "pythonparser"; version = artiqpkgs.packages.x86_64-linux.pythonparser.version; src = artiqpkgs.packages.x86_64-linux.pythonparser.src; dependencies = [ "regex" ]; } { name = "artiq-comtools"; version = artiqpkgs.inputs.artiq-comtools.packages.x86_64-linux.artiq-comtools.version; src = artiqpkgs.inputs.artiq-comtools.packages.x86_64-linux.artiq-comtools.src; dependencies = [ "numpy" "aiohttp" "sipyco" ]; } { name = "artiq"; version = artiqpkgs.packages.x86_64-linux.artiq.version; src = artiqpkgs.packages.x86_64-linux.artiq.src; preSetup = '' export VERSIONEER_OVERRIDE=${artiqpkgs.packages.x86_64-linux.artiq.version} export VERSIONEER_REV=${artiqpkgs.sourceInfo.rev} ''; dependencies = [ "pythonparser" "scipy" "numpy" "prettytable" "h5py" "python-dateutil" "pyqt" "qasync" "pyqtgraph" "pygit2" "python-levenshtein" "sipyco" "llvmlite" "llvm-tools" "lld" "tqdm" "python-lmdb" "artiq-comtools" "platformdirs" ]; } { name = "korad_ka3005p"; version = korad_ka3005p.version; src = korad_ka3005p.src; dependencies = [ "sipyco" "asyncserial" ]; } { name = "novatech409b"; version = novatech409b.version; src = novatech409b.src; dependencies = [ "sipyco" "asyncserial" ]; } { name = "lda"; version = lda.version; src = lda.src; dependencies = [ "sipyco" ]; } { name = "thorlabs_tcube"; version = thorlabs_tcube.version; src = thorlabs_tcube.src; dependencies = [ "sipyco" "asyncserial" ]; } { name = "newfocus8742"; version = newfocus8742.version; src = newfocus8742.src; dependencies = [ "sipyco" ]; } { name = "hut2"; version = hut2.version; src = hut2.src; dependencies = [ "sipyco" ]; } { name = "flake8-artiq"; version = flake8-artiq.version; src = flake8-artiq.src; dependencies = [ "flake8" ]; } { name = "trap-dac-utils"; version = trap-dac-utils.version; src = trap-dac-utils.src; dependencies = trap-dac-utils.condaDependencies; } { name = "dax"; version = dax.version; src = dax.src; dependencies = dax.condaDependencies; } { name = "dax-applets"; version = dax-applets.version; src = dax-applets.src; dependencies = [ "python>=3.5" "artiq" "numpy" "pyqt" "pyqtgraph" ]; } ]; msys2-pythonparser = msys2.makeMsys2Package rec { name = "python-pythonparser"; version = artiqpkgs.packages.x86_64-linux.pythonparser.version; src = artiqpkgs.packages.x86_64-linux.pythonparser.src; depends = readStringListFromFile pythonparserDependenciesFile; }; msys2-sipyco = msys2.makeMsys2Package { name = "python-sipyco"; src = artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco.src; inherit (artiqpkgs.inputs.sipyco.packages.x86_64-linux.sipyco) version; depends = readStringListFromFile sipycoDependenciesFile; }; msys2-artiq-comtools = msys2.makeMsys2Package { name = "artiq-comtools"; src = artiqpkgs.inputs.artiq-comtools.packages.x86_64-linux.artiq-comtools.src; inherit (artiqpkgs.inputs.artiq-comtools.packages.x86_64-linux.artiq-comtools) version; depends = (readStringListFromFile comtoolsDependenciesFile) ++ [ "mingw-w64-clang-x86_64-python-sipyco" ]; }; msys2-artiq = msys2.makeMsys2Package { name = "artiq"; inherit (artiqpkgs.packages.x86_64-linux.artiq) version src; prepare = '' export VERSIONEER_OVERRIDE=${artiqpkgs.packages.x86_64-linux.artiq.version} export VERSIONEER_REV=${artiqpkgs.sourceInfo.rev} ''; depends = (readStringListFromFile artiqDependenciesFile) ++ [ "mingw-w64-clang-x86_64-python-sipyco" "mingw-w64-clang-x86_64-python-pythonparser" "mingw-w64-clang-x86_64-artiq-comtools" ]; }; msys2-asyncserial = msys2.makeMsys2Package { name = "python-asyncserial"; version = artiqpkgs.packages.x86_64-linux.asyncserial.version; src = artiqpkgs.packages.x86_64-linux.asyncserial.src; depends = [ "mingw-w64-clang-x86_64-python" "mingw-w64-clang-x86_64-python-pyserial" ]; }; msys2-korad_ka3005p = msys2.makeMsys2Package { name = "korad_ka3005p"; version = korad_ka3005p.version; src = korad_ka3005p.src; depends = [ "mingw-w64-clang-x86_64-python-sipyco" "mingw-w64-clang-x86_64-python-asyncserial" ]; }; msys2-novatech409b = msys2.makeMsys2Package { name = "novatech409b"; version = novatech409b.version; src = novatech409b.src; depends = [ "mingw-w64-clang-x86_64-python-sipyco" "mingw-w64-clang-x86_64-python-asyncserial" ]; }; msys2-lda = msys2.makeMsys2Package { name = "lda"; version = lda.version; src = lda.src; depends = [ "mingw-w64-clang-x86_64-python-sipyco" ]; }; msys2-thorlabs_tcube = msys2.makeMsys2Package { name = "thorlabs_tcube"; version = thorlabs_tcube.version; src = thorlabs_tcube.src; depends = [ "mingw-w64-clang-x86_64-python-sipyco" "mingw-w64-clang-x86_64-python-asyncserial" ]; }; msys2-newfocus8742 = msys2.makeMsys2Package { name = "newfocus8742"; version = newfocus8742.version; src = newfocus8742.src; depends = [ "mingw-w64-clang-x86_64-python-sipyco" ]; }; msys2-hut2 = msys2.makeMsys2Package { name = "hut2"; version = hut2.version; src = hut2.src; depends = [ "mingw-w64-clang-x86_64-python-sipyco" ]; }; msys2-flake8-artiq = msys2.makeMsys2Package { name = "flake8-artiq"; version = flake8-artiq.version; src = flake8-artiq.src; depends = [ "mingw-w64-clang-x86_64-python-flake8" ]; }; msys2-repos = msys2.makeMsys2Repos [ msys2-pythonparser msys2-sipyco msys2-artiq-comtools msys2-artiq msys2-asyncserial msys2-korad_ka3005p msys2-novatech409b msys2-lda msys2-thorlabs_tcube msys2-newfocus8742 msys2-hut2 msys2-flake8-artiq ]; msys2-offline-installer = pkgs.stdenv.mkDerivation { name = "msys2-offline-installer"; buildInputs = with pkgs; [ p7zip ]; src = ./.; msys2_qt_ifw = pkgs.stdenvNoCC.mkDerivation rec { name = "msys2_qt_ifw"; srcs = import ./msys2/msys2_qt_ifw_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))); }; msys2_artiq_root = pkgs.stdenvNoCC.mkDerivation rec { name = "msys2_artiq_root"; artiq-deps-pkgs = import ./msys2/artiq_dependency_packages.nix { inherit pkgs; }; msys2-pkgs = import ./msys2/msys2_packages.nix { inherit pkgs; }; msys2-base = pkgs.fetchurl { url = "https://github.com/msys2/msys2-installer/releases/download/2024-05-07/msys2-base-x86_64-20240507.tar.xz"; name = "base"; sha256 = "sha256-RiXJqvmFDaItr6KgoWTekUPHue4i/LM4uBqfVx9HKpc="; }; zadig-binary = pkgs.fetchurl { url = "https://github.com/pbatard/libwdi/releases/download/v1.5.1/zadig-2.9.exe"; name = "zadig"; sha256 = "sha256-TsqpXfPaNiFIagQ674swULi6/nyQFAKHHoFiKe+CA5s="; }; src = ./.; buildInputs = [ pkgs.gnutar pkgs.zstd pkgs.pacman pkgs.fakeroot ]; phases = [ "installPhase" ]; installPhase = '' mkdir $out mkdir -p tmp/cache tar -xvf ${msys2-base} --strip-components=1 -C $out/ msys64 printf "\n[artiq]\nSigLevel = Optional TrustAll\nServer = https://msys2.m-labs.hk/artiq-beta\n" >> $out/etc/pacman.conf cat $out/etc/pacman.conf | sed -e "s|/etc/pacman.d|$out/etc/pacman.d|g" -e "s|SigLevel = Required|SigLevel = Never|g" -e "s|CheckSpace||g" > tmp/pacman.conf sed -i '/\[mingw32\]/,/^$/d; /\[clang32\]/,/^$/d; /\[mingw64\]/,/^$/d; /\[ucrt64\]/,/^$/d; /\[clangarm64\]/,/^$/d;' $out/etc/pacman.conf fakeroot pacman -U --asdeps --noconfirm --cachedir tmp/cache --config tmp/pacman.conf --root $out ${pkgs.lib.concatStringsSep " " (map (p: "${p}") msys2-pkgs)} fakeroot pacman -U --asdeps --noconfirm --cachedir tmp/cache --config tmp/pacman.conf --root $out ${pkgs.lib.concatStringsSep " " (map (p: "${p}") artiq-deps-pkgs)} fakeroot pacman -U --noconfirm --cachedir tmp/cache --config tmp/pacman.conf --root $out ${msys2-artiq}/*.pkg.tar.zst ${msys2-artiq-comtools}/*.pkg.tar.zst ${msys2-pythonparser}/*.pkg.tar.zst ${msys2-sipyco}/*.pkg.tar.zst cp ${zadig-binary} $out/zadig.exe mkdir -p $out/clang64/etc/ssl/certs cp -f $out/usr/ssl/certs/ca-bundle.crt $out/clang64/etc/ssl/certs/ca-bundle.crt cp -f $out/usr/ssl/cert.pem $out/clang64/etc/ssl/cert.pem cp -f $out/usr/ssl/certs/ca-bundle.trust.crt $out/clang64/etc/ssl/certs/ca-bundle.trust.crt rm -rf $out/mingw64* $out/clang32* $out/clangarm64* $out/mingw32* $out/ucrt64* \ $out/var/lib/pacman/sync/mingw64* $out/var/lib/pacman/sync/clang32* $out/var/lib/pacman/sync/clangarm64* \ $out/var/lib/pacman/sync/mingw32* $out/var/lib/pacman/sync/ucrt64* \ $out/etc/pacman.d/mirrorlist.mingw64 $out/etc/pacman.d/mirrorlist.clang32 $out/etc/pacman.d/mirrorlist.clangarm64 \ $out/etc/pacman.d/mirrorlist.mingw32 $out/etc/pacman.d/mirrorlist.ucrt64 ''; }; phases = [ "buildPhase" "installPhase" ]; buildPhase = '' export HOME=`mktemp -d` cp -r $src/installer/qt-ifw qt-ifw # needed for sed and 7z chmod -R 700 qt-ifw sed -i "s|@DATE@|$(date +'%Y-%m-%d')|g" qt-ifw/config/config.xml qt-ifw/packages/com.msys2.root/meta/package.xml ; sed -i "s|@VERSION@|${artiqpkgs.packages.x86_64-linux.artiq.version}|g" qt-ifw/config/config.xml qt-ifw/packages/com.msys2.root/meta/package.xml ; 7z a -mx9 -md128m "qt-ifw/packages/com.msys2.root/data/msys64.7z" "$msys2_artiq_root/"* ${pkgs.wineWowPackages.unstable}/bin/wine64 $msys2_qt_ifw/clang64/bin/binarycreator.exe \ -t "$msys2_qt_ifw/clang64/bin/installerbase.exe" \ -p "qt-ifw/packages" \ -c "qt-ifw/config/config.xml" \ --offline-only \ "artiq-msys2-x86_64.exe" \ -v ''; installPhase = '' mkdir -p $out cp artiq-msys2-x86_64.exe $out/artiq-msys2-x86_64-${artiqpkgs.packages.x86_64-linux.artiq.version}.exe mkdir -p $out/nix-support/ for i in $out/*.*; do echo file binary-dist $i >> $out/nix-support/hydra-build-products done ''; }; }; hydraJobs = packages.x86_64-linux; devShells.x86_64-linux = { msys2 = pkgs.mkShell { name = "dev-shell-msys2"; buildInputs = with pkgs; [ curl pacman fakeroot p7zip msys2.wine-msys2 wineWowPackages.unstable ]; }; }; }; }