Files
nixpkgs/pkgs/development/python-modules/home-assistant-chip-wheels/default.nix
T

297 lines
8.1 KiB
Nix

{
aiohttp,
alive-progress,
build,
clang-tools,
click,
colorama,
coloredlogs,
cryptography,
debugpy,
diskcache,
fetchFromGitHub,
fetchpatch,
glib,
gn,
googleapis-common-protos,
ipython,
jinja2,
json5,
jsonschema,
lark,
lib,
libnl,
mobly,
mypy,
mypy-protobuf,
ninja,
openssl,
packaging,
parameterized,
pip-tools,
pkg-config,
pkgconfig,
prompt-toolkit,
protobuf,
psutil,
ptpython,
pyelftools,
pyfakefs,
pygments,
pykwalify,
pyperclip,
pyserial,
python,
python-daemon,
python-path,
pythonOlder,
pyyaml,
requests,
setuptools,
six,
sphinx,
sphinx-argparse,
sphinx-design,
stdenv,
tabulate,
tornado,
types-pyyaml,
types-requests,
watchdog,
websockets,
zap-chip,
}:
stdenv.mkDerivation rec {
pname = "home-assistant-chip-wheels";
version = "2025.7.0";
src = fetchFromGitHub {
owner = "home-assistant-libs";
repo = "chip-wheels";
tag = version;
fetchSubmodules = false;
leaveDotGit = true;
hash = "sha256-SfhsM2RPghFPx0qtoHsXVymwmOWFiEGAyLx6FeB++dg=";
postFetch = ''
cd $out
# Download connectedhomeip.
git fetch
git reset --hard HEAD
git submodule update --init --depth 1 connectedhomeip
# Initialize only necessary submodules.
cd connectedhomeip
${python.interpreter} scripts/checkout_submodules.py --platform linux --shallow
# Keep the output deterministic.
cd $out
# in case python decided to leave a .pyc file, for example
git clean -fxd
rm -rf .git/
'';
};
strictDeps = true;
nativeBuildInputs = [
gn
pkg-config
ninja
clang-tools
zap-chip
# gdbus-codegen
glib
pkgconfig
python
# dependencies of build scripts
click
jinja2
lark
python-path
setuptools
build
pip-tools
];
propagatedBuildInputs = [
openssl
glib
libnl
];
patches = [
(fetchpatch {
# Fix building with newer gn version
name = "pw_protobuf_compiler-Create-a-new-includes.txt-for-each-toolchain.patch";
# https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/300272
url = "https://pigweed.googlesource.com/pigweed/pigweed/+/b66729b90fcb9df2ee4818f6d4fff59385cdbc80^!?format=TEXT";
decode = "base64 -d";
stripLen = 1;
extraPrefix = "connectedhomeip/third_party/pigweed/repo/";
hash = "sha256-6ss3j8j69w7EMio9mFP/EL2oPqQ2sLh67eWsJjHdDa8=";
})
# fix `ModuleNotFoundError: No module named 'matter'`
# https://github.com/project-chip/connectedhomeip/pull/39826
(fetchpatch {
url = "https://github.com/project-chip/connectedhomeip/commit/78c6a7e15658f66658eb9f780e1a0c0c176a67d7.patch";
stripLen = 1;
extraPrefix = "connectedhomeip/";
hash = "sha256-s5t9DvmZVpnVelrN9+Ekn0OJl/VouXUGKCgu/PTLHBI=";
})
];
postPatch = ''
cd connectedhomeip
export HOME=$(mktemp -d)
patchShebangs --build scripts
for patch in ../*.patch; do
patch -p1 < $patch
done
# ecdsa is insecure and only used in tests
patch -p1 < ${./dont-import-ecdsa.patch}
# unpin dependencies
# there are many files to modify, in different formats
sed -i 's/==.*$//' third_party/pigweed/repo/pw_env_setup/py/pw_env_setup/virtualenv_setup/python_base_requirements.txt
sed -i 's/==[^;]*//' scripts/setup/constraints.txt scripts/tests/requirements.txt
sed -i 's/\(^ \+[a-zA-Z0-9-]*\)[=~><]=[^;]*/\1/' third_party/pigweed/repo/pw_protobuf_compiler/py/setup.cfg third_party/pigweed/repo/pw_protobuf/py/setup.cfg third_party/pigweed/repo/pw_protobuf_compiler/py/setup.cfg
# remove a few dependencies not packaged in nixpkgs and which are apparently
# not needed to build the python bindings of chip
sed -i -e '/sphinxcontrib-mermaid/d' -e '/types-six/d' -e '/types-pygment/d' -e '/types-pyserial/d' third_party/pigweed/repo/*/py/setup.cfg
# obtained by running a build in nix-shell with internet access
cp ${./pigweed_environment.gni} build_overrides/pigweed_environment.gni
# some code is generated by a templating tool (zap-cli)
scripts/codepregen.py ./zzz_pregenerated/
# `pip._internal.exceptions.InstallationError: ''${PW_PROJECT_ROOT}/scripts/py_matter_idl is not a valid editable requirement`
substituteInPlace scripts/tests/requirements.txt \
--replace-fail '-e ''${PW_PROJECT_ROOT}/scripts/py_matter_idl' "" \
--replace-fail '-e ''${PW_PROJECT_ROOT}/scripts/py_matter_yamltests' ""
'';
# the python parts of the build system work as follows
# gn calls pigweed to read a dozen different files to generate
# a file looking like requirements.txt. It then calls pip
# to install this computed list of dependencies into a virtualenv.
# Of course, pip fails in the sandbox, because it cannot download
# the python packages.
# The documented way of doing offline builds is to create a folder
# with wheel files for all dependencies and point pip to it
# via its configuration file or environment variables.
# https://pigweed.dev/python_build.html#installing-offline
# The wheel of a python package foo is available as foo.dist.
# So that would be easy, but we also need wheels for transitive dependencies.
# the function saturateDependencies below computes this transitive closure.
#
# yes this list of dependencies contains both build tools and proper dependencies.
env.PIP_NO_INDEX = "1";
env.PIP_FIND_LINKS =
let
dependencies = [
aiohttp
alive-progress
colorama
coloredlogs
click
cryptography
debugpy
diskcache
googleapis-common-protos
ipython
jinja2
json5
jsonschema
lark
mobly
mypy
mypy-protobuf
packaging
parameterized
pkgconfig
prompt-toolkit
protobuf
psutil
ptpython
pyfakefs
pyelftools
pygments
pykwalify
pyperclip
pyserial
python-daemon
python-path
pyyaml
requests
six
sphinx
sphinx-argparse
sphinx-design
tabulate
tornado
types-pyyaml
types-requests
watchdog
websockets
];
filterNull = list: lib.filter (dep: dep != null) list;
toItem = dep: {
inherit dep;
key = dep.name;
};
saturatedDependencies = lib.genericClosure {
startSet = map toItem (filterNull dependencies);
operator = item: map toItem (filterNull ((item.dep).propagatedBuildInputs or [ ]));
};
saturatedDependencyList = lib.filter (dep: dep ? dist && dep != null) (
map (item: item.dep) saturatedDependencies
);
in
lib.concatMapStringsSep " " (dep: "file://${dep.dist}") saturatedDependencyList;
gnFlags = [
''chip_project_config_include_dirs=["//.."]''
''chip_crypto="openssl"''
''enable_rtti=true''
''chip_config_memory_debug_checks=false''
''chip_config_memory_debug_dmalloc=false''
''chip_mdns="minimal"''
''chip_minmdns_default_policy="libnl"''
''chip_python_version="${lib.versions.majorMinor python.version}"''
''chip_python_platform_tag="any"''
''chip_python_package_prefix="home-assistant-chip"''
''custom_toolchain="custom"''
''target_cc="${stdenv.cc.targetPrefix}cc"''
''target_cxx="${stdenv.cc.targetPrefix}c++"''
''target_ar="${stdenv.cc.targetPrefix}ar"''
];
preBuild = ''
export NIX_CFLAGS_COMPILE="$($PKG_CONFIG --cflags glib-2.0) -O2 -Wno-error"
export NIX_CFLAGS_LINK="$($PKG_CONFIG --libs gio-2.0) $($PKG_CONFIG --libs gobject-2.0) $($PKG_CONFIG --libs glib-2.0)"
'';
ninjaFlags = [ "chip-repl" ];
installPhase = ''
runHook preInstall
cp -r controller/python $out
runHook postInstall
'';
meta = {
description = "Python wheels for APIs and tools related to CHIP";
homepage = "https://github.com/home-assistant-libs/chip-wheels";
changelog = "https://github.com/home-assistant-libs/chip-wheels/releases/tag/${src.tag}";
license = lib.licenses.asl20;
teams = [ lib.teams.home-assistant ];
};
}