Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 12 additions & 31 deletions .github/workflows/update_tccbin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -698,13 +698,18 @@ jobs:
exit 1
fi

# Deliverable A (this PR) does not include the V selector change
# (deliverable C, vlib/builtin/builtin_d_gcboehm.c.v) - it merges
# separately, only after this pair is published and vlang/tccbin's
# gate is confirmed green under it. To actually exercise the
# dylib pairing here, apply that selector collapse to an entirely
# separate, freshly-cloned vlang/v workspace, in memory only -
# never written back to this checkout, never committed anywhere.
# Build ./v in an entirely separate, freshly-cloned workspace so the
# smoke test below runs a real V against the staged bundle.
#
# This step used to patch vlib/builtin/builtin_d_gcboehm.c.v in memory
# to make macOS amd64 select libgc.dylib, because the selector still
# chose the static libgc.a and the smoke test would otherwise not have
# exercised the dylib pairing at all. That patch is gone: the selector
# itself now links the dylib on both macOS arches, so this clone needs
# no modification to test the right thing. (Leaving the patch in place
# would in fact have broken this job outright - it asserted its search
# text occurred exactly once, and that text no longer exists.)
#
# This clone's own thirdparty/tcc has nothing to do with the
# bundle staged above (a brand new clone doesn't have one yet),
# so letting `make`'s default target bootstrap it normally here
Expand Down Expand Up @@ -733,30 +738,6 @@ jobs:
git clone --quiet "https://github.com/${{ github.repository }}" /tmp/v-bootstrap-workspace
git -C /tmp/v-bootstrap-workspace checkout --quiet "${{ github.sha }}"

python3 - <<'PYEOF'
path = "/tmp/v-bootstrap-workspace/vlib/builtin/builtin_d_gcboehm.c.v"
with open(path, "r", encoding="utf-8", newline="") as f:
content = f.read()
old = ('\t\t\t\t\t\t$if arm64 {\n'
'\t\t\t\t\t\t\t// tcc on macOS arm64 can leave the bundled GC archive symbols unresolved.\n'
'\t\t\t\t\t\t\t#flag @VEXEROOT/thirdparty/tcc/lib/libgc.dylib\n'
'\t\t\t\t\t\t\t#flag -Wl,-rpath,"@VEXEROOT/thirdparty/tcc/lib"\n'
'\t\t\t\t\t\t} $else {\n'
'\t\t\t\t\t\t\t// macOS amd64 tccbin only ships libgc.a (no .dylib).\n'
'\t\t\t\t\t\t\t#flag @VEXEROOT/thirdparty/tcc/lib/libgc.a\n'
'\t\t\t\t\t\t}\n')
new = ('\t\t\t\t\t\t// SMOKE-TEST-ONLY PATCH (thirdparty-macos-amd64_bdwgc_validate.sh\n'
'\t\t\t\t\t\t// caller) - never committed. Deliverable C applies this for real.\n'
'\t\t\t\t\t\t#flag @VEXEROOT/thirdparty/tcc/lib/libgc.dylib\n'
'\t\t\t\t\t\t#flag -Wl,-rpath,"@VEXEROOT/thirdparty/tcc/lib"\n')
count = content.count(old)
assert count == 1, f"expected exactly 1 occurrence of the selector block to patch, found {count}"
content = content.replace(old, new)
with open(path, "w", encoding="utf-8", newline="") as f:
f.write(content)
print("smoke-test-only selector patch applied in isolated workspace")
PYEOF

(cd /tmp/v-bootstrap-workspace && make -j4)

- name: Prove a failing TCC cannot fall back to another compiler
Expand Down
17 changes: 9 additions & 8 deletions vlib/builtin/builtin_d_gcboehm.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ $if dynamic_boehm ? {
$if !use_bundled_libgc ? {
$if macos {
$if tinyc {
$if arm64 {
// tcc on macOS arm64 can leave the bundled GC archive symbols unresolved.
#flag @VEXEROOT/thirdparty/tcc/lib/libgc.dylib
#flag -Wl,-rpath,"@VEXEROOT/thirdparty/tcc/lib"
} $else {
// macOS amd64 tccbin only ships libgc.a (no .dylib).
#flag @VEXEROOT/thirdparty/tcc/lib/libgc.a
}
// tcc cannot reliably link the bundled *static* GC archive on
// either macOS arch: its Mach-O archive reader leaves the GC
// symbols unresolved against an archive built by a modern
// toolchain, even though `nm -g` shows them defined. arm64 has
// always used the dynamic library for that reason; amd64 now
// does too, because tccbin ships a libgc.dylib rebuilt in
// lockstep with each tcc.exe for it as of vlang/v#27982.
#flag @VEXEROOT/thirdparty/tcc/lib/libgc.dylib
#flag -Wl,-rpath,"@VEXEROOT/thirdparty/tcc/lib"
} $else {
#flag -L@VEXEROOT/thirdparty/tcc/lib
#flag -lgc
Expand Down
14 changes: 11 additions & 3 deletions vlib/v/builder/gc_flags_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,17 @@ fn test_macos_tcc_boehm_uses_bundled_libgc() {
defer {
os.rm(exe_path) or {}
}
assert res.exit_code == 0
// macOS amd64 tccbin only ships libgc.a (no .dylib).
assert res.output.contains('thirdparty/tcc/lib/libgc.a')
assert res.exit_code == 0, res.output
normalized := res.output.replace('\\', '/')
// tcc cannot reliably link the bundled static archive on macOS, so both
// arches link the paired libgc.dylib with an rpath instead. tccbin ships
// one for amd64 as of vlang/v#27982; arm64 already did.
assert normalized.contains('thirdparty/tcc/lib/libgc.dylib'), res.output
assert normalized.contains('-rpath'), res.output
// The static archive must be gone from the link line entirely - this is
// what actually proves the selector collapsed, rather than the dylib
// merely being present alongside it.
assert !normalized.contains('thirdparty/tcc/lib/libgc.a'), res.output
assert !res.output.contains(' -lgc')
}

Expand Down
Loading