Skip to content
Snippets Groups Projects
default.nix 4.08 KiB
Newer Older
Legy (Beini)'s avatar
Legy (Beini) committed
{ pkgs ? import <nixpkgs> {} }:

let

Legy (Beini)'s avatar
Legy (Beini) committed
  python3' = let
Legy (Beini)'s avatar
Legy (Beini) committed
    packageOverrides = self: super: {
      pyparsing = super.pyparsing.overridePythonAttrs( old: rec {
        version = "2.3.1";
        src = super.fetchPypi {
          pname="pyparsing";
          inherit version;
          sha256="66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a";
        };
      });
    };
Legy (Beini)'s avatar
Legy (Beini) committed
    in pkgs.python3.override{inherit packageOverrides;};

  python3RequiredPackages = p: with p; [
    p.setuptools
    p.click
    p.pyserial
    p.future
    p.cryptography
    p.pyparsing
    p.pyelftools
  ];
Legy (Beini)'s avatar
Legy (Beini) committed

  toolchain = pkgs.callPackage ./esp32-toolchain.nix {};

Legy (Beini)'s avatar
Legy (Beini) committed
  qthingDependencies = with pkgs; [
    cmake (python3'.withPackages python3RequiredPackages) git ncurses flex bison gperf ninja toolchain
Legy (Beini)'s avatar
Legy (Beini) committed
  ];

  idfWrapper = pkgs.writeShellScriptBin "idf.py" ''
    args=""
    [ -n "$QTHING_PATH" ] && args="--project-dir=$QTHING_PATH --build-dir=$QTHING_PATH/build "
    exec nix-shell "''${QTHING_PATH:-.}/shell.nix" --run 'exec $IDF_TOOLS_PATH/idf.py '"$args $*"
Legy (Beini)'s avatar
Legy (Beini) committed
  idfWrapperFlake = pkgs.writeShellScriptBin "idf.py" ''
    args=""
    [ -n "$QTHING_PATH" ] && args="--project-dir=$QTHING_PATH --build-dir=$QTHING_PATH/build "
    exec $IDF_TOOLS_PATH/idf.py $args $*
  '';
  clangdWrapper = pkgs.writeShellScriptBin "clangd" ''
    args='--query-driver=${toolchain}/bin/* '
    [ -n "$QTHING_PATH" ] && args+="--compile-commands-dir=$QTHING_PATH/build "
    exec ${pkgs.llvmPackages_10.clang-unwrapped}/bin/clangd $args "$@"
  '';

Legy (Beini)'s avatar
Legy (Beini) committed
  shellSetup = ''
    export NIX_CFLAGS_LINK=-lncurses
    export IDF_PATH=$(realpath ''${QTHING_PATH:-.}/esp-idf)
Legy (Beini)'s avatar
Legy (Beini) committed
    export IDF_TOOLS_PATH=$IDF_PATH/tools
  '';

  qthingBaseRepo = pkgs.runCommand "qthing" {} ''
Legy (Beini)'s avatar
Legy (Beini) committed
    mkdir -p $out/generated
    ln -s ${./CMakeLists.txt} $out/CMakeLists.txt
    ln -s ${./components} $out/components
    ln -s ${./esp-idf} $out/esp-idf
Legy (Beini)'s avatar
Legy (Beini) committed
    ln -s ${./generated/CMakeLists.txt} $out/generated/CMakeLists.txt
    ln -s ${./partitions.csv} $out/partitions.csv
    ln -s ${./qthing} $out/qthing
    ln -s ${./sdkconfig} $out/sdkconfig
Legy (Beini)'s avatar
Legy (Beini) committed
in rec {

  shell = pkgs.mkShell {
Legy (Beini)'s avatar
Legy (Beini) committed
    name = "esp-idf-env";
    buildInputs = qthingDependencies ++ [pkgs.zsh];
Legy (Beini)'s avatar
Legy (Beini) committed
    shellHook = shellSetup;
  };

Legy (Beini)'s avatar
Legy (Beini) committed
  devShell = pkgs.mkShell {
    name = "esp-idf-env";
    buildInputs = qthingDependencies ++ [pkgs.zsh idfWrapperFlake ./bin];
    shellHook = shellSetup;
  };

  envrc = pkgs.writeText ".envrc" ''
    PATH_add ${idfWrapper}/bin
    PATH_add ${clangdWrapper}/bin
    PATH_add ${./bin}

    export QTHING_PATH=$(expand_path .)

    ${shellSetup}
  '';

  mkProject = { name, src, environment }: let
Legy (Beini)'s avatar
Legy (Beini) committed
    flashScript = pkgs.writeScript "flash" ''
      PATH=${pkgs.esptool}/bin/:$PATH
      cd @out@
      esptool.py "$@" write_flash @flash_cmdline@
    '';
    defaultDeviceConfig = pkgs.writeText "device_config.h" ''
      #define DEVICE_NAME "${name}"
    '';
    defaultCMakeLists = pkgs.writeText "CMakeLists.txt" ''
      idf_component_register(SRC_DIRS "." INCLUDE_DIRS "." REQUIRES main)
    '';
Legy (Beini)'s avatar
Legy (Beini) committed
  in pkgs.stdenv.mkDerivation {
    inherit name qthingBaseRepo;
Legy (Beini)'s avatar
Legy (Beini) committed
    buildInputs = qthingDependencies;
    unpackPhase = ''
      cp --reflink=auto -r ${qthingBaseRepo}/* ./
      cp --reflink=auto -r ${src} ./main
Legy (Beini)'s avatar
Legy (Beini) committed
      chmod u+w ./generated ./main
      if [[ ! -f main/device_config.h ]]; then
        ln -s ${defaultDeviceConfig} main/device_config.h
      fi
      if [[ ! -f main/CMakeLists.txt ]]; then
        ln -s ${defaultCMakeLists} main/CMakeLists.txt
      fi
Legy (Beini)'s avatar
Legy (Beini) committed
      cp --reflink=auto ${environment} generated/environment.h
Legy (Beini)'s avatar
Legy (Beini) committed
    configurePhase = shellSetup + ''
      patchShebangs esp-idf
      cmake -G Ninja -S . -B build
Legy (Beini)'s avatar
Legy (Beini) committed
    '';
    buildPhase = ''
      ninja -C build -j $NIX_BUILD_CORES
      flash_cmdline=$(cat build/flash_project_args | tr '\n' ' ') substituteAll ${flashScript} build/flash
Legy (Beini)'s avatar
Legy (Beini) committed
      chmod +x build/flash
    '';
    installPhase = ''
      mkdir -p $out/bin
      for path in $(cd build; find -iname '*.bin' -and -not -wholename '*/CMakeFiles/*'); do
        mkdir -p $out/$(dirname $path)
        cp build/$path $out/$path
Legy (Beini)'s avatar
Legy (Beini) committed
      done
      cp build/flash $out/bin