Skip to content

Commit 9a5b9ec

Browse files
committed
fix(dist): 图供给 C++ 运行时时,契约是 SelfContained,由对象兑现而不是由点名一个库
ld64.lld: error: library not found for -lc++ ⚠️ 我的第一版修法把整块跳过了,那说错了话,而且丢东西:那一块还负责产物格式、 MinGW 判定、macOS 下限这些下游要用的事实,跳过它们一起没了。 ⭐⭐ 而这一块里本来就有正确形状的先例 —— mi.freestanding: // 裸机短路整张表:下面找到的归档是**宿主的** if (in.freestanding) { m.effective = SelfContained; m.unitFlags = " -nostdlib++"; } 图供给运行时是同一件事的 hosted 形态。表里三个答案全都在「点名一个要链的运行时」 (系统的 / 工具链的 / 其中之一的静态形式),三个在「运行时是产物必须被接上的东西」 时都对,在「它已经在里面」时都错;而它会找到的归档是宿主的。 ⇒ 加 mi.graphCxxRuntime,与 freestanding 走同一条短路。 ⭐ 并且它比「跳过」更强:-nostdlib++ 是**主动**告诉驱动别加它自己那套,而不是 沉默。答案不是「在这里改挑 openkal 的那个」—— openkal 的那个**就是那些对象**, 没有库可点名,诚实的 flag 是阻止驱动自作主张的那一个。 实测:unit_ldflags = -nostdlib++;四个目标全部产出,三个能在本机跑的输出逐字相同。
1 parent 09a58a4 commit 9a5b9ec

2 files changed

Lines changed: 27 additions & 19 deletions

File tree

src/build/distribution.cppm

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,27 @@ struct MechanismInput {
256256
// (measured 2026-08-19). A target-side C++ runtime, if one is wanted, is
257257
// an ordinary package — the same way the libc is.
258258
bool freestanding = false;
259+
// ⭐⭐ THE HOSTED FORM OF THE LINE ABOVE: a package in the graph supplies
260+
// the C++ runtime, built for this target, and its objects are already on
261+
// the link line.
262+
//
263+
// The table below has three answers and all of them name a runtime to LINK
264+
// — the system's, the toolchain's, or a static form of one. Each is right
265+
// when the runtime is something the artifact has to be JOINED to, and each
266+
// is wrong here, where it is already inside. The archives it would find are
267+
// the host's, which is the same defect the `freestanding` flag above
268+
// exists for; the difference is only that this target has an OS.
269+
//
270+
// ⚠️ Measured 2026-08-23, cross-building for `aarch64-macos` over openkal
271+
// right after the format decision was corrected to key on the target — the
272+
// wrong format had been masking this:
273+
//
274+
// ld64.lld: error: library not found for -lc++
275+
//
276+
// ⇒ Not "pick openkal's here". openkal's IS the objects; there is no
277+
// library to name, and the honest flag is the one that stops the driver
278+
// from adding its own.
279+
bool graphCxxRuntime = false;
259280
};
260281

261282
struct Mechanism {
@@ -351,7 +372,7 @@ Mechanism resolve(const MechanismInput& in) {
351372
// ELF here, and every ELF cell below reaches for the toolchain's HOST
352373
// archives. One of them silently produced a link line with
353374
// x86-64 libc++.a on a riscv64 link.
354-
if (in.freestanding) {
375+
if (in.freestanding || in.graphCxxRuntime) {
355376
m.effective = Contract::SelfContained;
356377
m.unitFlags = " -nostdlib++";
357378
return m;

src/build/flags.cppm

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -891,24 +891,6 @@ CompileFlags compute_flags(const BuildPlan& plan) {
891891
// nothing below re-decides it. The flags land in the PER-UNIT channel
892892
// (`unit_ldflags`) rather than the global one because two roles in the
893893
// same build may hold different contracts.
894-
// ⭐⭐ AND NOT AT ALL WHEN THE C++ RUNTIME IS ALREADY IN THE OBJECTS.
895-
//
896-
// Every answer this block can give names a runtime to LINK — the system's
897-
// (`-lc++`), the toolchain's (`-load_hidden …/libc++.a`), or a static form
898-
// of one of them. All three are right when the runtime is something the
899-
// artifact has to be joined to, and all three are wrong when a package in
900-
// the graph already compiled one for this target and its objects are on
901-
// the link line.
902-
//
903-
// ⚠️ Measured 2026-08-23, immediately after the format decision above was
904-
// corrected to key on the target. `aarch64-macos` had been falling through
905-
// to `Elf`, where this block contributes nothing — so a wrong answer to one
906-
// question was masking a second wrong answer to another:
907-
//
908-
// ld64.lld: error: library not found for -lc++
909-
//
910-
// ⇒ There is nothing to find, and nothing to look for.
911-
if (!plan.toolchain.targetCxxRuntime)
912894
{
913895
namespace dist = mcpp::build::dist;
914896
auto const& bc = plan.manifest.buildConfig;
@@ -1065,6 +1047,11 @@ CompileFlags compute_flags(const BuildPlan& plan) {
10651047
// "incompatible with elf64lriscv". See MechanismInput::freestanding.
10661048
if (auto ft = mcpp::toolchain::triple::parse(plan.toolchain.targetTriple))
10671049
mi.freestanding = ft->is_freestanding();
1050+
// ⭐⭐ AND THE HOSTED FORM OF THE SAME FACT. A package in the graph has
1051+
// compiled a C++ runtime FOR THIS TARGET and its objects are on the
1052+
// link line — so, exactly as on bare metal, every archive the table
1053+
// below would reach for is the HOST's.
1054+
mi.graphCxxRuntime = plan.toolchain.targetCxxRuntime;
10681055

10691056
const bool wantsArchives =
10701057
(base == dist::Contract::SelfContained

0 commit comments

Comments
 (0)