floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.55k stars 469 forks source link

Compiling into a DLL with cimgui/sokol_imgui included #944

Closed kkukshtel closed 7 months ago

kkukshtel commented 7 months ago

I'm having a hard time trying to figure out how to compile a single DLL that packs in the util libs for imgui like sokol_imgui (and cimgui.h). I've been combining everything as a single DLL before without issue, but something about the compilation chain is acting wonky, maybe because imgui.h needs to be compiled as a C++ library? Would love any help here. Here's the file im trying to compile (and using the basic zig compilation as a template taken from the zig bindgen stuff):

#define SOKOL_IMPL
#define SOKOL_DLL
#define SOKOL_NO_ENTRY
#define SOKOL_TRACE_HOOKS
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#include "../src/sokol/sokol_app.h"
#include "../src/sokol/sokol_args.h"
#include "../src/sokol/sokol_audio.h"
#include "../src/sokol/sokol_fetch.h"
#include "../src/sokol/sokol_gfx.h"

#include "../src/sokol_gp/sokol_gp.h"

#include "../src/sokol/sokol_glue.h"
#include "../src/sokol/sokol_time.h"
#include "../src/sokol/sokol_log.h"

#include "../src/sokol/util/sokol_color.h"
#include "../src/sokol/util/sokol_debugtext.h"
#include "../../cimgui/src/cimgui/imgui/imgui.h"
#include "../../cimgui/src/cimgui/cimgui.h"
#include "../src/sokol/util/sokol_imgui.h"
#include "../src/sokol/util/sokol_gfx_imgui.h"

I'm seeing these errors in the console:

zig build-lib sokol Debug native: error: error(compilation): clang failed with stderr: In file included from /Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/sokol.c:31:
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:256:43: error: must use 'struct' tag to refer to type 'ImGuiInputTextCallbackData'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:257:38: error: must use 'struct' tag to refer to type 'ImGuiSizeCallbackData'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:267:5: error: unknown type name 'constexpr'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:267:47: error: call to undeclared function 'x'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:267:58: error: expected parameter declarator
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:267:58: error: expected ')'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:267:57: note: to match this '('
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:267:56: error: duplicate member 'y'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:266:48: note: previous declaration is here
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:267:63: error: expected ';' at end of declaration list
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:5: error: unknown type name 'constexpr'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:76: error: expected parameter declarator
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:76: error: expected ')'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:75: note: to match this '('
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:74: error: duplicate member 'y'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:279:66: note: previous declaration is here
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:85: error: expected parameter declarator
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:85: error: expected ')'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:84: note: to match this '('
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:83: error: duplicate member 'z'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:279:69: note: previous declaration is here
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:94: error: expected parameter declarator
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:94: error: expected ')'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:93: note: to match this '('
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:92: error: duplicate member 'w'
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:279:72: note: previous declaration is here
/Users/kyle/Workspace/Dinghy/Dinghy.Bootstrapper/libs/sokol/build/../../cimgui/src/cimgui/imgui/imgui.h:280:99: error: expected ';' at end of declaration list
fatal error: too many errors emitted, stopping now [-ferror-limit=]

Would love any help or guidance here!

kkukshtel commented 7 months ago

Also looking a little more — maybe it's worth just compiling Sokol + imgui together with Cpp into a seperate DLL that works with a different DLL that has the other Sokol libs compiled with C? Not sure if that would work or be a better option?

floooh commented 7 months ago

Yes, the errors look like the C++ code from imgui.h is compiled as C code.

One solution would be to compile your impl-source file as C++ (just change the extension to .cpp should do it). I'm not sure if sokol_gp.h compiles as C++ though (the other headers should work).

If this doesn't work, split the code into two impl source files, one C++ impl file with the imgui and cimgui implementations, and one C impl file where you'd need to remove the imgui.h header, then compile them into two object files and link them into a DLL.

kkukshtel commented 7 months ago

The latter was what I was considering, but the former sounds easier. However I thought I read somewhere that you were thinking of deprecating the cpp compile option for Sokol? Also - if it's being compiled as cpp I assume I could just skip cimgui and use imgui.h directly?

floooh commented 7 months ago

However I thought I read somewhere that you were thinking of deprecating the cpp compile option for Sokol?

True, I've been considering this, but I haven't made up my mind yet. At least for the core headers (sokol_app.h, sokol_gfx.h) this won't be anytime soon. If I ever switch to C only for the implementations, the "second tier" headers would be first (like sokol_gl.h)

Also - if it's being compiled as cpp I assume I could just skip cimgui and use imgui.h directly?

This depends entirely on whether you want to write your Dear ImGui UI code as C++ or C :)

kkukshtel commented 7 months ago

Well for my case I'm just wrapping the api to be called from c# so it seems like maybe the distinction for me is moot? Going the c++ route seems better just to cut out an erroneous dep because I'm just binding against what the Sokol layer exposes.

Good to know about the c++ future for Sokol as well! Seems like it's okay to build against it for now and maybe change some build stuff in the future should it change.

kkukshtel commented 7 months ago

Would it be possible to compile sokol_imgui.h as C++ but still use cimgui.h?

floooh commented 7 months ago

Yes, cimgui itself is a C++ project (the implementation is in a file cimgui.cpp). The cimgui.h header just exposes a plain C API.

kkukshtel commented 7 months ago

Yes, cimgui itself is a C++ project (the implementation is in a file cimgui.cpp). The cimgui.h header just exposes a plain C API.

The issue I'm running into though is that sokol_imgui.h expects to use cimgui.h if C and imgui.h if C++. So attempting to compile it all as C++ makes Sokol mad. I guess I'm asking if there is a way to force the use of cimgui.h in sokol_imgui.h even if it's compiled as C++.

floooh commented 7 months ago

I guess I'm asking if there is a way to force the use of cimgui.h in sokol_imgui.h even if it's compiled as C++.

There isn't, but it shouldn't matter because cimgui.h is just a stateless shim around imgui.h, so it should be possible to mix cimgui and imgui calls in the same application. Are you seeing any specific errors?

kkukshtel commented 7 months ago

The issue was that compiling it all as C++ would throw the Sokol errors but I guess I never tried it to see if it still worked regardless. The issue was more that, because I was accessing the functions through C# bindings, things got weird when trying to call the C++ code or C code if compiled with the other language.

I think I got a fix though which was what you had previously suggested. I built static libs of imgui+cimgui and Sokol, then combined them together into a DLL. This seems to work at least but now I'm fixing bindings but I think I've got it all sorted!

kkukshtel commented 7 months ago

I guess I'm asking if there is a way to force the use of cimgui.h in sokol_imgui.h even if it's compiled as C++.

There isn't, but it shouldn't matter because cimgui.h is just a stateless shim around imgui.h, so it should be possible to mix cimgui and imgui calls in the same application. Are you seeing any specific errors?

I marked this as completed but just to follow up (I'm also debugging this in the zig discord) - compiling as C++ but including cimgui.h instead of imgui.h will make Sokol warn(error?) to include imgui.h, but the code will still work right? It's more of a safety measure?

kkukshtel commented 7 months ago

Got it all to work by just compiling it all together into a big dll with zig. I think the issues were more about the build pipeline and not Sokol!