Hello! I am new to the nim community, so bear with me if I'm discussing 
something that's already been debated.

I've been getting into nim recently for game development and I just encountered 
an interesting issue. I started by bringing in 
[nimGL](https://github.com/lmariscal/nimgl) to get started quicker with the 
openGL context creation and window management stuff, and that's been working 
great for me so far. But then I got to the part where I wanted to load in some 
images to create textures, and grabbed [stb_image nim 
bindings](https://github.com/define-private-public/stb_image-Nim) because I've 
had a good experience with it in C. To my surprise, importing this library 
caused several linker errors:
    
    
    C:\Users\chr\nimcache\game_d\read.c.o:read.c:(.text+0x1f8): multiple 
definition of `stbi_failure_reason'
    C:\Users\chr\nimcache\game_d\stb_image.c.o:stb_image.c:(.text+0x1f8): first 
defined here
    C:\Users\chr\nimcache\game_d\read.c.o:read.c:(.text+0x4e9): multiple 
definition of `stbi_image_free'
    C:\Users\chr\nimcache\game_d\stb_image.c.o:stb_image.c:(.text+0x4e9): first 
defined here
    C:\Users\chr\nimcache\game_d\read.c.o:read.c:(.text+0x505): multiple 
definition of `stbi_set_flip_vertically_on_load'
    C:\Users\chr\nimcache\game_d\stb_image.c.o:stb_image.c:(.text+0x505): first 
defined here
    ....

And so on. At first I was confused, then I found the `--verbosity` flag on the 
nim compiler and noticed this:
    
    
    gcc.exe .... -DSTB_IMAGE_IMPLEMENTATION ..... 
C:\Users\chr\nimcache\game_d\game.c

On all the files in the build. I was like "huh, that's funny" and went and 
looked at the stb_image implementation, but it was using a #define 
STB_IMAGE_IMPLEMENTATION in a .c file to activate its implementation, not a 
compiler flag. So then I sat around confused for a minute and then grepped my 
entire user folder for it, and voila! Turns out nimGL is packaging stb_image 
with itself and passing this option via `{.passC.}`:
    
    
    {.passC: "-DSTB_IMAGE_IMPLEMENTATION -I" & 
currentSourcePath().splitPath.head & "/../private/stb",
     compile: "../private/stb/stb_image.c"}

So the problem is simply that both libraries are defining the same symbols.

On the one hand, maybe one of these libraries is behaving badly, but both seem 
like they're making pretty reasonable decisions here. Furthermore, I'd rather 
not just _not use_ the stb_image library, even though it's apparently 
superfluous, because its nim wrapper is more intuitive to use.

Am I wrong in thinking that this is indicative of a slightly larger problem? In 
particular, I believe this is an instance of the [diamond dependency 
problem](https://en.wikipedia.org/wiki/Dependency_hell#Problems) that crops up 
all over the place. In this case, both libraries depend on stb_image, and that 
causes redundant symbol definitions. But more generally, any two libraries 
which both depend on the same C library will cause this. I don't think 
stb_image is special because it's header-only, consider that two versions of 
some static library libfoo.a will export the same symbols as well.

Perhaps for a systems language like nim, we can declare that users of a library 
should be responsible for resolving this and exert maximum control over their 
code. But that feels unsatisfying to me, because the point of a language like 
nim is to strike a balance between control and convenience. Is there a 
nim-language- or nim-compiler-level solution to this? Has this already been 
brought up/explored? I'm curious what you all think of the matter.

Anyway, cheers from a potential future nim-lover,

\-- chr

Reply via email to