Files
komorebi/flake.nix
T
LGUG2Z b15d7cdc53 build(nix): import the nested flakes instead of locking them as inputs
The root flake got the code of komorebi-for-kde and komorebi-for-mac through two locked path inputs (kfde, kfm), so the root flake.lock pinned the content of those directories and needed 'nix flake update kfde kfm' after any edit under them; a stale pin gave 'attribute lib missing'.

Now the root imports komorebi-for-kde/flake.nix and komorebi-for-mac/flake.nix as plain files and calls their outputs/lib.mkOutputs with inputs declared in the root under the names kfde-* and kfm-* (nixpkgs, nixpkgs-lib, flake-compat, flake-parts, crane, rust-overlay, treefmt-nix, git-hooks-nix, and gitignore for kfm), pinned by revision in the URL to exactly the revisions of each nested flake.lock, with the same follows structure. The nested flakes are unchanged and still have their own locks. The kfde and kfm nodes are gone from flake.lock. When a nested flake.lock is bumped, update the revisions of the matching kfde-*/kfm-* inputs by hand.

Verified (tier 2): derivation paths unchanged before and after for kfde fmt, deny, nextest, schema-fresh, the Windows workspace clippy check, kfde-komorebic and kfm-komorebic (aarch64-darwin, eval only); every narHash of the nested locks is present in the root lock; nix flake check --no-build passes on x86_64-linux; nixosModules, overlays, darwinModules evaluate; kfde-vm has 34 suites.
2026-10-31 01:37:53 -07:00

668 lines
26 KiB
Nix

