builtin: use the paired libgc.dylib for macOS amd64 + tinyc, not libgc.a - #28008
builtin: use the paired libgc.dylib for macOS amd64 + tinyc, not libgc.a#28008quaesitor-scientiam wants to merge 1 commit into
Conversation
Deliverable C of the macOS-amd64 libgc pairing plan, and the last piece. tcc cannot reliably link the bundled *static* GC archive on macOS: its Mach-O archive reader leaves the GC symbols unresolved against an archive produced by a modern toolchain, even though `nm -g` shows them defined. arm64 has linked the dynamic library with an rpath for exactly that reason since vlang/tccbin#70. amd64 kept selecting libgc.a only because tccbin shipped no .dylib for it - which is what vlang#27982 fixed, rebuilding libgc.dylib in lockstep with every tcc.exe rebuild. That pair is now published (vlang/tccbin thirdparty-macos-amd64 da8ac5a4, libgc.dylib -> libgc.1.dylib as a real symlink), and vlang/tccbin#83's converted gate is green on it, so the selector can finally point at it. Also updated, both of which would otherwise break: - vlib/v/builder/gc_flags_test.v asserted the old behaviour, and runs on exactly the platform this changes (macOS, non-arm64). It now asserts the dylib and rpath are present AND that no libgc.a token remains - the absence is what actually proves the selector collapsed, rather than the dylib merely appearing alongside it. - update_tccbin.yml's isolated-workspace step patched this selector block in memory so its smoke test could exercise the dylib pairing before this change existed. That patch is now both redundant and fatal: it asserted its search text occurred exactly once, and that text no longer exists. Removed - the smoke test's own expectations (libgc.dylib present, no libgc.a token) are unchanged and are now satisfied by the real selector instead of a simulated one, which is strictly better fidelity. Co-Authored-By: WOZCODE <contact@withwoz.com>
|
All three points are correct - I've verified each against the tree rather than just taking them. Standing down on Part C; closing this so it can't be mistaken for mergeable. Over-broad selector. Right, and this is the one I'd defend least. The Test gaps. All three real:
The C0 comma-path prerequisite. This is the one I missed outright, and it's the sharpest of the three. Worth noting why I missed it, since it generalises: my impact analysis searched for things referencing what I removed ( One piece here that must not get dropped, whoever lands Part C:
assert count == 1, f"expected exactly 1 occurrence of the selector block to patch, found {count}"The moment the selector changes, that search text stops existing and the assert hard-fails, taking the macos-amd64 rebuild job with it. It needs removing in the same PR as the selector change - it's independent of the three points above, and it isn't optional. The smoke test's own expectations ( The commit is |
|
Closing as superseded - Part C is being taken over with the C0 comma-path prerequisite and a dedicated macOS smoke test. Branch |
Summary
Deliverable C of the macOS-amd64 libgc pairing plan, and the last piece of it.
tcccannot reliably link the bundled static GC archive on macOS: its Mach-O archive reader leaves the GC symbols unresolved against an archive produced by a modern toolchain, even thoughnm -gshows them defined. arm64 has linked the dynamic library with an rpath for exactly that reason since vlang/tccbin#70. amd64 kept selectinglibgc.aonly because tccbin shipped no.dylibfor it - which is what #27982 fixed, rebuildinglibgc.dylibin lockstep with everytcc.exerebuild.Why it's safe to land now
This was deliberately held back until the dylib was actually distributed - pointing the selector at a file that isn't in the bundle would break every macOS amd64
-cc tcc -gc boehmbuild. Both preconditions are now met:vlang/tccbinthirdparty-macos-amd64is atda8ac5a4, which shipslib/libgc.dylibas a genuine symlink (git mode120000) tolibgc.1.dylib, alongsidelibgc.a.Two things that would otherwise have broken
Both found by searching for anything depending on the old behaviour, rather than only changing the selector:
vlib/v/builder/gc_flags_test.vassertedlibgc.ais on the link line, and its guards ($if !macos { return }/$if arm64 { return }) mean it runs on exactly the platform this changes. It now asserts the dylib and rpath are present and that nolibgc.atoken remains - the absence is what actually proves the selector collapsed, rather than the dylib merely appearing alongside it..github/workflows/update_tccbin.ymlpatched this very selector block in memory, so the macos-amd64 smoke test could exercise the dylib pairing before this change existed. That patch is now both redundant and fatal: it asserted its search text occurred exactly once, and that text no longer exists, so the job would fail outright on its next run. Removed. The smoke test's own expectations (libgc.dylibpresent, nolibgc.atoken - already written that way) are unchanged and are now satisfied by the real selector rather than a simulated one, which is strictly better fidelity.Deliberately left alone after checking:
vlib/v/tests/gnu_make_tcc_fallback_test.v'slibgc.aassertion is inside a$if !linux { return }test;vlib/v/ast/cflags_test.vuses the path only as a flag-parsing string fixture; the FreeBSD/OpenBSD/Windows/Linuxlibgc.aselections are untouched.What CI here can and cannot prove
Worth stating plainly so a green tick isn't over-read: vlang/v CI has no macOS amd64 job that runs the self-test suite.
macos_ci.yml(which runsself_tests) ismacos-14only, i.e. arm64;macos-15-intelappears solely inrelease_ci.yml,vup_works.ymlandupdate_tccbin.yml. Sincetest_macos_tcc_boehm_uses_bundled_libgc()returns early under$if arm64, the test updated here will skip in every CI job - it is a guard for developers on Intel Macs, not a gate that runs on this PR.So CI here proves no regression elsewhere (arm64 macOS, formatting, the YAML lint, every other platform), but it does not exercise the changed path.
What does exercise it is #27982's smoke test on a real
macos-15-intelrunner: real V, realtcc.exe, reallibgc.dylib, asserting the staged compiler was the one invoked, exactly onelibgc.dylibtoken, exactly one matching-rpath, and nolibgc.atoken anywhere on the link line. That test ran against a selector patched in memory to do precisely what this PR now does for real - so the link path in this PR is already validated end-to-end; this PR is what makes it the committed default.Test plan
v fmt -verifyclean on both changed.vfiles.v vetclean on both changed.vfiles.update_tccbin.ymlparses, and passes the repo's Prettier lint (npx prettier@3.9.6 --check **.ymlfrom the repo root - the same invocationworkflow_lint.ymlruns).libgc.a; the two that did are updated above, the rest verified out of scope.gc_flags_test.von a macOS amd64 runner - this is the direct end-to-end check, and it now requires the published bundle, which is exactly the precondition verified above.The dylib link path itself was already validated end-to-end on
macos-15-intelduring #27982: real V + realtcc.exe+ reallibgc.dylib, asserting the staged compiler ran,-rpathwas present, andlibgc.anever appeared on the link line.