Files
nrfwatch/flake.nix
T

168 lines
5.4 KiB
Nix

{
description = "nrfwarch - smartwatch firmware for Xiao nRF54L15 Sense";
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};
zephyrEnv = ''
export ZEPHYR_BASE="$(pwd)/.zephyr/zephyr"
export ZEPHYR_SDK_INSTALL_DIR="$(pwd)/.sdk/zephyr-sdk-0.17.4"
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
'';
in
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
cmake
ninja
python312
python312Packages.pip
python312Packages.west
python312Packages.pyelftools
python312Packages.jsonschema
qemu_full
dtc
git
patchelf
gnumake
feh
];
shellHook = zephyrEnv + ''
echo "--- nrfwarch ---"
echo "Zephyr: $ZEPHYR_BASE"
echo "SDK: $ZEPHYR_SDK_INSTALL_DIR"
echo ""
echo "Setup: nix run .#setup-sdk"
echo "Tests: nix run .#test"
echo "Simulate: nix run .#sim"
'';
ZEPHYR_BASE = toString ./.zephyr/zephyr;
ZEPHYR_SDK_INSTALL_DIR = toString ./.sdk/zephyr-sdk-0.17.4;
ZEPHYR_TOOLCHAIN_VARIANT = "zephyr";
};
apps = {
setup-sdk = {
type = "app";
program = toString (
pkgs.writeShellScript "setup-sdk" ''
set -euo pipefail
SDK_VER="0.17.4"
SDK_DIR=".sdk/zephyr-sdk-$SDK_VER"
ZEPHYR_DIR=".zephyr"
export PATH="${pkgs.git}/bin:${pkgs.python312Packages.west}/bin:${pkgs.wget}/bin:${pkgs.xz}/bin:${pkgs.patchelf}/bin:${pkgs.findutils}/bin:${pkgs.gnugrep}/bin:${pkgs.file}/bin:${pkgs.curl}/bin:${pkgs.gnutar}/bin:$PATH"
if [ ! -d "$ZEPHYR_DIR/zephyr" ]; then
echo "Initializing Zephyr workspace..."
west init -m https://github.com/zephyrproject-rtos/zephyr --mr v4.3.0 "$ZEPHYR_DIR"
(cd "$ZEPHYR_DIR" && west update)
echo "Zephyr workspace ready."
else
echo "Zephyr workspace already exists."
fi
if [ ! -d "$SDK_DIR" ]; then
echo "Downloading Zephyr SDK $SDK_VER..."
mkdir -p .sdk
curl -fsSL "https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v$SDK_VER/zephyr-sdk-''${SDK_VER}_linux-x86_64.tar.xz" \
-o .sdk/zephyr-sdk.tar.xz
echo "Extracting..."
tar xf .sdk/zephyr-sdk.tar.xz -C .sdk
rm .sdk/zephyr-sdk.tar.xz
"$SDK_DIR/setup.sh" -t x86_64-zephyr-elf -t aarch64-zephyr-elf -t arm-zephyr-eabi
echo "Patching binaries for NixOS..."
LD_PATH="${pkgs.stdenv.cc.bintools.dynamicLinker}"
find "$SDK_DIR" -type f | while read -r f; do
if file "$f" 2>/dev/null | grep -q "ELF 64-bit.*dynamically linked"; then
patchelf --set-interpreter "$LD_PATH" "$f" 2>/dev/null || true
fi
done
echo "SDK ready."
else
echo "SDK already exists."
fi
echo ""
echo "All set. Run 'nix develop' to enter the dev shell."
''
);
};
test = {
type = "app";
program = toString (
pkgs.writeShellScript "test" ''
set -euo pipefail
${zephyrEnv}
if [ ! -d "$ZEPHYR_BASE" ]; then
echo "Zephyr not found. Run 'nix run .#setup-sdk' first."
exit 1
fi
BUILD_DIR="build-test"
if [ ! -f "$BUILD_DIR/build.ninja" ]; then
cmake -B "$BUILD_DIR" -GNinja -DBOARD=qemu_x86 -S tests
fi
ninja -C "$BUILD_DIR"
ninja -C "$BUILD_DIR" run
''
);
};
sim = {
type = "app";
program = toString (
pkgs.writeShellScript "sim" ''
set -euo pipefail
${zephyrEnv}
if [ ! -d "$ZEPHYR_BASE" ]; then
echo "Zephyr not found. Run 'nix run .#setup-sdk' first."
exit 1
fi
BUILD_DIR="build-sim"
if [ ! -f "$BUILD_DIR/build.ninja" ]; then
cmake -B "$BUILD_DIR" -GNinja -DBOARD=qemu_x86 -S sim
fi
ninja -C "$BUILD_DIR"
cleanup() {
kill $(jobs -p) 2>/dev/null || true
wait 2>/dev/null || true
}
trap cleanup EXIT INT TERM
echo "Starting display sim (Ctrl+C to stop)..."
"${pkgs.python312}/bin/python3" sim/view.py < <(
"${pkgs.ninja}/bin/ninja" -C "$BUILD_DIR" run 2>/dev/null
)
''
);
};
};
}
);
}