{
description = "komorebi for Windows";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
crane.url = "github:ipetkov/crane";
rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
treefmt-nix.url = "github:numtide/treefmt-nix";
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
git-hooks-nix.url = "github:cachix/git-hooks.nix";
git-hooks-nix.inputs.nixpkgs.follows = "nixpkgs";
asc = {
url = "github:LGUG2Z/komorebi-application-specific-configuration";
flake = false;
};
# the other platforms' flakes (komorebi-for-kde/flake.nix, komorebi-for-mac/flake.nix) are not inputs: their
# flake.nix files are imported below and called with these inputs, which are pinned to exactly the
# revisions of their flake.lock (so nothing here pins the content of those directories)
# inputs of komorebi-for-kde, pinned to the revisions in komorebi-for-kde/flake.lock (keep them equal to it)
kfde-nixpkgs.url = "github:NixOS/nixpkgs/f05535a0efcb2134c478d1e88434fadf486d42b5";
kfde-nixpkgs-lib.url = "github:nix-community/nixpkgs.lib/f7cd230690d9fc982d06129f9189b101fddcfa3b";
kfde-flake-compat = { url = "github:NixOS/flake-compat/5edf11c44bc78a0d334f6334cdaf7d60d732daab"; flake = false; };
kfde-flake-parts.url = "github:hercules-ci/flake-parts/024633cd702b10285db5cb19b40ad48d2399ba60";
kfde-flake-parts.inputs.nixpkgs-lib.follows = "kfde-nixpkgs-lib";
kfde-crane.url = "github:ipetkov/crane/e675a36b7377bebe41d548388a2501cbb16d380d";
kfde-rust-overlay.url = "github:oxalica/rust-overlay/19ecdd08213836b36c4296a3a4f4af5a3d5308db";
kfde-rust-overlay.inputs.nixpkgs.follows = "kfde-nixpkgs";
kfde-treefmt-nix.url = "github:numtide/treefmt-nix/0d6d739a833ba9a9c93034862e4a7b061a062a1c";
kfde-treefmt-nix.inputs.nixpkgs.follows = "kfde-nixpkgs";
kfde-git-hooks-nix.url = "github:cachix/git-hooks.nix/1ba1dbfe28738c9a71c266be6efa5b89e75491a9";
kfde-git-hooks-nix.inputs.nixpkgs.follows = "kfde-nixpkgs";
kfde-git-hooks-nix.inputs.flake-compat.follows = "kfde-flake-compat";
# inputs of komorebi-for-mac, pinned to the revisions in komorebi-for-mac/flake.lock (keep them equal to it)
kfm-nixpkgs.url = "github:NixOS/nixpkgs/16c7794d0a28b5a37904d55bcca36003b9109aaa";
kfm-nixpkgs-lib.url = "github:nix-community/nixpkgs.lib/2075416fcb47225d9b68ac469a5c4801a9c4dd85";
kfm-flake-compat = { url = "github:NixOS/flake-compat/5edf11c44bc78a0d334f6334cdaf7d60d732daab"; flake = false; };
kfm-flake-parts.url = "github:hercules-ci/flake-parts/a34fae9c08a15ad73f295041fec82323541400a9";
kfm-flake-parts.inputs.nixpkgs-lib.follows = "kfm-nixpkgs-lib";
kfm-crane.url = "github:ipetkov/crane/7d59256814085fd9666a2ae3e774dc5ee216b630";
kfm-rust-overlay.url = "github:oxalica/rust-overlay/1d3f83babdd21e16bf5cfe0f1efcb4f49ee1bc2c";
kfm-rust-overlay.inputs.nixpkgs.follows = "kfm-nixpkgs";
kfm-treefmt-nix.url = "github:numtide/treefmt-nix/d56486eb9493ad9c4777c65932618e9c2d0468fc";
kfm-treefmt-nix.inputs.nixpkgs.follows = "kfm-nixpkgs";
kfm-git-hooks-nix.url = "github:cachix/git-hooks.nix/f0927703b7b1c8d97511c4116eb9b4ec6645a0fa";
kfm-git-hooks-nix.inputs.nixpkgs.follows = "kfm-nixpkgs";
kfm-git-hooks-nix.inputs.flake-compat.follows = "kfm-flake-compat";
kfm-gitignore = { url = "github:hercules-ci/gitignore.nix/637db329424fd7e46cf4185293b9cc8c88c95394"; inputs.nixpkgs.follows = "kfm-nixpkgs"; };
kfm-git-hooks-nix.inputs.gitignore.follows = "kfm-gitignore";
};
outputs =
inputs@{
self,
nixpkgs,
flake-parts,
crane,
rust-overlay,
...
}:
let
windowsSdkVersion = "10.0.26100";
windowsCrtVersion = "14.44.17.14";
mkWindowsSdk =
pkgs:
pkgs.stdenvNoCC.mkDerivation {
name = "windows-sdk-${windowsSdkVersion}-crt-${windowsCrtVersion}";
nativeBuildInputs = [
pkgs.xwin
pkgs.cacert
];
outputHashAlgo = "sha256";
outputHashMode = "recursive";
# hash of `xwin splat --disable-symlinks`: without the flag xwin makes
# case-alias symlinks on a case-sensitive filesystem and none on a
# case-insensitive one, so the hash depends on the host
outputHash = "sha256-YjmEfoxtcmQXvUc+WtaElnyP/4osNvtSI7X6MDaNTjg=";
buildCommand = ''
export HOME=$(mktemp -d)
# keep the cache on the same filesystem as $out, as xwin moves
# files from the cache into the output and rename(2) fails with
# EXDEV when the build dir and the store are separate mounts
mkdir -p $out
xwin --accept-license \
--cache-dir $out/.xwin-cache \
--sdk-version ${windowsSdkVersion} \
--crt-version ${windowsCrtVersion} \
splat --disable-symlinks --output $out
rm -rf $out/.xwin-cache
'';
};
# the linker asks for `kernel32.lib` of a file that is `Kernel32.lib`, so
# on a case-sensitive host add a lowercase alias for every name with a
# capital in it, and the spellings the headers include each other by (the
# SDK itself is made without symlinks)
caseFolded =
{ pkgs, windowsSdk }:
if pkgs.stdenv.hostPlatform.isDarwin then
windowsSdk
else
pkgs.runCommandLocal "${windowsSdk.name}-case-folded" { } ''
cp -rs ${windowsSdk} $out
chmod -R u+w $out
cd $out
find . -name '*[A-Z]*' | while read -r path; do
directory=$(dirname "$path")
name=$(basename "$path")
lower=$(echo "$name" | tr 'A-Z' 'a-z')
if [ ! -e "$directory/$lower" ] && [ ! -L "$directory/$lower" ]; then
ln -s "$name" "$directory/$lower"
fi
done
# headers include each other with spellings that differ from the
# file name (`DriverSpecs.h` for `driverspecs.h`), which xwin
# covers with symlinks unless told not to
grep -Rhoi -E '^[[:space:]]*#[[:space:]]*include[[:space:]]*[<"][^>"]+[>"]' \
crt/include sdk/include 2>/dev/null \
| sed -E 's/.*[<"]([^>"]+)[>"]/\1/; s#\\#/#g; s#.*/##' \
| sort -u > $TMPDIR/spellings
find crt/include sdk/include \( -type f -o -type l \) \
| awk -v spellings=$TMPDIR/spellings '
BEGIN {
while ((getline line < spellings) > 0)
known[tolower(line)] = known[tolower(line)] "\n" line
}
{
n = split($0, parts, "/"); base = parts[n]
dir = substr($0, 1, length($0) - length(base))
m = split(known[tolower(base)], names, "\n")
for (i = 1; i <= m; i++)
if (names[i] != "" && names[i] != base)
print dir "\t" base "\t" names[i]
}' \
| while IFS=$'\t' read -r directory name spelling; do
if [ ! -e "$directory$spelling" ] && [ ! -L "$directory$spelling" ]; then
ln -s "$name" "$directory$spelling"
fi
done
'';
mkMsvcEnv =
{ pkgs, windowsSdk }:
let
sdk = caseFolded { inherit pkgs windowsSdk; };
clangVersion = pkgs.lib.versions.major pkgs.llvmPackages.clang.version;
in
{
# linker for the windows target
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER = "lld-link";
# c/c++ compiler
CC_x86_64_pc_windows_msvc = "clang-cl";
CXX_x86_64_pc_windows_msvc = "clang-cl";
AR_x86_64_pc_windows_msvc = "llvm-lib";
# IMPORTANT: libclang include path MUST come first to avoid header conflicts
CFLAGS_x86_64_pc_windows_msvc = builtins.concatStringsSep " " [
"--target=x86_64-pc-windows-msvc"
"-Wno-unused-command-line-argument"
"-fuse-ld=lld-link"
"/imsvc${pkgs.llvmPackages.libclang.lib}/lib/clang/${clangVersion}/include"
"/imsvc${sdk}/crt/include"
"/imsvc${sdk}/sdk/include/ucrt"
"/imsvc${sdk}/sdk/include/um"
"/imsvc${sdk}/sdk/include/shared"
];
CXXFLAGS_x86_64_pc_windows_msvc = builtins.concatStringsSep " " [
"--target=x86_64-pc-windows-msvc"
"-Wno-unused-command-line-argument"
"-fuse-ld=lld-link"
"/imsvc${pkgs.llvmPackages.libclang.lib}/lib/clang/${clangVersion}/include"
"/imsvc${sdk}/crt/include"
"/imsvc${sdk}/sdk/include/ucrt"
"/imsvc${sdk}/sdk/include/um"
"/imsvc${sdk}/sdk/include/shared"
];
# target-specific rust flags with linker flavor and library search paths
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS = builtins.concatStringsSep " " [
"-Clinker-flavor=lld-link"
"-Lnative=${sdk}/crt/lib/x86_64"
"-Lnative=${sdk}/sdk/lib/um/x86_64"
"-Lnative=${sdk}/sdk/lib/ucrt/x86_64"
];
# cargo target
CARGO_BUILD_TARGET = "x86_64-pc-windows-msvc";
};
mkKomorebiPackages =
{
pkgs,
windowsSdk,
# the commit stamped into the binaries; a build for the e2e guest
# gives a constant one, so that a new commit does not rebuild it
commit ? self.rev or (pkgs.lib.removeSuffix "-dirty" (self.dirtyRev or "unknown")),
}:
let
# toolchain with windows msvc target
toolchain = (pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml).override {
targets = [ "x86_64-pc-windows-msvc" ];
};
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
version = "0.1.0";
msvcEnv = mkMsvcEnv { inherit pkgs windowsSdk; };
src = pkgs.lib.cleanSourceWith {
src = ./.;
filter =
path: type:
# the other platforms' trees have their own workspaces and are built by their own outputs
!(pkgs.lib.hasInfix "/komorebi-for-kde" path || pkgs.lib.hasInfix "/komorebi-for-mac" path)
&& (
(craneLib.filterCargoSources path type)
|| (pkgs.lib.hasInfix "/docs/" path)
|| (builtins.match ".*/docs/.*" path != null)
|| (builtins.match ".*/komorebic/fixtures/.*" path != null)
);
};
commonArgs = {
inherit src version;
strictDeps = true;
# komorebic/build.rs downloads applications.json if it is missing, which
# is not possible in the sandbox, so provide the pinned copy instead
preBuild = "mkdir -p komorebic && cp ${inputs.asc}/applications.json komorebic/applications.json";
COMMIT_HASH = commit;
# build inputs for cross-compilation
nativeBuildInputs = [
pkgs.llvmPackages.clang-unwrapped
pkgs.llvmPackages.lld
pkgs.llvmPackages.llvm
# komorebic build script uses reqwest, which runs on the build host
pkgs.pkg-config
pkgs.openssl
pkgs.openssl.dev
];
# point the host-side openssl-sys build at the nix openssl
OPENSSL_NO_VENDOR = "1";
OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib";
OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include";
# cross-compilation environment
inherit (msvcEnv)
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER
CC_x86_64_pc_windows_msvc
CXX_x86_64_pc_windows_msvc
AR_x86_64_pc_windows_msvc
CFLAGS_x86_64_pc_windows_msvc
CXXFLAGS_x86_64_pc_windows_msvc
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS
CARGO_BUILD_TARGET
;
};
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
individualCrateArgs = commonArgs // {
inherit cargoArtifacts;
doCheck = false;
doDoc = false;
};
fullBuild = craneLib.buildPackage (
individualCrateArgs
// {
pname = "komorebi-workspace";
}
);
extractBinary =
binaryName:
pkgs.runCommand "komorebi-${binaryName}"
{
meta = fullBuild.meta // { };
}
''
mkdir -p $out/bin
cp ${fullBuild}/bin/${binaryName}.exe $out/bin/
'';
in
{
inherit
craneLib
src
individualCrateArgs
fullBuild
msvcEnv
;
komorebi = extractBinary "komorebi";
komorebic = extractBinary "komorebic";
komorebic-no-console = extractBinary "komorebic-no-console";
komorebi-bar = extractBinary "komorebi-bar";
komorebi-gui = extractBinary "komorebi-gui";
komorebi-shortcuts = extractBinary "komorebi-shortcuts";
komorebi-testwin = extractBinary "komorebi-testwin";
komorebi-e2e-agent = extractBinary "komorebi-e2e-agent";
};
mkPkgs =
system:
import nixpkgs {
inherit system;
overlays = [ (import rust-overlay) ];
};
in
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [
"aarch64-darwin"
"x86_64-linux"
"aarch64-linux"
];
imports = [
inputs.treefmt-nix.flakeModule
inputs.git-hooks-nix.flakeModule
# komorebi for KDE Plasma (kfde) and komorebi for macOS (kfm), re-exported with a prefix.
# Their flakes keep their own inputs and lock files (inputs.<name>.inputs), but their
# outputs are made here, from the whole repository as the source: the Rust workspaces of
# both depend on the crates of this tree by path, which a flake of their own directory
# cannot see (their `lib.mkOutputs`). The VM tests of kfde are not re-exported as checks,
# so that `nix flake check` of this flake does not boot them; they are reachable as
# legacyPackages.<system>.kfde-vm.
(
{ lib, ... }:
let
# the nested flake.nix files are plain attribute sets: import them and call their
# `lib.mkOutputs` with the inputs declared above (same revisions as their own locks).
# `self` of a nested flake: its own outputs, with the revision and the path of this one
nestedOutputs =
name: dir:
let
nestedInputs = lib.genAttrs [
"nixpkgs"
"flake-parts"
"crane"
"rust-overlay"
"treefmt-nix"
"git-hooks-nix"
] (n: inputs."${name}-${n}");
mkOutputs =
((import (self.outPath + "/${dir}/flake.nix")).outputs (nestedInputs // { inherit self; })).lib.mkOutputs;
nestedSelf =
outputs
// lib.filterAttrs (n: _: n == "rev" || n == "dirtyRev") self
// {
outPath = self.outPath + "/${dir}";
inputs = nestedInputs;
};
outputs = mkOutputs {
self = nestedSelf;
inputs = nestedInputs // {
self = nestedSelf;
};
repoRoot = self;
platformDir = dir;
};
in
outputs;
kfde = nestedOutputs "kfde" "komorebi-for-kde";
kfm = nestedOutputs "kfm" "komorebi-for-mac";
in
{
flake = {
nixosModules.komorebi-for-kde = kfde.nixosModules.default;
overlays.komorebi-for-kde = kfde.overlays.default;
darwinModules.komorebi-for-mac = kfm.darwinModules.default;
};
perSystem =
{ system, ... }:
let
prefixed = prefix: lib.mapAttrs' (name: lib.nameValuePair "${prefix}-${name}");
withoutVmTests = lib.filterAttrs (name: _: !(lib.hasPrefix "vm-" name));
in
{
packages =
prefixed "kfde" (kfde.packages.${system} or { }) // prefixed "kfm" (kfm.packages.${system} or { });
checks =
prefixed "kfde" (withoutVmTests (kfde.checks.${system} or { }))
// prefixed "kfm" (kfm.checks.${system} or { });
legacyPackages.kfde-vm = (kfde.legacyPackages.${system} or { }).vm or { };
};
}
)
];
perSystem =
{ config, system, ... }:
let
pkgs = mkPkgs system;
windowsSdk = mkWindowsSdk pkgs;
build = mkKomorebiPackages { inherit pkgs windowsSdk; };
# the binaries the e2e guest runs: the same build, but with a
# constant commit stamp, so a new commit (or a dirty tree) that does
# not change a source file reuses it. The commit under test is
# KOMOREBI_E2E_COMMIT, not what the binary says.
e2eBuild = mkKomorebiPackages {
inherit pkgs windowsSdk;
commit = "e2e";
};
# OVMF without SMM and with the TPM support Windows 11 Setup asks for
ovmfWithTpm = (pkgs.OVMF.override { tpmSupport = true; }).fd;
e2eWindows = pkgs.writeShellApplication {
name = "e2e-windows";
runtimeInputs = [
pkgs.qemu
pkgs.swtpm
(pkgs.python3.withPackages (p: [ p.pillow ]))
];
text = ''
: "''${E2E_GOLDEN:?set E2E_GOLDEN to the golden image directory}"
out=''${1:?usage: e2e-windows OUT SCENARIO...}
shift
# the binaries under test: this checkout's, or those of another
# commit, made by e2e/platforms/qemu_windows/build-ref.sh
if [ -n "''${KOMOREBI_E2E_BINS:-}" ]; then
bins=$KOMOREBI_E2E_BINS
if [ -f "$bins/commit" ]; then
KOMOREBI_E2E_COMMIT=$(cat "$bins/commit")
fi
else
bins=$(mktemp -d)
trap 'rm -rf "$bins"' EXIT
cp ${e2eBuild.komorebi}/bin/komorebi.exe "$bins"
cp ${e2eBuild.komorebic}/bin/komorebic.exe "$bins"
cp ${e2eBuild.komorebi-testwin}/bin/komorebi-testwin.exe "$bins"
fi
export OVMF_FD=${ovmfWithTpm}
export KOMOREBI_E2E_COMMIT=''${KOMOREBI_E2E_COMMIT:-${self.rev or "dirty"}}
export PYTHONPATH=${./e2e/lib}:${./e2e}
exec python -m platforms.qemu_windows.run \
"$E2E_GOLDEN" "$bins" "$out" "$@"
'';
};
# toolchain with windows target and nightly rustfmt
rustToolchain = (pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml).override {
targets = [ "x86_64-pc-windows-msvc" ];
};
nightlyRustfmt = pkgs.rust-bin.nightly.latest.rustfmt;
rustToolchainWithNightlyRustfmt = pkgs.symlinkJoin {
name = "rust-toolchain-with-nightly-rustfmt";
paths = [
nightlyRustfmt
rustToolchain
];
};
nightlyToolchain = pkgs.rust-bin.nightly.latest.default.override {
targets = [ "x86_64-pc-windows-msvc" ];
};
cargo-udeps = pkgs.writeShellScriptBin "cargo-udeps" ''
export PATH="${nightlyToolchain}/bin:$PATH"
exec ${pkgs.cargo-udeps}/bin/cargo-udeps "$@"
'';
in
{
treefmt = {
projectRootFile = "flake.nix";
programs = {
deadnix.enable = true;
just.enable = true;
nixfmt.enable = true;
taplo.enable = true;
rustfmt = {
enable = true;
package = pkgs.rust-bin.nightly.latest.rustfmt;
};
};
};
checks = {
komorebi-workspace-clippy = build.craneLib.cargoClippy (
build.individualCrateArgs
// {
cargoClippyExtraArgs = "--all-targets -- -D warnings";
}
);
komorebi-workspace-fmt = build.craneLib.cargoFmt {
inherit (build) src;
};
komorebi-workspace-toml-fmt = build.craneLib.taploFmt {
src = pkgs.lib.sources.sourceFilesBySuffices build.src [ ".toml" ];
};
komorebi-workspace-deny = build.craneLib.cargoDeny {
inherit (build) src;
};
komorebi-workspace-nextest = build.craneLib.cargoNextest build.individualCrateArgs;
# the Python of the Windows e2e guest that needs no guest: the
# vendored core's tests and those of the runner
e2e-tests =
pkgs.runCommand "e2e-tests"
{
nativeBuildInputs = [
pkgs.git
(pkgs.python3.withPackages (p: [
p.pillow
p.pytest
]))
];
}
''
cp -r ${./e2e} e2e
chmod -R u+w e2e
cd e2e
export HOME=$TMPDIR PYTHONPATH=$PWD/lib:$PWD
python -m pytest -q -p no:cacheprovider lib/tests platforms/qemu_windows/tests
touch $out
'';
};
packages = {
inherit (build)
komorebi
komorebic
komorebic-no-console
komorebi-bar
komorebi-gui
komorebi-shortcuts
komorebi-testwin
komorebi-e2e-agent
;
inherit windowsSdk;
# the test window of the Windows e2e guest, built with the constant
# stamp: a new commit does not rebuild what it depends on
komorebi-testwin-e2e = e2eBuild.komorebi-testwin;
komorebi-full = build.fullBuild;
default = build.fullBuild;
};
apps = {
komorebi = {
type = "app";
program = "${build.komorebi}/bin/komorebi.exe";
};
komorebic = {
type = "app";
program = "${build.komorebic}/bin/komorebic.exe";
};
komorebic-no-console = {
type = "app";
program = "${build.komorebic-no-console}/bin/komorebic-no-console.exe";
};
komorebi-bar = {
type = "app";
program = "${build.komorebi-bar}/bin/komorebi-bar.exe";
};
komorebi-gui = {
type = "app";
program = "${build.komorebi-gui}/bin/komorebi-gui.exe";
};
komorebi-shortcuts = {
type = "app";
program = "${build.komorebi-shortcuts}/bin/komorebi-shortcuts.exe";
};
default = {
type = "app";
program = "${build.fullBuild}/bin/komorebi.exe";
};
}
// pkgs.lib.optionalAttrs (system == "x86_64-linux") {
# the neutral scenarios against a throwaway Windows guest:
# E2E_GOLDEN=<golden image dir> nix run .#e2e-windows -- \
# OUT SCENARIO...
# KOMOREBI_E2E_BINS=<dir from build-ref.sh> tests another commit
# the golden image is built once with
# e2e/platforms/qemu_windows/build-golden.sh
e2e-windows = {
type = "app";
program = pkgs.lib.getExe e2eWindows;
};
};
devShells.default = pkgs.mkShell {
name = "komorebi";
RUST_BACKTRACE = "full";
# komorebic's build script runs on the host and wants OpenSSL, as in
# the nix build
OPENSSL_NO_VENDOR = "1";
OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib";
OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include";
# the Windows e2e guest (e2e/platforms/qemu_windows): the build
# scripts and the runner find OVMF here, and the vendored core
# and the platform on PYTHONPATH
OVMF_FD = "${ovmfWithTpm}";
shellHook = ''
export PYTHONPATH="$PWD/e2e/lib:$PWD/e2e''${PYTHONPATH:+:$PYTHONPATH}"
'';
# cross-compilation environment
inherit (build.msvcEnv)
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER
CC_x86_64_pc_windows_msvc
CXX_x86_64_pc_windows_msvc
AR_x86_64_pc_windows_msvc
CFLAGS_x86_64_pc_windows_msvc
CXXFLAGS_x86_64_pc_windows_msvc
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS
CARGO_BUILD_TARGET
;
packages = [
rustToolchainWithNightlyRustfmt
cargo-udeps
# cross-compilation tooling
pkgs.llvmPackages.clang-unwrapped # provides clang-cl
pkgs.llvmPackages.lld # provides lld-link
pkgs.llvmPackages.llvm # provides llvm-lib
# komorebic's build script (reqwest) runs on the build host
pkgs.pkg-config
pkgs.openssl
pkgs.cargo-deny
pkgs.cargo-nextest
pkgs.cargo-outdated
pkgs.jq
pkgs.just
pkgs.prettier
# the Windows e2e guest
pkgs.qemu
pkgs.swtpm
pkgs.xorriso
pkgs.socat
pkgs.git
(pkgs.python3.withPackages (p: [
p.pillow
p.pytest # the tests of e2e/lib
]))
];
};
pre-commit = {
check.enable = true;
settings.hooks.treefmt = {
enable = true;
package = config.treefmt.build.wrapper;
pass_filenames = false;
};
};
};
};
}