You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
obj/std.o 被无条件链进每个单元:纯 C 的 compat 包因此依赖 libstdc++.so.6 #416
switch (lu.kind) {
case LinkUnit::Binary:
case LinkUnit::TestBinary:
if (has_std_artifacts)
ins += "" + escape_ninja_path(std_o_dst); // ← 无条件
…
case LinkUnit::SharedLibrary:
if (has_std_artifacts)
ins += "" + escape_ninja_path(std_o_dst); // ← 无条件
…
}
Activity
docs: 七个 issue(#412 #415 #416 #417 #418 #421 #422)的逐条核实与修复方案
Sunrisepeak commentedon Aug 15, 2026
实施前按方案先复现,结论是这条 issue 的因果不成立 —— 症状是真的,归因是错的。
实测(mcpp 2026.8.15.1,本分支)
一个纯 C 的共享库工程(两个
.c,没有一行 C++,没有import std):std.o没有被链进去,而libstdc++.so.6照样在。真因
std.o本身也不可能是来源:零个未定义符号,它拖不动任何共享库。
真正的来源是链接驱动。生成的规则是:
g++隐式追加-lstdc++,而全仓--as-needed只用在-latomic那一处(
src/build/flags.cppm:240),所以-lstdc++会无条件成为NEEDED—— 即使没有任何符号引用它。
这条 issue 该怎么拆
原判据「纯 C 的 compat 包产出的
.so,readelf -d里没有libstdc++.so.6」不可能通过收窄
std.o达成,两者是独立的两件事:std.o无条件链进每个单元 —— 仍然该修(一个不该在那里的对象),但后果比本 issue 描述的小得多。风险也比预想低:
std.o唯一的符号是模块初始化器,而
import std的 TU 会引用它,所以谓词若漏判会得到链接期 undefined_ZGIW3std—— 响亮的失败,不是静默错误。libstdc++.so.6的来源。修法要么让纯 C 单元改用 C 驱动,要么引入
--as-needed(后者会影响 dlopen 的库,需要单独评估)。
建议按 2 另开一条,把本 issue 的判据收窄到 1。
分析全文:
.agents/docs/2026-08-15-issues-412-422-analysis.mdfix(link): #416 — link std.o only into units that actually reach `imp…
feat(bench): cross-platform benchmark suite, and the defects it expos…
speak-agent commentedon Aug 31, 2026
症状已消除,分两步落地 —— 关闭得晚了,补记在此。
归因的修正
Sunrisepeak 的复现是对的,本 issue 的因果不成立:
std.o有 0 个未定义符号,它拖不动任何共享库。纯 C 包上的NEEDED libstdc++.so.6来自链接驱动 ——cxx_shared/cxx_link一律用g++,与链接输入里有没有std.o无关。症状是真的,归因是错的。这条 issue 因此被拆成两半。
落地的两半
本 issue(
std.o按需链接) —— 2026.8.15.1(commitc459cf2)。src/build/ninja_backend.cppm:2001:has_std_artifacts只回答「这个工具链有没有预建的 std 模块」,与单元自身的需求无关;unit_needs_std才是关于这个链接单元的谓词,并且按 issue 要求覆盖了传递可达性,不只看本单元源码。回归测试tests/e2e/235_std_object_only_when_needed.sh。后续在同一处发现
std.compat.o完全没有unit_needs_std收窄 —— 本 issue 修了std.o而把它旁边那个漏了,于是一个 C++ TU 的全局初始化器进了每一个「工具链恰好带 std.compat」的链接单元。同一谓词、同一理由,已一并收拢,注释就在那两行上。驱动那一半 —— 拆出 #426,已修复关闭。非 C++ 的链接单元现在走
c_link/c_shared。判据
issue 写的三条都成立:纯 C 包产出的
.so的readelf -d里没有libstdc++.so.6;import std的工程正常链接运行;间接经依赖的模块接口用到 std 的工程也正常 —— 最后一条就是 235 里的传递性用例。