Summary
diffoscope installs and its binary is on PATH, but it cannot start: the Python libarchive-c binding it ships loads the native libarchive shared library via ctypes, and that library is not in the closure.
$ diffoscope --version
Traceback (most recent call last):
File "/usr/lib/python3.14/site-packages/diffoscope/main.py", line 753, in main
import libarchive # noqa
...
File "/usr/lib/python3.14/ctypes/__init__.py", line 491, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/bin/python3.14: undefined symbol: archive_version_number
Missing or incomplete libarchive module. Try installing your system's 'libarchive' package.
Reproduced in a min session (min 0.5.0-rc2.dev.48.g9f56446f) with diffoscope in the task's packages.
Cause
packages/diffoscope/build.ncl declares:
runtime_deps = [
python,
],
libarchive-c is a pure-Python ctypes binding — it needs libarchive.so at runtime, which nothing provides. There is also no libarchive package in pkgs at all, so this needs a new package before the dep can be added.
Note the ELF-based --from-build / DT_NEEDED runtime-dep derivation can't catch this class: the dependency is a ctypes.CDLL() lookup at import time, not a DT_NEEDED entry on any binary in the output. Python/ctypes packages need their native libs declared by hand.
Suggested fix
- Add a
libarchive package to pkgs.
- Add it to
diffoscope's runtime_deps.
- Guard it with a smoke test that actually invokes the tool (
diffoscope --version) rather than checking the binary exists — presence and function differ here, which is exactly how this stayed hidden.
Why it matters
diffoscope is the canonical reproducibility-diff tool and is the "second opinion" instrument for inbox#253 — 100% byte-reproducible pkgs. It being silently non-functional means the deep-dive step of that work isn't available in a session.
🤖 Filed via Claude Code
Summary
diffoscopeinstalls and its binary is on PATH, but it cannot start: the Pythonlibarchive-cbinding it ships loads the native libarchive shared library viactypes, and that library is not in the closure.Reproduced in a
minsession (min 0.5.0-rc2.dev.48.g9f56446f) withdiffoscopein the task'spackages.Cause
packages/diffoscope/build.ncldeclares:libarchive-cis a pure-Python ctypes binding — it needslibarchive.soat runtime, which nothing provides. There is also nolibarchivepackage in pkgs at all, so this needs a new package before the dep can be added.Note the ELF-based
--from-build/ DT_NEEDED runtime-dep derivation can't catch this class: the dependency is actypes.CDLL()lookup at import time, not a DT_NEEDED entry on any binary in the output. Python/ctypes packages need their native libs declared by hand.Suggested fix
libarchivepackage to pkgs.diffoscope'sruntime_deps.diffoscope --version) rather than checking the binary exists — presence and function differ here, which is exactly how this stayed hidden.Why it matters
diffoscope is the canonical reproducibility-diff tool and is the "second opinion" instrument for inbox#253 — 100% byte-reproducible pkgs. It being silently non-functional means the deep-dive step of that work isn't available in a session.
🤖 Filed via Claude Code