Skip to content

fix(graphics): consumer_envs 跳过标量行 —— #732/#734 的第二处回归 - #735

Merged
Sunrisepeak merged 2 commits into
mainfrom
fix/consumer-envs-skips-scalars
Aug 30, 2026
Merged

fix(graphics): consumer_envs 跳过标量行 —— #732/#734 的第二处回归#735
Sunrisepeak merged 2 commits into
mainfrom
fix/consumer-envs-skips-scalars

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

自我 review 时发现的,和 #733 同一类,但在另一个发射器上。

DISCOVERY 表有两个发射器:

去处 能指定 op?
S3 declare_subos_env subos shell
S2 consumer_envs 消费者 shim

xvm.add{ envs = ... } 收的是纯 { NAME = "value" } 映射,没有任何「设定而非合并」的表达方式 —— 每一项都按 PATH 式前插合并处理。

对四条搜索路径这正是想要的。对 XKB_CONFIG_ROOTLIBINPUT_QUIRKS_DIR 是破坏性的:它们指一个目录,所以一个已经 export XKB_CONFIG_ROOT=/usr/share/X11/xkb 的用户会拿到

<subos>/share/X11/xkb:/usr/share/X11/xkb

而 libxkbcommon 会在一个根本不是路径的路径里找不到 rules。

唯一的消费者是 pkgs/g/godot.lua:440#732 之前它的 shim 不带这两个变量,之后带了 —— 所以这是我引进的,而且当时没验。

修法

op 这个字段承担唯一含义 —— 「这是标量」 —— 两个发射器各按自己的机制正确处理:S3 用 set,S2 弃权。

for _, d in ipairs(DISCOVERY) do
    if d.op ~= "set" then
        envs[d.var] = "${XLINGS_DYNAMIC_SUBOS_DIR}/" .. d.rel
    end
end

代价写在注释里:从普通登录 shell 经 shim 启动的消费者拿不到键盘/quirks 数据集 —— 也就是这两行存在之前的状态,所以不构成退步;在 subos use 里 S3 照常设对。真正关闭它需要 xvm.add 支持 per-variable op,在那之前,静默破坏一个标量是两种失败里更坏的那个

验证

桩加载 graphics.lua 直接调 consumer_envs():

GBM_BACKENDS_PATH            ${XLINGS_DYNAMIC_SUBOS_DIR}/usr/lib/gbm
LIBGL_DRIVERS_PATH           ${XLINGS_DYNAMIC_SUBOS_DIR}/usr/lib/dri
XDG_DATA_DIRS                ${XLINGS_DYNAMIC_SUBOS_DIR}/share
__EGL_VENDOR_LIBRARY_DIRS    ${XLINGS_DYNAMIC_SUBOS_DIR}/share/glvnd/egl_vendor.d

XKB_CONFIG_ROOT      出现在 consumer_envs? false
LIBINPUT_QUIRKS_DIR  出现在 consumer_envs? false

教训

