How can I compile Cimgui statically and then use it?

756 views Asked by At

I'm new to C and I need some help with linking and compeileing.

Here is the library which I want to use: cimgui github I followed the instructions about how can I compile the library with the makefile and with CMake. (This is the make i use) When I used the makefile which was included in the project I used "make static" and in CMake I used MinGW makefile option and made the static option to "yes". With both options I successfully generated the .a file, so far so good. The problem comes when I try to compile a C code with the library. I tried: gcc main.c -o guitest cimgui.a but I get a lot of errors of compileing the header file (i guess). Any ideas how to make it work?

Thanks.

Here is some of the error code:

D:\Prog\C\gui>gcc main.c -o guitest cimgui.a
In file included from main.c:3:
cimgui.h:2560:28: error: expected identifier or '(' before ':' token
 typedef struct ImGuiStorage::ImGuiStoragePair ImGuiStoragePair;
                            ^
cimgui.h:2561:31: error: expected identifier or '(' before ':' token
 typedef struct ImGuiTextFilter::ImGuiTextRange ImGuiTextRange;
                               ^
cimgui.h:2562:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
 typedef ImStb::STB_TexteditState STB_TexteditState;
              ^
cimgui.h:2563:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
 typedef ImStb::StbTexteditRow StbTexteditRow;
              ^
cimgui.h:2564:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
 typedef ImStb::StbUndoRecord StbUndoRecord;
              ^
cimgui.h:2565:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
 typedef ImStb::StbUndoState StbUndoState;
              ^
cimgui.h:2566:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImChunkStream<ImGuiTableSettings> ImChunkStream_ImGuiTableSettings;
                      ^
cimgui.h:2567:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImChunkStream<ImGuiWindowSettings> ImChunkStream_ImGuiWindowSettings;
                      ^
cimgui.h:2568:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImPool<ImGuiTabBar> ImPool_ImGuiTabBar;
               ^
cimgui.h:2569:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImPool<ImGuiTable> ImPool_ImGuiTable;
               ^
cimgui.h:2570:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImSpan<ImGuiTableCellData> ImSpan_ImGuiTableCellData;
               ^
cimgui.h:2571:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImSpan<ImGuiTableColumn> ImSpan_ImGuiTableColumn;
               ^
cimgui.h:2572:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImSpan<ImGuiTableColumnIdx> ImSpan_ImGuiTableColumnIdx;
               ^
cimgui.h:2573:17: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImVector<ImDrawChannel> ImVector_ImDrawChannel;
                 ^
cimgui.h:2574:17: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImVector<ImDrawCmd> ImVector_ImDrawCmd;
                 ^
cimgui.h:2575:17: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImVector<ImDrawIdx> ImVector_ImDrawIdx;
                 ^
cimgui.h:2576:17: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
 typedef ImVector<ImDrawList*> ImVector_ImDrawListPtr;



cimgui.h:3768:51: error: unknown type name 'ImFontAtlas'
 CIMGUI_API void igImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas,void* stbrp_context_opaque);
                                                   ^~~~~~~~~~~
cimgui.h:3769:42: error: unknown type name 'ImFontAtlas'
 CIMGUI_API void igImFontAtlasBuildFinish(ImFontAtlas* atlas);
                                          ^~~~~~~~~~~
cimgui.h:3770:60: error: unknown type name 'ImFontAtlas'
 CIMGUI_API void igImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas,int x,int y,int w,int h,const char* in_str,char in_marker_char,unsigned char in_marker_pixel_value);
                                                            ^~~~~~~~~~~
cimgui.h:3771:61: error: unknown type name 'ImFontAtlas'
 CIMGUI_API void igImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas,int x,int y,int w,int h,const char* in_str,char in_marker_char,unsigned int in_marker_pixel_value);
                                                             ^~~~~~~~~~~
cimgui.h:3780:48: warning: 'struct ImGuiTextBuffer' declared inside parameter list will not be visible outside of this definition or declaration
 CIMGUI_API void ImGuiTextBuffer_appendf(struct ImGuiTextBuffer *buffer, const char *fmt, ...);
                                                ^~~~~~~~~~~~~~~
cimgui.h:3787:12: error: unknown type name 'ImVector_ImWchar'
 CIMGUI_API ImVector_ImWchar* ImVector_ImWchar_create(void);
            ^~~~~~~~~~~~~~~~
cimgui.h:3788:42: error: unknown type name 'ImVector_ImWchar'
 CIMGUI_API void ImVector_ImWchar_destroy(ImVector_ImWchar* self);
                                          ^~~~~~~~~~~~~~~~
cimgui.h:3789:39: error: unknown type name 'ImVector_ImWchar'
 CIMGUI_API void ImVector_ImWchar_Init(ImVector_ImWchar* p);
                                       ^~~~~~~~~~~~~~~~
cimgui.h:3790:41: error: unknown type name 'ImVector_ImWchar'
 CIMGUI_API void ImVector_ImWchar_UnInit(ImVector_ImWchar* p);
                                         ^~~~~~~~~~~~~~~~
