Skip to content

runtime_search 闭包里没有 $ORIGIN —— resolution.json 与 DT_RPATH 天生不可逐项比对 #415

Description

@speak-agent

现象

resolution.json 记录的运行期搜索闭包少一项:产物自己的目录($ORIGIN)不在里面。

实测(2026.8.11.3,一个消费依赖共享库的工程):

记录的闭包(resolution.json → runtime.search.closure):
  payload      <store>/xim-x-glibc/2.44/lib64
  payload      <store>/xim-x-gcc/16.1.0/lib64
  subos_farm   <home>/registry/subos/default/lib

产物真实的 DT_RPATH:
  …/xim-x-glibc/2.44/lib64 : …/xim-x-gcc/16.1.0/lib64 : $ORIGIN : …/subos/default/lib
                                                        ^^^^^^^ 记录里没有

为什么这不只是"记录不全"

src/platform/runtime_search.cppm 自称是唯一的排序:

Search order = decreasing immutability. This is the one invariant in this
module, and it is not stylistic.

src/build/plan.cppm:660 进一步写着「search::ordered is what enforces it」。

$ORIGIN 由另一个函数(plan.cppmshared_library_link_flags)在另一条通道
(per-unit flags)上发出,从不进入闭包 —— 所以这个排序模型对最关键的那个目录
是装饰性的。#414 修的正是这条:farm 曾经排在 $ORIGIN 前面,产物链接了一份 libX11、
运行期加载了另一份。

直接后果:

建议

只做轻档 (i):把产物输出目录以新的 Origin::Artifact 纳入闭包记录,
rank() 置于 PackageSubosFarm 之间。

  • src/platform/runtime_search.cppm:Origin 加一档 + rank() + to_string()
    • is_machine_local()($ORIGIN 随产物走 ⇒ machine-local)
  • src/build/plan.cppm:667 runtime_search_closure():加入产物输出目录
  • 显示侧:src/build/prepare.cppm:6417 写记录、src/doctor.cppm:703 打标签

不涉及 pack(已核):is_machine_local 全仓只有那一个生产消费方;
src/pack/pack.cppm 不 import mcpp.platform.runtime_search,它自己用 patchelf 把
所有 RPATH 重写成 $ORIGIN/../lib

重档 (ii) 不建议现在做:让闭包成为唯一的 rpath 生产者(把 $ORIGIN 的发出
也从 shared_library_link_flags 挪进来)才真正消灭"两个生产者",但 $ORIGIN 本质是
per-unit 的(只有消费共享库的单元才需要),挪进全局闭包意味着要给闭包引入 per-unit
概念,改动量与风险都明显更大。

判据

e2e 219 能把「记录的闭包」与「产物的 DT_RPATH」逐项比对并通过,而不必对
$ORIGIN 做任何过滤或例外。

背景

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions