Linux tcc: build without the legacy bounds-checking runtime (glibc 2.34+)

tcc 0.9.27's lib/bcheck.c uses __malloc_hook, removed in glibc 2.34, so
the pinned build failed on Ubuntu 24.04 (lib/bcheck.c:738). Shards never use
-b; the build now passes BCHECK_O= unconditionally, keeping every other
libtcc1.a object. The bundle smoke also clears LIBRARY_PATH, CC and
GCC_EXEC_PREFIX and checks shards import no bounds-checking symbols.
Verified: linux_tcc_bundle_smoke_test passes on Ubuntu 24.04 x86_64
(glibc 2.39, gcc + libc6-dev installed, so host headers exist but are not
used) and on Steam Runtime sniper (glibc 2.31).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Shokunin
2026-10-13 00:02:09 -07:00
parent 9714fb678a
commit 3fee0ae7be
3 changed files with 14 additions and 5 deletions
+6 -2
View File
@@ -134,8 +134,8 @@ def main():
out = os.path.join(work, 'shard_f%d.so' % flavor)
env_keep = dict(os.environ)
os.environ['PATH'] = '/nonexistent' # no host compiler can help
os.environ.pop('CPATH', None)
os.environ.pop('C_INCLUDE_PATH', None)
for v in ('CPATH', 'C_INCLUDE_PATH', 'LIBRARY_PATH', 'CC', 'GCC_EXEC_PREFIX'):
os.environ.pop(v, None)
try:
ok = co._compile_dll_tcc(c_path, out, [inc], flavor, tcc)
finally:
@@ -153,6 +153,10 @@ def main():
if not hasattr(lib, 'func_80114000'):
print('FAIL flavor %d: func_80114000 not exported' % flavor)
fails += 1
nm = os.popen('nm -D --undefined-only %s' % out).read()
if 'bound' in nm or '__bound' in nm:
print('FAIL flavor %d: the shard references bounds-checking symbols' % flavor)
fails += 1
print('ok flavor %d: shard built by the bundled tcc + musl and loaded (abi 0x%X)'
% (flavor, abi))
return 1 if fails else 0
+7 -2
View File
@@ -706,8 +706,13 @@ def stage_linux_tcc(toolchain, dl_cache, pins, log=print):
cc = os.environ.get('CC', 'cc')
_run_build(['./configure', '--prefix=' + inst, '--cc=' + cc,
'--extra-cflags=-O2'], tcc_src, 'tcc configure')
_run_build(['make', '-j%d' % (os.cpu_count() or 2)], tcc_src, 'tcc build')
_run_build(['make', 'install'], tcc_src, 'tcc install')
# BCHECK_O= : leave out lib/bcheck.o, tcc's legacy bounds-checking runtime
# (-b). Shards never use it, and it does not build against current glibc
# (it uses __malloc_hook, removed in glibc 2.34: Ubuntu 24.04 fails at
# lib/bcheck.c:738). libtcc1.a keeps every other object. Unconditional,
# so every build host produces the same bundle.
_run_build(['make', '-j%d' % (os.cpu_count() or 2), 'BCHECK_O='], tcc_src, 'tcc build')
_run_build(['make', 'install', 'BCHECK_O='], tcc_src, 'tcc install')
musl = get_pinned_archive(pins['musl_url'], pins['musl_sha256'],
os.path.join(dl_cache, _url_basename(pins['musl_url'])),