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

直接后果:

建议

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

  • 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 做任何过滤或例外。

背景

Activity

  1. added 3 commits that reference this issue on Aug 15, 2026
  2. speak-agent commented on Aug 31, 2026

    @speak-agent
    MemberAuthor

    已修复,随 2026.8.15.1(commit c459cf2)发布 —— 关闭得晚了,补记在此。

    按 issue 建议的轻档 (i) 实施,重档 (ii) 未做,理由与 issue 写的一致:$ORIGIN 本质是 per-unit 的,把它的发出也搬进全局闭包需要给闭包引入 per-unit 概念。

    落地:

    • modules/platform/src/runtime_search.cppm —— Origin 增加 Artifact 一档,rank() 为 2(落在 Package 与 SubosFarm 之间),is_machine_local() 返回 false($ORIGIN 随产物走),to_string() 为 "artifact"。
    • runtime_search_closure() 纳入产物输出目录;记录侧与 mcpp why runtime / doctor 的展示侧同步。
    • 单测 tests/unit/test_runtime_search.cpp 钉住 rank 的两侧不等式与 is_machine_local,因为这两条是这一档存在的全部理由,而它们不会由任何构建失败报出来。

    判据用的是 issue 自己写的那一条,不是别的:

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

    tests/e2e/219_runtime_search_farm_is_last.sh 现在就是逐项比对,通过时打印

    closure == DT_RPATH, 4 entries, item by item
    

    失败信息里保留了两个方向的解释,并点名本 issue:记录里少 $ORIGIN 说明 Origin::Artifact 不再进闭包;记录里有而产物里没有,说明它被记给了一个根本不发 rpath 的工程。

    pack 不受影响这一点也按 issue 的核查结论确认过:src/pack/ 不 import mcpp.platform.runtime_search,它自己用 patchelf 把 RPATH 重写成 $ORIGIN/../lib。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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