Load GUI libraries at runtime (but only if needed)

Do you have a question about makefiles, a compiler or IDE you are using and need to know how to set it up for wxWidgets or why it doesn't compile but other IDE's do ? Post your questions here.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

ONEEYEMAN wrote: Sat Mar 11, 2023 5:12 am Hi,
What you could have done is to link dynamically to everything and save yourself time and money

But it seems you like to waste them for fun, so enjoy....

Thank you.

I can't claim full credit for my achievement here, as I sought inspiration at a life drawing class. I went there to spend a couple of minutes drawing the model, and then wrote poems as the loader trying to resolve symbols. Higher resolution here:
http://www.virjacode.com/download/hack_no_mustard.jpg

smaller.jpg
You do not have the required permissions to view the files attached to this post.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

I'm going to take this to the next level. Here's what I'm going to do:

I'm going to take the static libraries for wxGTK3 and I'm going to use 'objcopy' on them to prefix 'wxGTK3_' to every exported symbol.

I'm going to take the static libraries for wxX11 and I'm going to use 'objcopy' on them to prefix "wxX11_' to every exported symbol.

This means that my executable file will be able to link with both wxGTK3 and wxX11, without getting any multiple definition errors.

Then in my main program, I check at runtime for the existence of "libgtk-3.0.so". If it exists then I dynamically load it and run my GUI in GTK3. If it doesn't exist however, then instead I dynamically load "libX11.so" and use X11.

My executable file will run on any x86_64 Linux machine because it's only dependency will be glibc.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

Here's what I'm thinking I will 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.
(Step 6) Use objcopy on all the ".o.gtk3" files in order to prefix "gtk3_" to every symbol.
(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?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7481
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Load GUI libraries at runtime (but only if needed)

Post by ONEEYEMAN »

Hi,
What happens if you program runs on Wayland?
Not an X11, but pure Wayland?

Thank you.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

ONEEYEMAN wrote: Wed Mar 15, 2023 11:32 pm What happens if you program runs on Wayland?
Not an X11, but pure Wayland?

Do you want me to also link it with wxWayland?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7481
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Load GUI libraries at runtime (but only if needed)

Post by ONEEYEMAN »

Hi,
I don't want you to do anything. It's your software.
I'm just asking what will happen, seeing that you are fixated of breaking the rules of normal *nix builds. ,-)

Thank you.
stahta01
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 550
Joined: Fri Nov 03, 2006 2:00 pm

Re: Load GUI libraries at runtime (but only if needed)

Post by stahta01 »

Am I the only one who thinks that this is case of premature optimization?
Because unless this is an system repair type tool I think it sounds like overkill.
Or, if it was an CIA computer cracking tool it might make sense.

Tim S.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7481
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Load GUI libraries at runtime (but only if needed)

Post by ONEEYEMAN »

Hi, Tim,
No, you are not.
And it is a complete waste of time.

On top of that he creates a disaster- link statically and dynamically to a system libraries.

But I would let him.
Then when he moves to Wayland or even better, starts working with KDE/QT, or start getting crashes

It just Neverending story with Linux.

Thank you.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

I've prefixed all the symbols exported from the wxGTK3 library with 'wxGTK3_', and I've prefixed all the symbols exported from the wxX11 library with 'wxX11_', as follows:

Code: Select all

#!/bin/sh
echo - - - - Deleting all files
rm -rf *.o *.a
echo - - - - Copying intact .a files
/usr/local/lib/wx/config/gtk3-unicode-static-3.2 --libs all | tr ' ' '\n' | sort | uniq | grep "\.a$" | xargs -i -r -n1 cp "{}" ./
echo - - - - Extracting .o files from .a files
find -name "*\.a" | xargs -i -r -n1 ar -x "{}"
echo - - - - Deleting all .a files
rm -rf *.a
echo - - - - Compiling an exhaustive list of exported symbols
nm *.o | grep -E "^[0-9a-f]{16} T " | cut -d ' ' -f 3 | sort | uniq > exported_symbols.txt
echo - - - - Adding a prefix to all the exported symbols
find -name "*\.o" | while read objfile; do cat exported_symbols.txt | xargs -i -r -n1 objcopy --redefine-sym {}=wxGTK3_{} ${objfile}; done
Next in the Makefile for my program, I compile all the GUI-related files twice, once for wxGTK3 and once for wxX11:

Code: Select all

wxwidgets/%.cpp.x11.o: wxwidgets/%.cpp $(wildcard wxwidgets/*.h wxwidgets/*.hpp)
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ $(wxwidgets_cxxflags_x11)
	cat wxwidgets/x11/exported_symbols.txt | while read symbol; do objcopy --redefine-sym $${symbol}=wxX11_$${symbol} $@; done

wxwidgets/%.cpp.gtk3.o: wxwidgets/%.cpp $(wildcard wxwidgets/*.h wxwidgets/*.hpp)
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ $(wxwidgets_cxxflags_gtk3)
	cat wxwidgets/gtk3/exported_symbols.txt | while read symbol; do objcopy --redefine-sym $${symbol}=wxGTK3_$${symbol} $@; done
When I link my program together, the object files seeking symbols from wxX11 should find them all prefixed with "wxX11_" in the altered wxX11 static library files, and the object files seeking symbols from wxGTK3 should find them all prefixed with "wxGTK3_" in the altered wxGTK3 static library files.

I might have this finished today. It's taking ages to rename all the symbols in static library files -- it's still not finished doing that.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

Virchanza wrote: Fri Mar 17, 2023 5:18 pm I might have this finished today. It's taking ages to rename all the symbols in static library files -- it's still not finished doing that.

Holy crap I got this working just now. Here's how my executable file looks:

Code: Select all

$ readelf -a ./ssh | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
$ ldd ./ssh
	linux-vdso.so.1 (0x00007ffd28d58000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f632db77000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f632d94f000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f632efd7000)
At runtime, it tries to dynamically load 'libgtk-3.so', and if it succeeds, the GTK3 gui is shown. If it fails, then instead it loads 'libX11.so' and displays the X11 gui.

What I have here is an executable file which is linked statically with two different versions of wxWidgets, specifically:
gtk3-unicode-static-3.2
x11univ-ansi-debug-static-2.8


If neither GTK3 nor X11 is installed, the executable can still be used as a simple console program.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7481
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Load GUI libraries at runtime (but only if needed)

Post by ONEEYEMAN »

Hi,
And you still have 2 executables...

Thank you.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

ONEEYEMAN wrote: Sat Mar 18, 2023 5:22 pm Hi,
And you still have 2 executables...

Thank you.
Please explain.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7481
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Load GUI libraries at runtime (but only if needed)

Post by ONEEYEMAN »

Hi,
IIRC, you started this journey in order to have one executable that could be run as console and GUI app.
And you still end up with 2 binaries...

And for what? To save couple of milliseconds? To save couple of kilobytes?
What was the purpose (not the goal) of all this?

Because in reality you might end up with 3 executables (3rd one being for wxQt), because Qt license does not allow static linking.

So what is the purpose?

Thank you.
Virchanza
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Jul 19, 2009 6:12 am

Re: Load GUI libraries at runtime (but only if needed)

Post by Virchanza »

ONEEYEMAN wrote: Sat Mar 18, 2023 7:24 pm And you still end up with 2 binaries...
This is the part I wanted you to explain. I have only one binary. Why do you think I have two binaries?

I have only one binary
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7481
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Load GUI libraries at runtime (but only if needed)

Post by ONEEYEMAN »

Hi,
I now re-read you last message and I see you just link to 2 different libraries. Sorry about that.

And you didn't explain why you wanted all this?

On top of that wxQt will not let you do that, because Qt license restriction.
Moreover - wxX11 is not really maintained and there are a lot of problems with that port. So, be ready to get a lot of phone calls about non-working software.

Just wamted to let you know that your work is far from being done.

I would suggest to shoot an E-mail to wx-dev ML asking if you can take a job of maintaining wxX11 port. (I think you are perfect man for the job).

Just keep in mind - this job will not pay a dime... ;-)

Thank you.