rebuild-pyd
Rebuild the astroray Python extension cleanly, clearing every stale .pyd shadow copy that can mask a fresh build. Use when tests behave as if code changes had no effect, or after switching between Ble
SKILL.md.claude/skills/rebuild-pyd/SKILL.md
GitHubrebuild-pyd
Astroray ships its Python module (astroray.pyd / astroray.cp312-win_amd64.pyd) into several directories for IDE/Jupyter/Blender convenience. tests/base_helpers.py inserts the project root into sys.path after build/, so the project-root copy wins. A stale .pyd outside build/ will silently shadow a fresh build and produce frozen-in-time test output.
This skill does the canonical clean rebuild for one of three variants. The user picks the variant; nothing here assumes.
Variants
| Variant | Preset / script | OpenMP | CUDA | Loaded by |
|---|---|---|---|---|
standalone |
cmake --preset windows-cpu-vs + build |
ON | OFF | pytest, CLI raytracer |
cuda |
cmake --preset windows-cuda-vs + build |
ON | ON | pytest with GPU |
blender |
python scripts/build/build_blender_addon.py |
ON | OFF | Blender's MSVC Python |
Note (issue #780, 2026-09-09): the blender variant now builds with OpenMP ON. The historic "OpenMP hangs the Blender addon" rule was a GIL/OpenMP circular wait, not a libgomp/vcomp toolchain defect: OpenMP workers acquired the GIL for the progress callback while the master held it at the end-of-parallel-region barrier. pkg241 (#748) released the GIL across the CPU render (py::gil_scoped_release), so the deadlock can no longer occur, and forcing OpenMP OFF cost the addon CPU leg every core but one. build_blender_addon.py sets -DASTRORAY_DISABLE_OPENMP=OFF and bundles vcomp140.dll next to the .pyd; do not override it back to ON. (See .astroray_plan/docs/780-addon-openmp-deadlock-root-cause-2026-09.md; memory/mingw_openmp_blender_deadlock.md is superseded.)
Procedure
Locate every shadow. From repo root:
Get-ChildItem -Recurse -Filter astroray*.pyd | Select-Object FullName, Length, LastWriteTimeExpected legitimate locations:
build/astroray.cp312-win_amd64.pyd(standalone preset binaryDir isbuild/)build_cuda/astroray.cp312-win_amd64.pydbuild_tcnn/astroray.cp312-win_amd64.pyd- the Blender addon's
Release/staging copy
Anything at any of these paths is a shadow and must go:
./astroray.pyd./astroray.cp312-win_amd64.pyd./tests/astroray*.pyd./Release/astroray*.pyd(only if not the Blender staging dir — checkblender_addon/Release/is the legit one)
Delete shadows. Show the list to the user before deleting. Then
Remove-Itemeach. Never delete frombuild/,build_cuda/,build_tcnn/, orblender_addon/Release/.Rebuild the chosen variant:
standalone:cmake --preset windows-cpu-vsthencmake --build --preset windows-cpu-vs-releasecuda:cmake --preset windows-cuda-vsthencmake --build --preset windows-cuda-vs-releaseblender:python scripts/build/build_blender_addon.py— do not pass extra CMake flags; the script ownsASTRORAY_DISABLE_OPENMP=OFF(OpenMP ON since issue #780) andPYBIND11_FINDPYTHON=ON, and bundlesvcomp140.dll.
Verify the fresh artifact. Re-run the
Get-ChildItemfrom step 1 and confirm the timestamp on the expected output (e.g.build/astroray.cp312-win_amd64.pyd) is newer than 60 seconds ago. If any shadow reappeared (e.g. a post-build copy step you forgot about), surface that path rather than silently moving on.For
standalone/cuda, smoke-test:python -c "import sys; sys.path.insert(0, 'build'); import astroray; print(astroray.__file__)". The printed path must be insidebuild/(orbuild_cuda/). If it points to the project root, step 2 missed a shadow.
Anti-patterns
- Running
cmake --buildwithout first clearing shadows: the build will succeed and tests will still load the old binary. - Using
find . -name '*.pyd' -deleteblindly: that nukes the Blender addon staging copy too. - Re-enabling OpenMP "just to test" in the Blender variant: it will hang at module init with no log past
Read blend:.
When to invoke
Type /rebuild-pyd (model invocation is disabled — this only runs on explicit user request) when:
- A test fix "isn't working" and the failure output looks identical to before the edit.
- You just switched Python versions or pybind11 settings.
- You're about to ship a Blender addon build and need to be sure no OpenMP-linked
.pydleaked through.