Immediate-Mode-UI / Nuklear

A single-header ANSI C immediate mode cross-platform GUI library
https://immediate-mode-ui.github.io/Nuklear/doc/index.html
Other
9.06k stars 542 forks source link

Compiling Examples with different Backends #544

Open DiegoJArg opened 1 year ago

DiegoJArg commented 1 year ago

Hi. I am very new here. And very interested on this low-resources gui concept. While trying the demos, I made a unified Makefile that I am attaching here to be executed from Nuklear/demo directory. Makefile.zip

However, I couldn't figure out how to compile the examples with different backends. The example folder contains another backend stb_image.h not present on the demo folder. And those c-files contains calls to a stbi_load function which is not present in other backends like the GDI ones. Is it possible to try the same 'complex' examples with multiple backends?

It would be an interesting approach to compile a project with different backends without modifying the sources, probably through DEFINE passed to the compiler. Is that possible or planned?

Other thing that called my attention was about the "Small codebase (~18kLOC)" and "(you can compile and use only what you need)". A very basic non-nuklear gdi example is ~100kb while the most basic example of nuklear is ~500kb. A heavier example, as those in the example folder, are about ~700kb. Not complaining at all! But I wonder if there is one step missing to "compile and use only what you need" or I should know that this is the bare minimum and the maximum is still unknown.

gdi_basic.zip nk_gdi.zip

Many thanks in advance !

dumblob commented 1 year ago

However, I couldn't figure out how to compile the examples with different backends. The example folder contains another backend stb_image.h not present on the demo folder. And those c-files contains calls to a stbi_load function which is not present in other backends like the GDI ones. Is it possible to try the same 'complex' examples with multiple backends?

We do not have such complex examples utilizing multiple backends in our repo. But many of Nuklear users probably have such apps (ping them or perhaps some of them will appear here in a few months/years - yeah, we are a slow repo :wink:).

OTOH it is super easy to port any app to a different backend - maybe 10 SLOC (yes, ten) and you are done :wink:.

It would be an interesting approach to compile a project with different backends without modifying the sources, probably through DEFINE passed to the compiler. Is that possible or planned?

Definitely possible. Planned actually yes, but nobody stood up to do it :wink:. PRs welcome (read https://github.com/Immediate-Mode-UI/Nuklear#reviewers-guide )!

Other thing that called my attention was about the "Small codebase (~18kLOC)" and "(you can compile and use only what you need)". A very basic non-nuklear gdi example is ~100kb while the most basic example of nuklear is ~500kb. A heavier example, as those in the example folder, are about ~700kb. Not complaining at all! But I wonder if there is one step missing to "compile and use only what you need" or I should know that this is the bare minimum and the maximum is still unknown.

I think our "most basic" examples all use fonts. And for font handling you need a font handling library (which is embedded into Nuklear by default - DEFINEs can change this though) and the font itself. I guess that is the major source of the "bloat".

Did I answer your questions?

DiegoJArg commented 1 year ago

Thank you for your comments @dumblob. I am just too new here yet to be more helpful.

While playing with the lib, I noted that #define NK_PRIVATE is meant to define all functions as static through NK_API. Enabling it reduced ~100kb from the demo/gdi. But NK_API defaults to extern instead of defaulting to static. Since one of the main awesome concepts of this project is to be a single-file-header, I guess the expected would be to default to static, unless NK_LIB is defined.

Also played with NKINCLUDE* defines, disabled them all, and with NK_INCLUDE_DEFAULT_ALLOCATOR disabled, I get nk_init_default() undefined. I know that this is explained in the files itself's, but if nk_init_default is the actual default, then NK_INCLUDE_DEFAULT_ALLOCATOR should probably be defaulted too, or defined to default into a fixed nk_init_fixed.

Additionally, since this produces a single self-contained executable, If compiling with gcc -s which 'Removes all symbol table and relocation information from the executable', it reduced demo/gdi to 50%. Although, to be honest, I am not aware of implications.

I think our "most basic" examples all use fonts. And for font handling you need a font handling library (which is embedded into Nuklear by default - DEFINEs can change this though) and the font itself. I guess that is the major source of the "bloat".

I've started up using demo/gdi, which doesn't have defined NK_INCLUDE_FONT_BAKING or NK_INCLUDE_DEFAULT_FONT. It seems that to include the font, I have to define them, otherwise I understand that no-fonts are being loaded ? Instead, would it use system fonts?

However, I couldn't figure out how to compile the examples with different backends.

I noted now that at demo/gdi there is a defined for that: INCLUDE_ALL. Which includes demo's from the common folder.