In file included from main.c:2:
main.c: In function 'main':
main.c:16:66: error: 'ImGuiIO' undeclared (first use in this function)
   assert(igDebugCheckVersionAndDataLayout(igGetVersion(), sizeof(ImGuiIO), sizeof(ImGuiStyle),
                                                                  ^~~~~~~
main.c:16:66: note: each undeclared identifier is reported only once for each function it appears in
main.c:16:83: error: 'ImGuiStyle' undeclared (first use in this function); did you mean 'igGetStyle'?
   assert(igDebugCheckVersionAndDataLayout(igGetVersion(), sizeof(ImGuiIO), sizeof(ImGuiStyle),
                                                                                   ^~~~~~~~~~
main.c:17:50: error: 'ImVec2' undeclared (first use in this function)
                                           sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert),
                                                  ^~~~~~
main.c:17:66: error: 'ImVec4' undeclared (first use in this function)
                                           sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert),
                                                                  ^~~~~~
main.c:17:82: error: 'ImDrawVert' undeclared (first use in this function)
                                           sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert),
                                                                                  ^~~~~~~~~~
main.c:18:50: error: 'ImDrawIdx' undeclared (first use in this function)
                                           sizeof(ImDrawIdx)));
                                                  ^~~~~~~~~
main.c:20:3: warning: implicit declaration of function 'igCreateContext'; did you mean 'igGetCurrentContext'? [-Wimplicit-function-declaration]
   igCreateContext(NULL);
   ^~~~~~~~~~~~~~~
   igGetCurrentContext
main.c:21:12: error: 'io' undeclared (first use in this function)
   ImGuiIO *io = igGetIO();
            ^~
main.c:25:3: warning: implicit declaration of function 'ImFontAtlas_GetTexDataAsRGBA32' [-Wimplicit-function-declaration]
   ImFontAtlas_GetTexDataAsRGBA32(io->Fonts, &text_pixels, &text_w, &text_h, NULL);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:30:11: error: expected ';' before 'display_size'
     ImVec2 display_size;
           ^~~~~~~~~~~~~
           ;
main.c:31:5: error: 'display_size' undeclared (first use in this function)
     display_size.x = 1920;
     ^~~~~~~~~~~~
main.c:37:5: warning: implicit declaration of function 'igBegin'; did you mean 'igBeginMenu'? [-Wimplicit-function-declaration]
     igBegin("mainwindow",NULL,ImGuiWindowFlags_NoTitleBar);
     ^~~~~~~
     igBeginMenu
main.c:37:31: error: 'ImGuiWindowFlags_NoTitleBar' undeclared (first use in this function)
     igBegin("mainwindow",NULL,ImGuiWindowFlags_NoTitleBar);
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:40:5: warning: implicit declaration of function 'igSliderFloat'; did you mean 'igValue_Float'? [-Wimplicit-function-declaration]
     igSliderFloat("float", &f, 0.0f, 1.0f, "%.3f", 0);
     ^~~~~~~~~~~~~
     igValue_Float
main.c:50:3: warning: implicit declaration of function 'igDestroyContext'; did you mean 'igGetCurrentContext'? [-Wimplicit-function-declaration]
   igDestroyContext(NULL);
   ^~~~~~~~~~~~~~~~
   igGetCurrentContext
1

There are 1 answers

0
qrikko On

This is one of the trickier things conceptually with C++ being a superset of C.

It seems reasonable to think that one would compile this library as a C library with a c compiler. But it is not a C implementation of dear imgui. It is just providing a wrapper for the c++ functionality wrapped in a C interface.

So it doesn't touch the dear imgui implementation at all, it just make the library accessible in C.

So, I am not sure it will play nice as a static library, only used it as a shared library. But might well be possible, jumping through some hoops.

I believe that either using a static lib (.a) or shared lib (.so), you will have to do something like this:

  1. #define CIMGUI_DEFINE_ENUMS_AND_STRUCTS before include. This will use the generated definitions to typedef and map all of the C++ interface to C-readable types and symbols.

  2. If linking leads to problems it might well be worth both building the library and compiling your code linking it with -fPIC. It makes sure to use "Position Independent Code" which is a pretty common practice when building shared objects at least. But I am not sure if it is needed.

  3. Dear ImGui is using a lot of C++ functionality so it is quite likely that you will have to link the standard library :/ -lstdc++ in your c project. I haven't found a way around that at least.

For me I ended up going somewhat a different route. I have an architecture which uses a core library completely in C. And for any executable I link that core, and optionally load modules for different functionality. So my core and modules are pure C. When I build my executable it is typically in C, linking the core. But nothing stops it from being a C++ project linking my C libraries. So for my tools I opted to just make it a C++ project, and I can without fuzz use dear imgui. So I compile it as a C++ project including my core in an extern "C" block.

I started out with cimgui, but argued that if I still need to link the c++ standard library there isn't really much point in keeping it pure C. Since I only use it for tools it just doesn't make a lot of sense to bother with keeping it C only.

So to summarize I would think that you should be able to build cimgui with the provided make (or CMake) build pipeline. And to link it you would have something like gcc -fPIC -lcimgui -lstdc++ mycode.c.

I hope it helps someone even if I realize this question is pretty old, I felt it deserved to be answered with what I've figured out while I tried to use the wrapper.