Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple defintions from header-only C libraries #18776

Open
define-private-public opened this issue Sep 1, 2021 · 5 comments
Open

Multiple defintions from header-only C libraries #18776

define-private-public opened this issue Sep 1, 2021 · 5 comments

Comments

@define-private-public
Copy link
Contributor

For the stb_image wrapper I wrote, someone filed a bug reporting they were getting "multiple definition" issues:

C:\Users\Skaruts\nimcache\main_d\read.c.o:read.c:(.text+0x79e1): multiple definition of `stbi_failure_reason'
C:\Users\Skaruts\nimcache\main_d\textures.c.o:textures.c:(.text+0xb038): first defined here
C:\Users\Skaruts\nimcache\main_d\read.c.o:read.c:(.text+0x79e9): multiple definition of `stbi_image_free'
C:\Users\Skaruts\nimcache\main_d\textures.c.o:textures.c:(.text+0xb050): first defined here
C:\Users\Skaruts\nimcache\main_d\read.c.o:read.c:(.text+0x79f8): multiple definition of `stbi_set_flip_vertically_on_load'
C:\Users\Skaruts\nimcache\main_d\textures.c.o:textures.c:(.text+0xb05f): first defined here
C:\Users\Skaruts\nimcache\main_d\read.c.o:read.c:(.text+0x79ff): multiple definition of `stbi_load_gif_from_memory'
C:\Users\Skaruts\nimcache\main_d\textures.c.o:textures.c:(.text+0xb093): first defined here
C:\Users\Skaruts\nimcache\main_d\read.c.o:read.c:(.text+0x7af4): multiple definition of `stbi_is_hdr_from_memory'

When I asked a bit more about their project, they said they also included nimraylib_now, which is a Raylib binding, which also includes stb_image. Both of these projects include the stb_image header file, and thus cause multiple definitions conflicts upon compilation.

I know this is more of a C issue rather than a Nim issue, but with the rise of popularity of header-only libraries in C/C++ land, it's only natural that many people will want to use them more in Nim as well. And this will probably lead to more conflicts like the above mentioned. Is there any easy way to mitigate this problem from arising in my library?


Or maybe as a more complex feature, could the Nim compiler do some name mangling on functions exposed from C/C++ to prevent issues like this automatically for any developers?

@Araq
Copy link
Member

Araq commented Sep 1, 2021

Does your wrapper use .header?

@RSDuck
Copy link
Contributor

RSDuck commented Sep 1, 2021

Does your wrapper use .header?

I don't think that should matter.

The issue at hand are header only C++ libraries where there's a single header file which also includes all the source code of the library behind an ifdef. Projects then have a source file where they define this ifdef and include the header.

Single header libraries are more or less a workaround to the tons of problems configuring dependencies in C/C++ can have. And because C/C++ developers are usually more wary of deep depedency chains/start to use classically linked libraries once deeper dependency chains come around this isn't really an issue there.

Or maybe as a more complex feature, could the Nim compiler do some name mangling on functions exposed from C/C++ to prevent issues like this automatically for any developers?

that would require the Nim compiler to parse C++ which sounds like a desaster.

A possible solution for this concrete case would be to utilise the fact that stb_image has a workaround for this: https://github.com/define-private-public/stb_image-Nim/blob/master/stb_image/stb_image.h#L345

A single Nim module would probably have to use something like {.emit: "#define STB_IMAGE_STATIC\n#include \"stb_image.h\"".} then do all the importc inside that module (unexported!) and wrap them in Nim in that module.

EDIT: another (easier) solution would be to give the option to disable the compilation of the C++ source file of stb_image. Then the Nim importc's would just link with raylib's stb_image.

@define-private-public
Copy link
Contributor Author

Does your wrapper use .header?

No, that's something my wrapper isn't using. Is that a newer feature of Nim? My wrapper was made initially around 4+ years ago.

@Araq
Copy link
Member

Araq commented Sep 4, 2021

Well .header could mitigate the problem, that's why I brought it up. (It could also make things worse... :-) )

@define-private-public
Copy link
Contributor Author

How would .header make things worse?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants