Somewhat disappointing experiences with Winelib and WTL

Claus Fischer claus.fischer at
Sun Feb 5 22:08:28 CST 2006

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.




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.


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

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

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

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.



Claus Fischer <claus.fischer at>

More information about the wine-devel mailing list