`xlings use <pkg> <ver>` does not re-declare sysroot assets — GL keeps loading the old drivers
## Symptom
Switching mesa reports success, and the subos sysroot keeps pointing at the **old** payload:
```
$ xlings use mesa 25.0.7.2
[xlings] mesa -> local:25.0.7.2 (xim:mesa 25.0.7.1 -> local:mesa 25.0.7.2)
$ readlink <subos>/usr/lib/dri
<XLINGS_HOME>/data/xpkgs/xim-x-mesa/25.0.7.1/lib/dri # ← 25.0.7.1
$ ls <subos>/usr/lib/dri
kms_swrast_dri.so libdril_dri.so nouveau_dri.so radeonsi_dri.so swrast_dri.so zink_dri.so
```
The new payload has **eight** drivers (`iris_dri.so` and `d3d12_dri.so` added). The active view shows six. Re-running `xlings use` is idempotent and does not fix it.
## Why it matters
`LIBGL_DRIVERS_PATH` points at that directory, so a GL program keeps loading the **previous** version's drivers while `xlings list` and `xlings use` both report the new one active. Nothing is broken-looking: rendering still works, just with the old driver set — so a user who upgrades mesa to get `iris` finds it silently absent.
This is the silent-success shape: the switch, the registry and the payload disagree, and only the payload is right.
## Mechanism
`pkgs/m/mesa.lua` `config()` declares the directory into the sysroot:
```lua
graphics.declare_dri(dir, "lib/dri", tag)
graphics.declare_egl_vendor(dir, "share/glvnd/egl_vendor.d/50_mesa.json", tag)
graphics.declare_vulkan_icd(dir, "share/vulkan/icd.d", tag)
```
`config()` runs at **install** time. A `use` switch changes the xvm selection but does not appear to re-run it, so every sysroot-declared asset keeps resolving to whichever payload declared it last.
This is not mesa-specific — it applies to any recipe whose `config()` declares sysroot assets (`sysroot.declare_*`, `graphics.declare_*`). mesa is just where it is visible, because the asset is a *directory whose contents changed*.
## Scope I actually verified
- **Cross-namespace** (`xim:mesa@25.0.7.1` → `local:mesa@25.0.7.2`): reproduced, as above.
- **Same-namespace** (`xim:mesa@A` → `xim:mesa@B`): **not tested** — I could not, because the newer version is not published to the index yet. That is the case that matters for real upgrades, so it should be checked before assuming the scope.
Removing the old payload to force re-declaration is refused, correctly, by the reverse-dep guard:
```
[error] xim:mesa@25.0.7.1 is required by 2 installed package(s) in subos 'default':
xim:graphics@0.1.0
xim:wsl-gl-host-link@0.1.0
```
## Candidate fixes
1. **Re-run `config()` on `use`.** Most direct, and matches the mental model that the active version's config is what governs. Risk: `config()` hooks are written assuming install-time, and some do more than declare.
2. **Make the declaration resolve through the active selection** rather than baking a payload path at install time — i.e. the symlink points at a stable per-name location that `use` re-targets. Fixes the whole class rather than one hook.
(2) looks structurally right; (1) is the smaller change.
## Repro
```sh
xlings install mesa -y # version A
# install version B of the same package
xlings use mesa <B>
readlink <subos>/usr/lib/dri # still A
```
1 条评论