{ pkgs ? import <nixpkgs> {} }: let python3' = let packageOverrides = self: super: { pyparsing = super.pyparsing.overridePythonAttrs( old: rec { version = "2.3.1"; src = super.fetchPypi { pname="pyparsing"; inherit version; sha256="66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a"; }; }); }; in pkgs.python3.override{inherit packageOverrides;}; python3RequiredPackages = p: with p; [ p.setuptools p.click p.pyserial p.future p.cryptography p.pyparsing p.pyelftools ]; toolchain = pkgs.callPackage ./esp32-toolchain.nix {}; qthingDependencies = with pkgs; [ cmake (python3'.withPackages python3RequiredPackages) git ncurses flex bison gperf ninja toolchain ]; 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 $*" ''; 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 "$@" ''; shellSetup = '' export NIX_CFLAGS_LINK=-lncurses export IDF_PATH=$(realpath ''${QTHING_PATH:-.}/esp-idf) export IDF_TOOLS_PATH=$IDF_PATH/tools ''; qthingBaseRepo = pkgs.runCommand "qthing" {} '' mkdir -p $out/generated ln -s ${./CMakeLists.txt} $out/CMakeLists.txt ln -s ${./components} $out/components ln -s ${./esp-idf} $out/esp-idf 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 ''; in rec { shell = pkgs.mkShell { name = "esp-idf-env"; buildInputs = qthingDependencies ++ [pkgs.zsh]; shellHook = shellSetup; }; 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 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) ''; in pkgs.stdenv.mkDerivation { inherit name qthingBaseRepo; buildInputs = qthingDependencies; unpackPhase = '' cp --reflink=auto -r ${qthingBaseRepo}/* ./ cp --reflink=auto -r ${src} ./main 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 cp --reflink=auto ${environment} generated/environment.h ''; configurePhase = shellSetup + '' patchShebangs esp-idf cmake -G Ninja -S . -B build ''; buildPhase = '' ninja -C build -j $NIX_BUILD_CORES flash_cmdline=$(cat build/flash_project_args | tr '\n' ' ') substituteAll ${flashScript} build/flash 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 done cp build/flash $out/bin ''; }; }