Problems:
- Nuklear is configured with macro defines. If you're including it inside of multiple source files, you need to ensure that config stays the same across all of them.
- If you change any macro define, you should recompile whole Nuklear and all files using it just to be sure. If macro defines come from command line, it complicates this process a lot, even with proper incremental build system.
- Nuklear may depend on some specific header coming from other library (e.g.
<SDL3/SDL.h> in case you want to reuse SDL's types) and ensuring that this header is available everywhere is complicated
- clangd (LSP) and other static analysis tools can get quite confused when predefines are coming indirectly from source file (see my comment below)
- Currently, if you want those problems solved, you need all kinds of hacks to make it behave correctly, either in build recipe or somewhere in Nuklear.
- I've created a kicka$$ config for
demo/sdl3_renderer, which lets you build this demo on multiple platforms, but due to mentioned limitations, it must live in the main file here, which makes it quite awkward to copy and reuse in your own code (example)
- demos with similar backends could reuse the same configuration code, which is currently impossible
I thought about all of these for quite some time, and the solution that I use in my personal branch looks like this. Somewhere at the very top of src/Nuklear.h :
/*
* Useful when you have a lot of stuff that you want to overwrite
* Create "nk_config.h" file somewhere and make sure that preprocessor can find it
* For example, use following compiler flags: -I/path/to/config/dir -DNK_CONFIG
*/
#ifdef NK_CONFIG
#include "nk_config.h"
#endif
^ This works very well for my build system (custom GNU Make recipe), and I'm pretty sure it should work with everything else too. I've seen this trick used throughout many C libraries. Every private file in Nuklear is including this thing so it solves the problem. We should probably ensure that src/nuklear_internal.h also includes it, and maybe add our own include guards just to make sure, but those are just details that I'll figure out.
If you clicked at the link to the branch from above, you would also notice that I already tried a different solution:
#ifdef NK_CONFIG_FILE
#include NK_CONFIG_FILE
#endif
^ but this one is impossible to support portably. MSVC does not support this trick to this very day, and trying to support it would require additional macro. I also noticed that passing paths into macro defines at command line (e.g. -Dmacro=/my/path) is very error prone (expansion works differently between compilers and shell types) and so I abandoned this idea entirely. (but we can also add it later, I guess)
Any thoughts ?
Problems:
<SDL3/SDL.h>in case you want to reuse SDL's types) and ensuring that this header is available everywhere is complicateddemo/sdl3_renderer, which lets you build this demo on multiple platforms, but due to mentioned limitations, it must live in the main file here, which makes it quite awkward to copy and reuse in your own code (example)I thought about all of these for quite some time, and the solution that I use in my personal branch looks like this. Somewhere at the very top of
src/Nuklear.h:^ This works very well for my build system (custom GNU Make recipe), and I'm pretty sure it should work with everything else too. I've seen this trick used throughout many C libraries. Every private file in Nuklear is including this thing so it solves the problem. We should probably ensure that
src/nuklear_internal.halso includes it, and maybe add our own include guards just to make sure, but those are just details that I'll figure out.If you clicked at the link to the branch from above, you would also notice that I already tried a different solution:
^ but this one is impossible to support portably. MSVC does not support this trick to this very day, and trying to support it would require additional macro. I also noticed that passing paths into macro defines at command line (e.g.
-Dmacro=/my/path) is very error prone (expansion works differently between compilers and shell types) and so I abandoned this idea entirely. (but we can also add it later, I guess)Any thoughts ?