往 DISCOVERY 加行的检查清单现在是三项:

  1. 新提供方 config() 里要有两个调用(declare_* 放置 + declare_subos_env 声明);
  2. 回头检查每个 declare_subos_env 调用点传没传集合(fix(mesa): 只声明自己填的路径 —— #732 的回归 #733);
  3. 回头检查 consumer_envs() 的消费者 —— 新行会自动进入每一个 shim(本 PR)。

自我 review 时发现的,和 #733 同一类但在**另一个发射器**上。

DISCOVERY 表有两个发射器:
  S3  declare_subos_env  → subos shell,能指定 op
  S2  consumer_envs      → 消费者 shim,**不能**

xvm.add{ envs = ... } 收的是纯 { NAME = "value" } 映射,没有任何"设定而非合并"
的表达方式——每一项都按 PATH 式前插合并处理。对四条搜索路径这正是想要的;对
XKB_CONFIG_ROOT 和 LIBINPUT_QUIRKS_DIR 是破坏性的:它们指**一个**目录,所以一个
已经 export 了 XKB_CONFIG_ROOT=/usr/share/X11/xkb 的用户会拿到

    <subos>/share/X11/xkb:/usr/share/X11/xkb

而 libxkbcommon 会在一个根本不是路径的路径里找不到 rules。

唯一的消费者是 pkgs/g/godot.lua:440。#732 之前它的 shim 不带这两个变量,之后带
了——所以这是我引进的,而且当时没验。

修法:让 op 这个字段承担唯一含义「这是标量」,两个发射器各按自己的机制正确处理
——S3 用 set,S2 弃权。

代价写在注释里:从普通登录 shell 经 shim 启动的消费者拿不到键盘/quirks 数据集,
也就是这两行存在之前的状态,所以不构成退步;在 subos use 里 S3 照常设对。真正
关闭它需要 xvm.add 支持 per-variable op,在那之前,静默破坏一个标量是两种失败里
更坏的那个。

验证(桩加载 graphics.lua 直接调 consumer_envs):

    GBM_BACKENDS_PATH            ${XLINGS_DYNAMIC_SUBOS_DIR}/usr/lib/gbm
    LIBGL_DRIVERS_PATH           ${XLINGS_DYNAMIC_SUBOS_DIR}/usr/lib/dri
    XDG_DATA_DIRS                ${XLINGS_DYNAMIC_SUBOS_DIR}/share
    __EGL_VENDOR_LIBRARY_DIRS    ${XLINGS_DYNAMIC_SUBOS_DIR}/share/glvnd/egl_vendor.d

    XKB_CONFIG_ROOT      出现在 consumer_envs? false
    LIBINPUT_QUIRKS_DIR  出现在 consumer_envs? false
#735 只改 libs/graphics.lua,推上去之后:

    no checks reported on the 'fix/consumer-envs-skips-scalars' branch

一个 CI 都没跑。ci-test.yml 与 ci-xpkg-test.yml 的 paths 过滤器里有
pkgs/** 和 tests/**,没有 libs/**。

而 libs/graphics.lua 被 mesa、nvidia-gl-host-link、xkeyboard-config、
libinput-quirks 四个 recipe import,它们的 install/config 钩子大部分实体就在
这个文件里。所以「只改 libs/」是本索引里**波及面最大**的一类改动,却恰好是
唯一完全不跑 CI 的一类。

这也解释了本轮两次回归为什么都只能靠自我 review 发现(#733 mesa 声明了不该声明
的路径、#735 consumer_envs 把标量拼成冒号路径)——它们都改到了 libs/,CI 从来
没有机会看见。
@Sunrisepeak
Sunrisepeak merged commit ea36f6b into main Aug 30, 2026
11 checks passed
@Sunrisepeak
Sunrisepeak deleted the fix/consumer-envs-skips-scalars branch August 30, 2026 12:19
Sunrisepeak added a commit that referenced this pull request Aug 30, 2026
* ci: publish-artifact 也要看 libs/**——这一处漏的是交付,不是评审

#735 合进 main、所有检查全绿,而 xlings update 仍然在发
xim-index-f1702a1.tar.gz——也就是修复**之前**那一版。gitee 镜像同步到了
ea36f6b,但索引产物没有重出。

原因和 #735 修的是同一个盲区,只是第三处:publish-artifact.yml 的 paths 是
pkgs/** / xim-indexrepos.lua / .xpkgindex.json,没有 libs/**。

而这个 workflow 发布的产物**就是 xlings update 下载的东西**,里面含 libs/——
四个 recipe import xim.pkgindex.graphics,执行的正是那里的代码。所以只改
libs/ 的修复只能经由这个产物到达用户,而在这一行之前它根本到不了。

夜间 cron(0 18 * * *)最终会补上,所以这是慢漏而不是断供;但「合了、绿了、
用户拿到的还是旧的」这个状态本身就不该存在。

已手动 workflow_dispatch 一次让 #735 立刻到达用户。

没有加进 pkgindex-deloy.yml / site-check.yml:那两个从包元数据渲染文档站,
libs/ 不是面向用户的文档。

* ci: publish-artifact 把自己也列进 paths

沿用 ci-test.yml 的既有做法。改了触发条件或步骤的发布器应当**发布一次**——那是
唯一能证明它还能用的动作,也让本 PR 这类改动自验:合入之后要么出产物要么不出。

顺带解释了 #736 为什么零检查:没有任何 workflow 监视 publish-artifact.yml。

---------

Co-authored-by: sunrisepeak <x.d2learn.org@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants