I use wxWidgets when I'm writing desktop GUI programs. It allows me to write a program once and have it run well on Apple macOS, MS-Windows, Linux.
I link my program statically with the wxWidgets library, which exports symbols which all begin with 'wx', for example:
wxShowTip, wxYield, wxRadioBox::Enable (mangled to _ZN10wxRadioBox6EnableEb)
Currently on my Linux PC, I have two versions of the wxWidgets static libraries installed:
(1) Based on GTK3
(2) Based on X11
The GTK3 is smoother and nicer, but the X11 will work on anything running an X server.
I've been able to build an executable file that links dynamically with the GUI library -- I mean I can build an executable for GTK3 that loads '
libgtk-3.0.so' at runtime. Similarly I can build an executable for X11 that loads 'libX11.so' at runtime. I already have that tested and working. If neither GTK3 nor X11 are present then my executable can still be used as a simple console app (it only needs 'glibc' installed).
I was thinking it would be cool though, if I were to link my executable statically with both the GTK3 and X11 versions of the wxWidgets libraries, but of course though, I would get symbol clashes. So here's what I would need to do:
(Step 1) Use objcopy on the wxWidgets-GTK3 static libraries to prefix "gtk3_" to every exported symbol.
(Step 2) Use objcopy on the wxWidgets-X11 static libraries to prefix "x11_" to every exported symbol.
So then my executable would have symbols linked into it such as "gtk3_wxYield" and "x11_wxYield".
Then at runtime, my executable would check for the existence of "
libgtk-3.0.so", and if it finds it, it would load it and use it. However if it can't find it, it would load 'libX11.so' instead.
So how am I going to do this? Well a few ideas are swirling in my head right now, and it's 11:15pm here so I'll probably go to bed and wake up with a solution, but anyway here's what I could do:
(Step 3) Compile all of my C++ source files to object files, for example (main.cpp -> main.o)
(Step 4) Make a copy of all the object files, so that one is called main.o.x11, and the other is called main.o.gtk3.
(Step 5) Use objcopy on all the ".o.x11" files in order to prefix "x11_" to every symbol that begins with "wx".
(Step 6) Use objcopy on all the ".o.gtk3" files in order to prefix "gtk3_" to every symbol that begins with "wx".
(Step 7) At runtime, determine if "
libgtk-3.0.so" exists and can be loaded. If it can be loaded, then call the function "main_gtk3". Otherwise call the function "main_x11".
I bet I can get this working. The final executable file will only have one dependency -- it will link dynamically with 'glibc' (i.e. libc.so and libm.so) -- so you'll still be able to use it as a simple command line program. But if you have GTK3 installed, then you can use the GTK3 gui. If you don't have GTK3 installed then you can use the X11 gui.
Anyone got any ideas about this?