v 0.5.2 ee46dc3 (Windows, tcc/gcc)vtext, a text-shaping library outside this repo, vendors stb_truetype.h
from thirdparty/fontstash with STB_TRUETYPE_IMPLEMENTATION and
STBTT_STATIC, so that linking it beside gg does not produce two copies of
every stbtt_ symbol. vlib/fontstash includes the same header from the same
path, with the same two macros.
A 25-line program that opens a gg window and calls into that module fails
with 453 errors:
thirdparty/fontstash/stb_truetype.h:1133:20: error: redefinition of 'stbtt__buf_get8'
thirdparty/fontstash/stb_truetype.h:1140:20: error: redefinition of 'stbtt__buf_peek8'
thirdparty/fontstash/stb_truetype.h:1147:13: error: redefinition of 'stbtt__buf_seek'
thirdparty/fontstash/stb_truetype.h:1153:13: error: redefinition of 'stbtt__buf_skip'
thirdparty/fontstash/stb_truetype.h:1158:21: error: redefinition of 'stbtt__buf_get'stb_truetype.h:502 turns STBTT_STATIC into #define STBTT_DEF static, so
both inclusions emit static int stbtt__buf_get8(...). The error itself shows
why STBTT_STATIC no longer prevents this: redefinition in one translation
unit is a compile error, whereas the same name defined static in two
different translation units is not. When V emitted one CU per module the
macro was sufficient; now both definitions land in one CU and collide inside
it.
module main
import gg
import vtext
fn main() {
ctx := vtext.new_context()
_ = ctx
mut w := gg.new_context(width: 200, height: 120, create_window: true,
window_title: 'x', frame_fn: frame)
w.run()
}
fn frame(mut c gg.Context) {}Two things I checked rather than assumed, in case they change the shape of
this: both thirdparty/fontstash/fontstash.h (lines 289-296) and the library's
stbtt.c.v (lines 21-23) set the macro, so neither is a stray copy; and the
failure is the same whether vtext is imported first or second, and with
either tcc or gcc.
I could not find an existing report — searching for stbtt__buf_get8
redefinition and gg vtext stb_truetype turned up nothing, but I may have
the wrong terms, so apologies if this is a duplicate.
I tried this on ecafbd9 using a small local standin for
vtext. It builds when I import the standin by itself but fails with duplicatestb_truetypedefinitions when I import it alongsidefontstash. I saw the same thing with-old-compilertoo.The generated C has both implementations in the same translation unit.
STBTT_STATICdoesn’t prevent that: it gives the functions internal linkage but you still can’t define the same function twice in one unit. Simply deduplicating the include could also break things, since the two copies can use differentSTBTT_mallochooks.I got it working by putting one implementation and its callers in a separate
.cfile, compiling that to an object and exposing wrapper functions to V.So this seems to be a limitation of how V combines C directives from modules, rather than a V3 regression. I haven’t tested on Windows or on the older release mentioned in the issue.
I wonder would documenting the separate object approach be enough here or is broader support for isolating module C implementations something V should consider?