1{ 2 aiohttp, 3 appdirs, 4 appnope, 5 black, 6 build, 7 clang-tools, 8 click, 9 colorama, 10 coloredlogs, 11 coverage, 12 cryptography, 13 diskcache, 14 fetchFromGitHub, 15 fetchpatch, 16 glib, 17 gn, 18 googleapis-common-protos, 19 google-cloud-storage, 20 ipython, 21 jinja2, 22 json5, 23 jsonschema, 24 lark, 25 lib, 26 libnl, 27 mobly, 28 mypy, 29 mypy-extensions, 30 mypy-protobuf, 31 ninja, 32 openssl, 33 packaging, 34 parameterized, 35 pip-tools, 36 pkg-config, 37 pkgconfig, 38 prompt-toolkit, 39 protobuf, 40 psutil, 41 ptpython, 42 pyelftools, 43 pygments, 44 pykwalify, 45 pylint, 46 pyperclip, 47 pyserial, 48 python, 49 python-daemon, 50 pythonOlder, 51 pyyaml, 52 requests, 53 setuptools, 54 six, 55 sphinx, 56 sphinx-argparse, 57 sphinx-design, 58 stdenv, 59 stringcase, 60 toml, 61 tornado, 62 types-protobuf, 63 types-pyyaml, 64 types-requests, 65 types-setuptools, 66 watchdog, 67 websockets, 68 wheel, 69 yapf, 70 zap-chip, 71}: 72 73stdenv.mkDerivation rec { 74 pname = "home-assistant-chip-wheels"; 75 version = "2025.4.0"; 76 src = fetchFromGitHub { 77 owner = "home-assistant-libs"; 78 repo = "chip-wheels"; 79 tag = version; 80 fetchSubmodules = false; 81 leaveDotGit = true; 82 hash = "sha256-20dqVXHPgSxBveTxlbHEjTtp9NI1oVCVpBTDbjDI2QA="; 83 postFetch = '' 84 cd $out 85 # Download connectedhomeip. 86 git fetch 87 git reset --hard HEAD 88 git submodule update --init --depth 1 connectedhomeip 89 90 # Initialize only necessary submodules. 91 cd connectedhomeip 92 ${python.interpreter} scripts/checkout_submodules.py --platform linux --shallow 93 94 # Keep the output deterministic. 95 cd $out 96 # in case python decided to leave a .pyc file, for example 97 git clean -fxd 98 rm -rf .git/ 99 ''; 100 }; 101 102 strictDeps = true; 103 104 nativeBuildInputs = [ 105 gn 106 pkg-config 107 ninja 108 clang-tools 109 zap-chip 110 # gdbus-codegen 111 glib 112 pkgconfig 113 python 114 # dependencies of build scripts 115 click 116 jinja2 117 lark 118 setuptools 119 stringcase 120 build 121 pip-tools 122 black 123 yapf 124 ]; 125 126 propagatedBuildInputs = [ 127 openssl 128 glib 129 libnl 130 ]; 131 132 patches = [ 133 (fetchpatch { 134 # Fix building with newer gn version 135 name = "pw_protobuf_compiler-Create-a-new-includes.txt-for-each-toolchain.patch"; 136 # https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/300272 137 url = "https://pigweed.googlesource.com/pigweed/pigweed/+/b66729b90fcb9df2ee4818f6d4fff59385cdbc80^!?format=TEXT"; 138 decode = "base64 -d"; 139 stripLen = 1; 140 extraPrefix = "connectedhomeip/third_party/pigweed/repo/"; 141 hash = "sha256-6ss3j8j69w7EMio9mFP/EL2oPqQ2sLh67eWsJjHdDa8="; 142 }) 143 ]; 144 145 postPatch = '' 146 cd connectedhomeip 147 export HOME=$(mktemp -d) 148 149 patchShebangs --build scripts 150 151 for patch in ../*.patch; do 152 patch -p1 < $patch 153 done 154 155 # unpin dependencies 156 # there are many files to modify, in different formats 157 sed -i 's/==.*$//' third_party/pigweed/repo/pw_env_setup/py/pw_env_setup/virtualenv_setup/python_base_requirements.txt 158 sed -i 's/==[^;]*//' scripts/setup/constraints.txt 159 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 160 # remove a few dependencies not packaged in nixpkgs and which are apparently 161 # not needed to build the python bindings of chip 162 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 163 164 # obtained by running a build in nix-shell with internet access 165 cp ${./pigweed_environment.gni} build_overrides/pigweed_environment.gni 166 167 # some code is generated by a templating tool (zap-cli) 168 scripts/codepregen.py ./zzz_pregenerated/ 169 ''; 170 171 # the python parts of the build system work as follows 172 # gn calls pigweed to read a dozen different files to generate 173 # a file looking like requirements.txt. It then calls pip 174 # to install this computed list of dependencies into a virtualenv. 175 # Of course, pip fails in the sandbox, because it cannot download 176 # the python packages. 177 # The documented way of doing offline builds is to create a folder 178 # with wheel files for all dependencies and point pip to it 179 # via its configuration file or environment variables. 180 # https://pigweed.dev/python_build.html#installing-offline 181 # The wheel of a python package foo is available as foo.dist. 182 # So that would be easy, but we also need wheels for transitive dependencies. 183 # the function saturateDependencies below computes this transitive closure. 184 # 185 # yes this list of dependencies contains both build tools and proper dependencies. 186 env.PIP_NO_INDEX = "1"; 187 env.PIP_FIND_LINKS = 188 let 189 dependencies = [ 190 aiohttp 191 appdirs 192 appnope 193 black 194 build 195 colorama 196 coloredlogs 197 coverage 198 click 199 cryptography 200 diskcache 201 googleapis-common-protos 202 google-cloud-storage 203 ipython 204 jinja2 205 json5 206 jsonschema 207 lark 208 mobly 209 mypy 210 mypy-extensions 211 mypy-protobuf 212 packaging 213 parameterized 214 pip-tools 215 pkgconfig 216 prompt-toolkit 217 protobuf 218 psutil 219 ptpython 220 pyelftools 221 pygments 222 pykwalify 223 (pylint.overridePythonAttrs { doCheck = pythonOlder "3.13"; }) 224 pyperclip 225 pyserial 226 python-daemon 227 pyyaml 228 requests 229 setuptools 230 six 231 sphinx 232 sphinx-argparse 233 sphinx-design 234 stringcase 235 toml 236 tornado 237 types-protobuf 238 types-pyyaml 239 types-requests 240 types-setuptools 241 watchdog 242 websockets 243 wheel 244 yapf 245 ]; 246 filterNull = list: lib.filter (dep: dep != null) list; 247 toItem = dep: { 248 inherit dep; 249 key = dep.name; 250 }; 251 saturatedDependencies = lib.genericClosure { 252 startSet = map toItem (filterNull dependencies); 253 operator = item: map toItem (filterNull ((item.dep).propagatedBuildInputs or [ ])); 254 }; 255 saturatedDependencyList = lib.filter (dep: dep ? dist && dep != null) ( 256 map (item: item.dep) saturatedDependencies 257 ); 258 in 259 lib.concatMapStringsSep " " (dep: "file://${dep.dist}") saturatedDependencyList; 260 261 gnFlags = [ 262 ''chip_project_config_include_dirs=["//.."]'' 263 ''chip_crypto="openssl"'' 264 ''enable_rtti=true'' 265 ''chip_config_memory_debug_checks=false'' 266 ''chip_config_memory_debug_dmalloc=false'' 267 ''chip_mdns="minimal"'' 268 ''chip_minmdns_default_policy="libnl"'' 269 ''chip_python_version="${lib.versions.majorMinor python.version}"'' 270 ''chip_python_platform_tag="any"'' 271 ''chip_python_package_prefix="home-assistant-chip"'' 272 ''custom_toolchain="custom"'' 273 ''target_cc="${stdenv.cc.targetPrefix}cc"'' 274 ''target_cxx="${stdenv.cc.targetPrefix}c++"'' 275 ''target_ar="${stdenv.cc.targetPrefix}ar"'' 276 ]; 277 278 preBuild = '' 279 export NIX_CFLAGS_COMPILE="$($PKG_CONFIG --cflags glib-2.0) -O2 -Wno-error" 280 export NIX_CFLAGS_LINK="$($PKG_CONFIG --libs gio-2.0) $($PKG_CONFIG --libs gobject-2.0) $($PKG_CONFIG --libs glib-2.0)" 281 ''; 282 283 ninjaFlags = [ "chip-repl" ]; 284 285 installPhase = '' 286 runHook preInstall 287 288 cp -r controller/python $out 289 290 runHook postInstall 291 ''; 292 293 meta = { 294 description = "Python wheels for APIs and tools related to CHIP"; 295 homepage = "https://github.com/home-assistant-libs/chip-wheels"; 296 changelog = "https://github.com/home-assistant-libs/chip-wheels/releases/tag/${src.tag}"; 297 license = lib.licenses.asl20; 298 teams = [ lib.teams.home-assistant ]; 299 }; 300 301}