QB64-Phoenix-Edition / QB64pe

The QB64 Phoenix Edition Repository
https://qb64phoenix.com
Other
132 stars 26 forks source link

QB64 preprocessor variables should be visible inside C header libraries #55

Open a740g opened 2 years ago

a740g commented 2 years ago

In the example below defcheck() returns 1. It would be helpful if it could see the QB64 preprocessor variable and return 5 instead.

This will allow us to directly use many single file C header libraries on GitHub, like the famous STB header only libraries. Without the QB64 preprocessor variables visible, we must write a "stub" .h file with #define XYZ_IMPLEMENTATION and then include the actual header file.

-----------------------------
prog.bas
-----------------------------
$Let PENTIUM = 100
Declare Library "./myclib"
    Function defcheck&
End Declare

Print defcheck

End

-----------------------------
myclib.h
-----------------------------
int defcheck()
{
#ifdef PENTIUM
    return 5;
#else
    return 1;
#endif
}
mkilgore commented 2 years ago

This touches a lot on what I wrote about in #49. Unfortunately I don't have the time to look into it yet but I think we need to iron out a more holistic approach for including separate C/C++ code rather than just addressing some of these individual problems. I actually mentioned this use case in that card already ("Including C code from a header").

For this particular suggestion I'm a little iffy about just exposing them all. A small part of it is that I'm not sure $Let variables map that well to #defines, but my bigger concern is the large potential it has for causing problems. Keep in mind that preprocessor variables will replace any instance of that token in the C/C++ source file, so you could easily get compilation problems if you make a $Let with too basic a name - it might even still compile but produce a bugged program. And due to how the compilation works they would interact with the generated C++ code as well, so any $Let variable that matches a name in the generated C++ would create big problems, and that's not really something we can easily detect and prevent. It would also likely break existing programs :-/

The other aspect is how this kind of thing would play out when #40 is worked on and the generated program is eventually compiled from multiple separate sources, which unfortunately is a whole separate can of worms and probably can't be done without it being a breaking change. But in that situation just providing the same set of #defines to every file obviously won't work for libraries like the STB ones, since it would include the implementation multiple times and cause linking errors.

Going off what I suggested in #49, I think the best way to support this is that you provide a separate C file which includes the proper #define XYZ_IMPLEMENTATION to get all the definitions, and then it would get compiled separately and linked it with your QB64 program. That creates the simplest process since then the generated QB64 code itself can just include the header normally and does not need to worry about including it once with the correct #define. But until that theoretical idea is done there's no easy way for you to do this without just having a separate build process to produce the compiled implementation, so it doesn't really help you right now.

So with that said, I think this is still worth discussing, perhaps some kind of "in between" solution could be warranted to make it easy to work around the issue for the moment even if it's not a real long term solution. @SteveMcNeill and I were talking about some similar stuff in the discord yesterday, it was brought up that we could have a text box in the IDE configuration for entering extra compilation flags, and that would allow you to add the -DXYZ_IMPLEMENTATION to the compilation. I personally wasn't a fan of the idea because I don't want people to start relying on it when it will likely have to go away in the future, but perhaps it would at least provide a kind of 'escape hatch' for you to use for the moment while we figure out a better approach. That's also something I think has a realistic chance of being easy to implement and thus could actually get added relatively soon.