Hi Wine developers and users!
Over the last few days, I have been trying to find out whether the combination of WTL and Winelib could be a promising inter-platform GUI solution.
While I have made some progress and got some new knowledge, I believe I have now come to a dead end where I'll have to give up that attempt.
In case you are interested, here's my summary report.
It might be useful to others.
Regards,
Claus
***********************************************************
The Goal: *********
WTL on Windows gives me: - compact executables: small and fast - easy-to-install executables: no DLLs needed - programs easy to maintain and deploy - mature GUI
The goal is to combine WTL/ATL (no COM) with Winelib to create a Linux-application with the same look and feel and roughly the same qualities: no DLL's, shared libraries, C++ ABI hassles, etc. Just one binary linked to libc.
1. ATL/WTL **********
ATL 3.0 (from my MSVC 6 compiler) and WTL 7.5 (from sourceforge) can be made to work. Issues are: - GCC 4 is very picky with templates and would need lots of template prototypes; I have used GCC 3.3.5 - Some template prototypes are still needed - Some MSVC-specific pragmas etc. need to be ifdef'd - A few pack pragmas need to be replaced by Wine's pack headers - Everything related to _get_uuid(class) I've commented out; I need no COM stuff - Some GCC warnings need to be turned off, or alternatively code changes need to be made - Various small changes - As more parts of WTL get used (i.e. instantiated), more changes will be required
Basically, ATL+WTL can reach a state where they compile with GCC 3 and the changes are still mostly cosmetic. Some of the changes might even be incorporated in the official WTL, now that it's free.
I have read the mails of Boaz Harrosh' previous changes; apparently he has had to invest much more work because of COM.
With the modified ATL/WTL, I was able to compile the wizard-created sample SDI application on Linux.
2. Winelib "as is" ******************
After some digging through the Web, I've been able to link the sample SDI application against Winelib.
It took somewhat longer than it should have due to (a) WTL's habit of just ATLASSERT()ing things and (b) the rather elaborate work of finding those places with wine-dbg and/or ATLTRACE()s plus WINEDEBUG=+relay.
Since I'm not familiar with the Wine debugger, it would have been very helpful to be able to use gdb on the resulting executable. However, gdb reported that it didn't know the file format.
==> Wishlist to Wine: - Make gdb work on Winelib programs - Document Winelib and the build process better (the documentation is outdated, though the tools are good).
All in all a reasonably successful endeavour, and the application runs stable and looks fine except for the font (that probably can be configured better).
BUT: ... BIG SHOCK: That's not a single ELF executable, it's a weird mixture of PE and ELF and a .so file and a wrapper program that apparently starts wine in the background ...
That doesn't fulfill my goals of building a native Linux exe with no dependencies except libc.
It's also quite slow when loading.
3. Winelib statically linked ****************************
Apparently Wine has made a decision a few years ago: that support for native Windows apps with all the infrastructure they need (Wine server, registry, resources, multithreading, etc.) is more important than support for porting applications to native Linux apps.
That decision is obviously correct, given the large number of Windows applications that are only available as binaries and require much infrastructure.
I'm aware of that, but I've still decided to give my dream of a native Linux app a try.
I tried the following method: (a) Get and compile Wine 0.9.7 (b) Add rules to Makedll.rules to pack the objects into .a libraries (c) Attempt to link my program's objects against those static libs (d) Make changes and corrections and repeat
I first made a reduced WTL application that does not use a resource file. I don't know if this was a good decision.
The following changes were necessary to Wine: - Comment out a lot of DLLMain functions - Comment out some 16-bit functions that have name collisions - Turn on debug mode (-O0 -g) - Write a startup function main() (Wine's libwinecrt0.a didn't work for me) That might be the reason for more trouble - Link to all of libs/unicode - Link to some objects in libs/wine (I didn't link to loader, don't know if that's good)
This is where the heavy trouble started: - Replace the assembly stuff in critical sections (due to the debug mode) ... my app is single-threaded - Somehow set up code pages for ansi/Unix (LocaleInit() failed, see below) - Comment out some calls to the registry where the run-time environment is registered
What eventually caused me to stop is: - Somehow fake Wine Server or do the equivalent stuff or just jump over (Basically Register Class as atoms) - Somehow fake a lot of initial resources (E.g. GetSystemCursor etc.) - Overall too many modifications in interacting systems - Altogether not a "robust" feeling
This is where I stopped.
I don't know whether I'm "so close" or miles away, but my random code editing seemed to get out of hand.
4. What is needed *****************
What would be needed to support static linking against Winelib (if that's decided to be a supportworthy goal):
- Infrastructure to build static libs - separate out DllMain - separate out some 16 bit functions
- Possibility to provide heap based allocation through straight malloc()
- Infrastructure to fake loading resources (for those resources that come from Winelib/system)
- Infrastructure for proper initialization of modules e.g. through one setup function for each DLL and one common setup function that calls the others in some natural order The overall initialization function should be configurable so that programs that need only a few DLL's (user, gdi, crtdll, kernel, ntdll) don't need to link everything
- Infrastructure to allow faking registry calls for those calls initiated by Winelib internal stuff (and possibly also ATL/WTL internal stuff)
- Infrastructure to handle Window class registration etc. (i.e. reduced Wine server support in the app)
What I specifically don't need/want through Winelib: - networking - filesystem access - loading of external DLL's or other libraries - C++ runtime library support
***********************************************************
This is, in keywords, my experience with WTL and static Winelib linking. I'll be apreciative of any responses.
Please CC: my mail address.
Also, if anyone is interested in hosting patches to ATL/WTL or even just looking at them, I'll gladly provide them.
Regards,
Claus