fix: repair Windows wheels with delvewheel --ignore-existing - #395
Merged
Conversation
cibuildwheel 4.1 runs delvewheel by default on Windows. Our build installs libfastjet & friends into fastjet/bin inside the wheel, but delvewheel only searches --add-path and PATH for dependencies -- it never looks inside the wheel unless --ignore-existing is given (delvewheel 1.13.0, _wheel_repair.py sets _wheel_dirs = None otherwise). Hence "FileNotFoundError: Unable to find library: fastjet.dll". Set repair-wheel-command in pyproject.toml rather than a workflow env var so that ci.yml's test_wheels job, wheels.yml and local cibuildwheel runs all get it. Verified against the published 3.5.1.3 win_amd64 wheel: default flags reproduce the failure, --ignore-existing leaves fastjet/bin untouched and vendors msvcp140.dll into fastjet.libs. Assisted-by: ClaudeCode:claude-opus-5
lgray
enabled auto-merge (squash)
July 27, 2026 23:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 AI text below 🤖
cibuildwheel 4.1 runs
delvewheel repairby default on Windows, and it fails withRoot cause
Our build installs the fastjet DLLs inside the wheel at
fastjet/bin/(andfastjet/__init__.pyadds that directory viaos.add_dll_directory). delvewheel resolves dependencies only from--add-pathand thenPATH— it never looks inside the wheel unless--ignore-existingis passed. In delvewheel 1.13.0,_wheel_repair.pyonly populates the in-wheel search list under that flag:https://github.com/adang1345/delvewheel/blob/v1.13.0/delvewheel/_wheel_repair.py#L256-L266 → consumed by
find_library()in_dll_utils.py, whose only other search location isPATH.So
--add-pathcannot reach these DLLs: they exist only inside the built wheel and in scikit-build's temp build tree, never under{project}. The wheels.yml run of the previous commit shows cibuildwheel expanding it to--add-path D:.\bin(and the folded-scalar quoting turned the whole command into a single quoted token, so it failed before delvewheel even started). Moving the DLLs next to_ext.pydwould not help either — same code path.Fix
Put in
pyproject.tomlrather than a workflow env var because the job that actually failed wasci.yml'stest_wheels, notwheels.yml(the failing run logs the defaultrepair_command: delvewheel repair -w {dest_dir} -v {wheel}). pyproject covers both workflows plus local cibuildwheel runs. TheCIBW_REPAIR_WHEEL_COMMAND_WINDOWSenv block is dropped.Verification
Run locally with delvewheel 1.13.0 (the version CI installs) against the published
fastjet-3.5.1.3-cp314-cp314-win_amd64.whl, which has the same layout as the failing build:delvewheel repair -w out -v <whl>FileNotFoundError: Unable to find library: fastjet.dll— CI failure reproduceddelvewheel repair --ignore-existing -w out -v <whl>fastjet.dllnow resolved fromfastjet/bin; stops atmsvcp140.dll, which macOS has no copy of... --ignore-existing --add-path <dir containing msvcp140.dll>(simulates a WindowsPATH)In the successful run,
fastjet/bin/*.dllare left in place and un-mangled,fastjet.libs/msvcp140.dllis vendored, andfastjet/__init__.pygets delvewheel'sadd_dll_directory(fastjet.libs)patch inserted above the existingbinhook and aboveimport fastjet._ext. Wheel size 2544651 -> 2688643 bytes.Side benefit: the MSVC C++ runtime is now bundled, so the wheel no longer relies on a system VC++ redistributable being installed.
One thing to watch in this run:
win_arm64needs an arm64msvcp140.dllonPATHon thewindows-11-armrunners. If that turns out to be missing, adding--exclude msvcp140.dllrestores the pre-4.1 behaviour of bundling nothing extra.CI result
Run 30314452394 is green. Both Windows wheel jobs repair as expected:
Identical output on
win_arm64— the arm64msvcp140.dllconcern above did not materialise, so no--excludeis needed. The x64 wheel job then ran the test suite against the repaired wheel:92 passed, 8 warnings in 10.41s.Note: because this commit reverts wheels.yml to its state on main, the PR's net diff no longer touches that file, so the
wheelsworkflow (which ispaths-filtered on it) will not run on this PR. Happy to kick it off viaworkflow_dispatchif you want the full 3.10-3.14t matrix exercised before merge.